lono 0.5.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +152 -23
- data/lib/lono.rb +1 -0
- data/lib/lono/cli.rb +3 -2
- data/lib/lono/dsl.rb +59 -12
- data/lib/lono/new.rb +4 -2
- data/lib/lono/template.rb +22 -9
- data/lib/lono/version.rb +1 -1
- data/lib/{starter_project → starter_project_json}/Gemfile +2 -1
- data/lib/{starter_project → starter_project_json}/Guardfile +0 -0
- data/lib/starter_project_json/config/lono.rb +20 -0
- data/lib/{starter_project → starter_project_json}/config/lono/api.rb +9 -9
- data/lib/{starter_project → starter_project_json}/templates/db.json.erb +1 -1
- data/lib/{starter_project → starter_project_json}/templates/partial/host_record.json.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/partial/server.json.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/user_data/app.sh.erb +1 -4
- data/lib/{starter_project → starter_project_json}/templates/user_data/db.sh.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/user_data/db2.sh.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/user_data/ruby_script.rb.erb +0 -0
- data/lib/{starter_project/templates/app.json.erb → starter_project_json/templates/web.json.erb} +1 -1
- data/lib/starter_project_yaml/Gemfile +4 -0
- data/lib/starter_project_yaml/Guardfile +12 -0
- data/lib/{starter_project → starter_project_yaml}/config/lono.rb +5 -5
- data/lib/starter_project_yaml/config/lono/api.rb +58 -0
- data/lib/starter_project_yaml/templates/db.yml.erb +148 -0
- data/lib/starter_project_yaml/templates/partial/host_record.yml.erb +14 -0
- data/lib/starter_project_yaml/templates/partial/server.yml.erb +59 -0
- data/lib/starter_project_yaml/templates/partial/user_data/bootstrap.sh.erb +5 -0
- data/lib/starter_project_yaml/templates/web.yml.erb +205 -0
- data/lono.gemspec +1 -1
- data/spec/lib/lono/dsl_spec.rb +184 -0
- data/spec/lib/lono/new_spec.rb +59 -0
- data/spec/lib/lono_spec.rb +6 -116
- data/spec/spec_helper.rb +1 -0
- metadata +42 -15
data/lib/lono/version.rb
CHANGED
File without changes
|
@@ -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 "
|
2
|
-
source "
|
1
|
+
template "api-web-prod.json" do
|
2
|
+
source "web.json.erb"
|
3
3
|
variables(
|
4
4
|
ami: "ami-123",
|
5
|
-
instance_type: "
|
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 "
|
20
|
-
source "
|
19
|
+
template "api-worker-prod.json" do
|
20
|
+
source "web.json.erb"
|
21
21
|
variables(
|
22
22
|
ami: "ami-123",
|
23
|
-
instance_type: "
|
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 "
|
38
|
+
template "api-redis-prod.json" do
|
39
39
|
source "db.json.erb"
|
40
40
|
variables(
|
41
41
|
ami: "ami-456",
|
42
|
-
instance_type: "
|
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: "
|
53
|
+
instance_type: "t2.small",
|
54
54
|
port: "80",
|
55
55
|
volume_size: "20",
|
56
56
|
availability_zone: "us-east-1e"
|
File without changes
|
File without changes
|
@@ -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
|
-
|
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
|
File without changes
|
File without changes
|
File without changes
|
@@ -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 "
|
2
|
-
|
3
|
-
source "
|
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-
|
9
|
-
instance_type: "
|
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
|