lono 0.5.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +5 -0
  4. data/README.md +152 -23
  5. data/lib/lono.rb +1 -0
  6. data/lib/lono/cli.rb +3 -2
  7. data/lib/lono/dsl.rb +59 -12
  8. data/lib/lono/new.rb +4 -2
  9. data/lib/lono/template.rb +22 -9
  10. data/lib/lono/version.rb +1 -1
  11. data/lib/{starter_project → starter_project_json}/Gemfile +2 -1
  12. data/lib/{starter_project → starter_project_json}/Guardfile +0 -0
  13. data/lib/starter_project_json/config/lono.rb +20 -0
  14. data/lib/{starter_project → starter_project_json}/config/lono/api.rb +9 -9
  15. data/lib/{starter_project → starter_project_json}/templates/db.json.erb +1 -1
  16. data/lib/{starter_project → starter_project_json}/templates/partial/host_record.json.erb +0 -0
  17. data/lib/{starter_project → starter_project_json}/templates/partial/server.json.erb +0 -0
  18. data/lib/{starter_project → starter_project_json}/templates/user_data/app.sh.erb +1 -4
  19. data/lib/{starter_project → starter_project_json}/templates/user_data/db.sh.erb +0 -0
  20. data/lib/{starter_project → starter_project_json}/templates/user_data/db2.sh.erb +0 -0
  21. data/lib/{starter_project → starter_project_json}/templates/user_data/ruby_script.rb.erb +0 -0
  22. data/lib/{starter_project/templates/app.json.erb → starter_project_json/templates/web.json.erb} +1 -1
  23. data/lib/starter_project_yaml/Gemfile +4 -0
  24. data/lib/starter_project_yaml/Guardfile +12 -0
  25. data/lib/{starter_project → starter_project_yaml}/config/lono.rb +5 -5
  26. data/lib/starter_project_yaml/config/lono/api.rb +58 -0
  27. data/lib/starter_project_yaml/templates/db.yml.erb +148 -0
  28. data/lib/starter_project_yaml/templates/partial/host_record.yml.erb +14 -0
  29. data/lib/starter_project_yaml/templates/partial/server.yml.erb +59 -0
  30. data/lib/starter_project_yaml/templates/partial/user_data/bootstrap.sh.erb +5 -0
  31. data/lib/starter_project_yaml/templates/web.yml.erb +205 -0
  32. data/lono.gemspec +1 -1
  33. data/spec/lib/lono/dsl_spec.rb +184 -0
  34. data/spec/lib/lono/new_spec.rb +59 -0
  35. data/spec/lib/lono_spec.rb +6 -116
  36. data/spec/spec_helper.rb +1 -0
  37. metadata +42 -15
data/lib/lono/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lono
2
- VERSION = "0.5.2"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,3 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'lono'
3
+ gem 'lono'
4
+ gem 'lono-cfn'
@@ -0,0 +1,20 @@
1
+ template "blog-web-prod.json" do
2
+ app,role,env = name.sub('.json','').split('-')
3
+ source "web.json.erb"
4
+ variables(
5
+ env: env,
6
+ app: app,
7
+ role: role,
8
+ ami: "ami-4836a428", # us-west-2
9
+ instance_type: "t2.small",
10
+ port: "80",
11
+ high_threshold: "35",
12
+ high_periods: "4",
13
+ low_threshold: "20",
14
+ low_periods: "2",
15
+ max_size: "6",
16
+ min_size: "3",
17
+ down_adjustment: "-1",
18
+ up_adjustment: "2"
19
+ )
20
+ end
@@ -1,8 +1,8 @@
1
- template "prod-api-app.json" do
2
- source "app.json.erb"
1
+ template "api-web-prod.json" do
2
+ source "web.json.erb"
3
3
  variables(
4
4
  ami: "ami-123",
5
- instance_type: "m1.small",
5
+ instance_type: "t2.small",
6
6
  port: "80",
7
7
  high_threshold: "15",
8
8
  high_periods: "4",
@@ -16,11 +16,11 @@ template "prod-api-app.json" do
16
16
  )
17
17
  end
18
18
 
19
- template "prod-api-worker.json" do
20
- source "app.json.erb"
19
+ template "api-worker-prod.json" do
20
+ source "web.json.erb"
21
21
  variables(
22
22
  ami: "ami-123",
23
- instance_type: "m1.small",
23
+ instance_type: "t2.small",
24
24
  port: "80",
25
25
  high_threshold: "15",
26
26
  high_periods: "4",
@@ -35,11 +35,11 @@ template "prod-api-worker.json" do
35
35
  )
36
36
  end
37
37
 
38
- template "prod-api-redis.json" do
38
+ template "api-redis-prod.json" do
39
39
  source "db.json.erb"
40
40
  variables(
41
41
  ami: "ami-456",
42
- instance_type: "m1.small",
42
+ instance_type: "t2.small",
43
43
  port: "80",
44
44
  volume_size: "20",
45
45
  availability_zone: "us-east-1e"
@@ -50,7 +50,7 @@ template "parent/db-stack.json" do
50
50
  source "db.json.erb"
51
51
  variables(
52
52
  ami: "ami-456",
53
- instance_type: "m1.small",
53
+ instance_type: "t2.small",
54
54
  port: "80",
55
55
  volume_size: "20",
56
56
  availability_zone: "us-east-1e"
@@ -1,4 +1,4 @@
1
- <% @env,@app,@role = name.sub('.json','').split('-') %>
1
+ <% @app,@role,@env = name.sub('.json','').split('-') %>
2
2
  {
3
3
  "AWSTemplateFormatVersion": "2010-09-09",
4
4
  "Description": "<%= @app.capitalize %> <%= @role %>",
@@ -2,7 +2,4 @@
2
2
  <% stack_name = "#{@env}-#{@app}-#{@role}" %>
3
3
  exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
4
4
  echo <%= stack_name %> > /tmp/stack_name
5
- set +e
6
- rvm use system --default
7
- set -e
8
- cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
5
+ cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
@@ -1,4 +1,4 @@
1
- <% @env,@app,@role = name.sub('.json','').split('-') %>
1
+ <% @app,@role,@env = name.sub('.json','').split('-') %>
2
2
  {
3
3
  "AWSTemplateFormatVersion": "2010-09-09",
4
4
  "Description": "<%= @app.capitalize %> Stack",
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'lono'
4
+ gem 'lono-cfn'
@@ -0,0 +1,12 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard "lono" do
5
+ watch(%r{^config/lono.rb$})
6
+ watch(%r{^templates/.*$})
7
+ end
8
+
9
+ # Commented out due to CF rate limiting
10
+ # guard "cloudformation", templates_path: "output" do
11
+ # watch(%r{^output/.+\.yml$})
12
+ # end
@@ -1,12 +1,12 @@
1
- template "prod-blog-app.json" do
2
- env,app,role = name.sub('.json','').split('-')
3
- source "app.json.erb"
1
+ template "blog-web-prod.yml" do
2
+ app,role,env = name.sub('.yml','').split('-')
3
+ source "web.yml.erb"
4
4
  variables(
5
5
  env: env,
6
6
  app: app,
7
7
  role: role,
8
- ami: "ami-456",
9
- instance_type: "m1.small",
8
+ ami: "ami-4836a428", # us-west-2
9
+ instance_type: "t2.small",
10
10
  port: "80",
11
11
  high_threshold: "35",
12
12
  high_periods: "4",
@@ -0,0 +1,58 @@
1
+ template "api-web-prod.yml" do
2
+ source "web.yml.erb"
3
+ variables(
4
+ ami: "ami-123",
5
+ instance_type: "t2.small",
6
+ port: "80",
7
+ high_threshold: "15",
8
+ high_periods: "4",
9
+ low_threshold: "5",
10
+ low_periods: "10",
11
+ max_size: "24",
12
+ min_size: "6",
13
+ down_adjustment: "-3",
14
+ up_adjustment: "3",
15
+ ssl_cert: "arn:aws:iam::12345:server-certificate/wildcard"
16
+ )
17
+ end
18
+
19
+ template "api-worker-prod.yml" do
20
+ source "web.yml.erb"
21
+ variables(
22
+ ami: "ami-123",
23
+ instance_type: "t2.small",
24
+ port: "80",
25
+ high_threshold: "15",
26
+ high_periods: "4",
27
+ low_threshold: "5",
28
+ low_periods: "10",
29
+ max_size: "24",
30
+ min_size: "6",
31
+ down_adjustment: "-3",
32
+ up_adjustment: "3",
33
+ user_data_script: "ruby_script.rb.erb",
34
+ ssl_cert: "arn:aws:iam::12345:server-certificate/wildcard"
35
+ )
36
+ end
37
+
38
+ template "api-redis-prod.yml" do
39
+ source "db.yml.erb"
40
+ variables(
41
+ ami: "ami-456",
42
+ instance_type: "t2.small",
43
+ port: "80",
44
+ volume_size: "20",
45
+ availability_zone: "us-east-1e"
46
+ )
47
+ end
48
+
49
+ template "parent/db-stack.yml" do
50
+ source "db.yml.erb"
51
+ variables(
52
+ ami: "ami-456",
53
+ instance_type: "t2.small",
54
+ port: "80",
55
+ volume_size: "20",
56
+ availability_zone: "us-east-1e"
57
+ )
58
+ end
@@ -0,0 +1,148 @@
1
+ <% @app,@role,@env = name.sub('.yml','').split('-') -%>
2
+ ---
3
+ AWSTemplateFormatVersion: '2010-09-09'
4
+ Description: '<%= @app.capitalize %> <%= @role %>'
5
+ Outputs:
6
+ DBHostname:
7
+ Description: Hostname for Redis
8
+ Value:
9
+ Fn::Join:
10
+ - ''
11
+ - - ''
12
+ - Fn::GetAtt:
13
+ - server
14
+ - PublicDnsName
15
+ Parameters:
16
+ Ami:
17
+ Default: <%= @ami %>
18
+ Description: deploy ami
19
+ Type: String
20
+ Application:
21
+ Default: <%= @app %>
22
+ Description: foo, bar, etc
23
+ Type: String
24
+ Environment:
25
+ Default: <%= @env %>
26
+ Description: stag, prod etc
27
+ Type: String
28
+ InstanceType:
29
+ AllowedValues:
30
+ - t1.micro
31
+ - m1.small
32
+ - m1.medium
33
+ - m1.large
34
+ - m1.xlarge
35
+ - m2.xlarge
36
+ - m2.2xlarge
37
+ - m2.4xlarge
38
+ - c1.medium
39
+ - c1.xlarge
40
+ - cc1.4xlarge
41
+ - cc2.8xlarge
42
+ - cg1.4xlarge
43
+ ConstraintDescription: must be a valid EC2 instance type.
44
+ Default: <%= @instance_type %>
45
+ Description: server EC2 instance type
46
+ Type: String
47
+ KeyName:
48
+ AllowedPattern: "[-_ a-zA-Z0-9]*"
49
+ ConstraintDescription: can contain only alphanumeric characters, spaces, dashes
50
+ and underscores.
51
+ Default: default
52
+ Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
53
+ MaxLength: '64'
54
+ MinLength: '1'
55
+ Type: String
56
+ Role:
57
+ Default: '<%= @role %>'
58
+ Description: redis, psql, app, etc
59
+ Type: String
60
+ StackNumber:
61
+ Default: ''
62
+ Description: s1, s2, s3, etc
63
+ Type: String
64
+ VolumeSize:
65
+ ConstraintDescription: must be between 5 and 1024 Gb.
66
+ Default: '<%= @volume_size %>'
67
+ Description: Size of Volume
68
+ MaxValue: '1024'
69
+ MinValue: '5'
70
+ Type: Number
71
+ Resources:
72
+ CfnUser:
73
+ Properties:
74
+ Path: "/"
75
+ Policies:
76
+ - PolicyDocument:
77
+ Statement:
78
+ - Action: cloudformation:DescribeStackResource
79
+ Effect: Allow
80
+ Resource: "*"
81
+ PolicyName: root
82
+ Type: AWS::IAM::User
83
+ DataVolume:
84
+ DeletionPolicy: Snapshot
85
+ Properties:
86
+ AvailabilityZone:
87
+ Fn::GetAtt:
88
+ - server
89
+ - AvailabilityZone
90
+ Size:
91
+ Ref: VolumeSize
92
+ Tags:
93
+ - Key: Usage
94
+ Value: Data Volume
95
+ Type: AWS::EC2::Volume
96
+ HostKeys:
97
+ Properties:
98
+ UserName:
99
+ Ref: CfnUser
100
+ Type: AWS::IAM::AccessKey
101
+ HostRecord:
102
+ Properties:
103
+ Comment: DNS name for my stack.
104
+ HostedZoneName: ".mydomain.net."
105
+ Name:
106
+ Fn::Join:
107
+ - ''
108
+ - - Ref: AWS::StackName
109
+ - ".mydomain.net."
110
+ ResourceRecords:
111
+ - Fn::GetAtt:
112
+ - server
113
+ - PublicDnsName
114
+ TTL: '60'
115
+ Type: CNAME
116
+ Type: AWS::Route53::RecordSet
117
+ MountPoint:
118
+ Properties:
119
+ Device: "/dev/sdf"
120
+ InstanceId:
121
+ Ref: server
122
+ VolumeId:
123
+ Ref: DataVolume
124
+ Type: AWS::EC2::VolumeAttachment
125
+ ServiceSecurityGroup:
126
+ Properties:
127
+ GroupDescription: Enable SSH access.
128
+ SecurityGroupIngress:
129
+ - CidrIp: 0.0.0.0/0
130
+ FromPort: '22'
131
+ IpProtocol: tcp
132
+ ToPort: '22'
133
+ Type: AWS::EC2::SecurityGroup
134
+ WaitCondition:
135
+ DependsOn: MountPoint
136
+ Metadata:
137
+ Comment1: Note that the WaitCondition is dependent on the volume mount point
138
+ allowing the volume to be created and attached to the EC2 instance
139
+ Comment2: The instance bootstrap script waits for the volume to be attached
140
+ to the instance prior to signalling completion.
141
+ Properties:
142
+ Handle:
143
+ Ref: WaitHandle
144
+ Timeout: '3000'
145
+ Type: AWS::CloudFormation::WaitCondition
146
+ WaitHandle:
147
+ Type: AWS::CloudFormation::WaitConditionHandle
148
+ <%= partial("server.yml.erb") %>
@@ -0,0 +1,14 @@
1
+ HostRecord:
2
+ Properties:
3
+ Comment: DNS name for <%= @domain %>
4
+ HostedZoneName: <%= @domain %>.
5
+ Name:
6
+ Fn::Join:
7
+ - ''
8
+ - - Ref: AWS::StackName
9
+ - ".<%= @domain %>"
10
+ ResourceRecords:
11
+ - !GetAtt elb.DNSName
12
+ TTL: '60'
13
+ Type: CNAME
14
+ Type: AWS::Route53::RecordSet
@@ -0,0 +1,59 @@
1
+ server:
2
+ Properties:
3
+ AvailabilityZone: us-east-1e
4
+ ImageId:
5
+ Ref: Ami
6
+ InstanceType:
7
+ Ref: InstanceType
8
+ KeyName:
9
+ Ref: KeyName
10
+ SecurityGroups:
11
+ - global
12
+ - Fn::Join:
13
+ - "-"
14
+ - - Ref: Environment
15
+ - Ref: Application
16
+ - Ref: ServiceSecurityGroup
17
+ UserData:
18
+ Fn::Base64: !Sub | # No more Fn::Join needed
19
+ #!/bin/bash -lexv
20
+ exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
21
+
22
+ FIND_IN_MAP=!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]
23
+ HOSTNAME_PREFIX=!FindInMap [ EnvironmentMapping, HostnamePrefix, !Ref Environment ]
24
+ BAR=!Ref DRINK ; MORE=!FindInMap [MapName, TopLevelKey, SecondLevelKey ]
25
+
26
+ BASE64=!Base64 "value to encode"
27
+ GET_ATT=!GetAtt server.PublicDnsName
28
+ GET_AZS=!GetAZs us-east-1
29
+ JOIN=!Join [ ":", [a, b, c]
30
+ SELECT=!Select [ "1", [ a, b, c] ]
31
+
32
+ VARTEST=<%= @vartest %>
33
+
34
+ echo !Ref AWS::StackName > /tmp/stack_name
35
+ # Helper function
36
+ function error_exit
37
+ {
38
+ /usr/local/bin/cfn-signal -e 1 -r "$1" '!Ref WaitHandle'
39
+ exit 1
40
+ }
41
+ # Wait for the EBS volume to show up
42
+ while [ ! -e /dev/xvdf ]; do echo Waiting for EBS volume to attach; sleep 1; done
43
+ /bin/mkdir /media/redis
44
+ /sbin/mkfs -t ext4 /dev/xvdf
45
+ echo "/dev/xvdf /media/redis auto defaults 0 0" >> /etc/fstab
46
+ /bin/mount /media/redis
47
+ /usr/bin/redis-cli shutdown
48
+ sleep 10
49
+ mv /var/lib/redis/* /media/redis/
50
+ rm -r /var/lib/redis
51
+ ln -s /media/redis /var/lib/redis
52
+ chown -R redis:redis /var/lib/redis
53
+ chown -R redis:redis /media/redis
54
+ /usr/bin/redis-server
55
+ # If all is well so signal success
56
+ /usr/local/bin/cfn-signal -e $? -r "Ready to rock" '!Ref WaitHandle'
57
+ cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
58
+
59
+ Type: AWS::EC2::Instance