cfndsl 0.1.16 → 0.1.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,176 @@
1
+ {
2
+ "AWSTemplateFormatVersion" : "2010-09-09",
3
+
4
+ "Description" : "Create a multi-az, load balanced, Auto Scaled sample web site. The Auto Scaling trigger is based on the CPU utilization of the web servers. The AMI is chosen based on the region in which the stack is run. This example creates a web service running across all availability zones in a region. The instances are load balanced with a simple health check. The web site is available on port 80, however, the instances can be configured to listen on any port (8888 by default). **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",
5
+
6
+ "Parameters" : {
7
+ "InstanceType" : {
8
+ "Description" : "Type of EC2 instance to launch",
9
+ "Type" : "String",
10
+ "Default" : "m1.small"
11
+ },
12
+ "WebServerPort" : {
13
+ "Description" : "The TCP port for the Web Server",
14
+ "Type" : "String",
15
+ "Default" : "8888"
16
+ },
17
+ "KeyName" : {
18
+ "Description" : "The EC2 Key Pair to allow SSH access to the instances",
19
+ "Type" : "String"
20
+ }
21
+ },
22
+
23
+ "Mappings" : {
24
+ "AWSInstanceType2Arch" : {
25
+ "t1.micro" : { "Arch" : "64" },
26
+ "m1.small" : { "Arch" : "32" },
27
+ "m1.large" : { "Arch" : "64" },
28
+ "m1.xlarge" : { "Arch" : "64" },
29
+ "m2.xlarge" : { "Arch" : "64" },
30
+ "m2.2xlarge" : { "Arch" : "64" },
31
+ "m2.4xlarge" : { "Arch" : "64" },
32
+ "c1.medium" : { "Arch" : "32" },
33
+ "c1.xlarge" : { "Arch" : "64" },
34
+ "cc1.4xlarge" : { "Arch" : "64" }
35
+ },
36
+ "AWSRegionArch2AMI" : {
37
+ "us-east-1" : { "32" : "ami-6411e20d", "64" : "ami-7a11e213" },
38
+ "us-west-1" : { "32" : "ami-c9c7978c", "64" : "ami-cfc7978a" },
39
+ "eu-west-1" : { "32" : "ami-37c2f643", "64" : "ami-31c2f645" },
40
+ "ap-southeast-1" : { "32" : "ami-66f28c34", "64" : "ami-60f28c32" },
41
+ "ap-northeast-1" : { "32" : "ami-9c03a89d", "64" : "ami-a003a8a1" }
42
+ }
43
+ },
44
+
45
+ "Resources" : {
46
+ "WebServerGroup" : {
47
+ "Type" : "AWS::AutoScaling::AutoScalingGroup",
48
+ "Properties" : {
49
+ "AvailabilityZones" : { "Fn::GetAZs" : ""},
50
+ "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
51
+ "MinSize" : "1",
52
+ "MaxSize" : "3",
53
+ "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ]
54
+ }
55
+ },
56
+
57
+ "LaunchConfig" : {
58
+ "Type" : "AWS::AutoScaling::LaunchConfiguration",
59
+ "Properties" : {
60
+ "KeyName" : { "Ref" : "KeyName" },
61
+ "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
62
+ { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" },
63
+ "Arch" ] } ] },
64
+ "UserData" : { "Fn::Base64" : { "Ref" : "WebServerPort" }},
65
+ "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ],
66
+ "InstanceType" : { "Ref" : "InstanceType" }
67
+ }
68
+ },
69
+
70
+ "WebServerScaleUpPolicy" : {
71
+ "Type" : "AWS::AutoScaling::ScalingPolicy",
72
+ "Properties" : {
73
+ "AdjustmentType" : "ChangeInCapacity",
74
+ "AutoScalingGroupName" : { "Ref" : "WebServerGroup" },
75
+ "Cooldown" : "60",
76
+ "ScalingAdjustment" : "1"
77
+ }
78
+ },
79
+ "WebServerScaleDownPolicy" : {
80
+ "Type" : "AWS::AutoScaling::ScalingPolicy",
81
+ "Properties" : {
82
+ "AdjustmentType" : "ChangeInCapacity",
83
+ "AutoScalingGroupName" : { "Ref" : "WebServerGroup" },
84
+ "Cooldown" : "60",
85
+ "ScalingAdjustment" : "-1"
86
+ }
87
+ },
88
+
89
+ "CPUAlarmHigh": {
90
+ "Type": "AWS::CloudWatch::Alarm",
91
+ "Properties": {
92
+ "AlarmDescription": "Scale-up if CPU > 90% for 10 minutes",
93
+ "MetricName": "CPUUtilization",
94
+ "Namespace": "AWS/EC2",
95
+ "Statistic": "Average",
96
+ "Period": "300",
97
+ "EvaluationPeriods": "2",
98
+ "Threshold": "90",
99
+ "AlarmActions": [ { "Ref": "WebServerScaleUpPolicy" } ],
100
+ "Dimensions": [
101
+ {
102
+ "Name": "AutoScalingGroupName",
103
+ "Value": { "Ref": "WebServerGroup" }
104
+ }
105
+ ],
106
+ "ComparisonOperator": "GreaterThanThreshold"
107
+ }
108
+ },
109
+ "CPUAlarmLow": {
110
+ "Type": "AWS::CloudWatch::Alarm",
111
+ "Properties": {
112
+ "AlarmDescription": "Scale-down if CPU < 70% for 10 minutes",
113
+ "MetricName": "CPUUtilization",
114
+ "Namespace": "AWS/EC2",
115
+ "Statistic": "Average",
116
+ "Period": "300",
117
+ "EvaluationPeriods": "2",
118
+ "Threshold": "70",
119
+ "AlarmActions": [ { "Ref": "WebServerScaleDownPolicy" } ],
120
+ "Dimensions": [
121
+ {
122
+ "Name": "AutoScalingGroupName",
123
+ "Value": { "Ref": "WebServerGroup" }
124
+ }
125
+ ],
126
+ "ComparisonOperator": "LessThanThreshold"
127
+ }
128
+ },
129
+
130
+ "ElasticLoadBalancer" : {
131
+ "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
132
+ "Properties" : {
133
+ "AvailabilityZones" : { "Fn::GetAZs" : "" },
134
+ "Listeners" : [ {
135
+ "LoadBalancerPort" : "80",
136
+ "InstancePort" : { "Ref" : "WebServerPort" },
137
+ "Protocol" : "HTTP"
138
+ } ],
139
+ "HealthCheck" : {
140
+ "Target" : { "Fn::Join" : [ "", ["HTTP:", { "Ref" : "WebServerPort" }, "/"]]},
141
+ "HealthyThreshold" : "3",
142
+ "UnhealthyThreshold" : "5",
143
+ "Interval" : "30",
144
+ "Timeout" : "5"
145
+ }
146
+ }
147
+ },
148
+
149
+ "InstanceSecurityGroup" : {
150
+ "Type" : "AWS::EC2::SecurityGroup",
151
+ "Properties" : {
152
+ "GroupDescription" : "Enable SSH access and HTTP access on the inbound port",
153
+ "SecurityGroupIngress" : [ {
154
+ "IpProtocol" : "tcp",
155
+ "FromPort" : "22",
156
+ "ToPort" : "22",
157
+ "CidrIp" : "0.0.0.0/0"
158
+ },
159
+ {
160
+ "IpProtocol" : "tcp",
161
+ "FromPort" : { "Ref" : "WebServerPort" },
162
+ "ToPort" : { "Ref" : "WebServerPort" },
163
+ "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]},
164
+ "SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}
165
+ } ]
166
+ }
167
+ }
168
+ },
169
+
170
+ "Outputs" : {
171
+ "URL" : {
172
+ "Description" : "The URL of the website",
173
+ "Value" : { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]}
174
+ }
175
+ }
176
+ }
@@ -0,0 +1,231 @@
1
+
2
+ # We start things off by calling the CloudFormation function.
3
+ CloudFormation {
4
+ # Declare the template format version
5
+ AWSTemplateFormatVersion "2010-09-09"
6
+
7
+ # As the DSL is really ruby, we get all of the different
8
+ # ways to quote strings that come with ruby.
9
+ Description %Q/
10
+ Create a multi-az, load balanced, Auto Scaled sample web site. The
11
+ Auto Scaling trigger is based on the CPU utilization of the web
12
+ servers. The AMI is chosen based on the region in which the stack is
13
+ run. This example creates a web service running across all
14
+ availability zones in a region. The instances are load balanced with a
15
+ simple health check. The web site is available on port 80, however,
16
+ the instances can be configured to listen on any port (8888 by
17
+ default).
18
+
19
+ **WARNING** This template creates one or more Amazon EC2
20
+ instances. You will be billed for the AWS resources used if you create
21
+ a stack from this template.
22
+ /
23
+
24
+ # We can declare Parameters anywhere in the CloudFormation
25
+ # block - these will get rolled up into the Parameters container
26
+ # in the output.
27
+ Parameter("InstanceType") {
28
+ Description "Type of EC2 instance to launch"
29
+ Type "String"
30
+ Default "m1.small"
31
+ }
32
+
33
+ Parameter( "WebServerPort") {
34
+ Description "The TCP port for the Web Server"
35
+ Type "String"
36
+ Default "8888"
37
+ }
38
+ Parameter("KeyName") {
39
+ Description "The EC2 Key Pair to allow SSH access to the instances"
40
+ Type "String"
41
+ }
42
+
43
+ # The same kind of thing for parameters works for mappings,
44
+ # except that there is not a special object declared for mappings,
45
+ # so we just have to build a hash of hashes which will be turned
46
+ # directly into json.
47
+
48
+ Mapping("AWSRegionArch2AMI", {
49
+ "us-east-1" => { "32" => "ami-6411e20d", "64" => "ami-7a11e213" },
50
+ "us-west-1" => { "32" => "ami-c9c7978c", "64" => "ami-cfc7978a" },
51
+ "eu-west-1" => { "32" => "ami-37c2f643", "64" => "ami-31c2f645" },
52
+ "ap-southeast-1" => { "32" => "ami-66f28c34", "64" => "ami-60f28c32" },
53
+ "ap-northeast-1" => { "32" => "ami-9c03a89d", "64" => "ami-a003a8a1" }
54
+ })
55
+
56
+
57
+ # We can also write arbitrary ruby code
58
+
59
+ # Here we build up a ruby hash
60
+ architectures = {}
61
+ [ "t1.micro", "m1.large", "m1.xlarge", "m2.xlarge",
62
+ "m2.2xlarge", "m2.4xlarge", "c1.xlarge", "cc1.4xlarge"
63
+ ].each do |arch|
64
+ # Iterate through the 64 bit machines to build a mapping for
65
+ # 64 bit architecture
66
+ architectures[arch] = { "Arch" => "64" }
67
+ end
68
+
69
+ [ "m1.small", "c1.medium"
70
+ ].each do |arch|
71
+ # iterate throught he 32 bit machine to build a mapping for
72
+ # 32 bit architectures
73
+ architectures[arch] = { "Arch" => "32" }
74
+ end
75
+
76
+ Mapping("AWSInstanceType2Arch", architectures )
77
+ # This will add a mapping entry equivalent to the following to the
78
+ # template:
79
+ #
80
+ # "AWSInstanceType2Arch" : {
81
+ # "m2.4xlarge" : { "Arch" : "64" },
82
+ # "c1.xlarge" : { "Arch" : "64" },
83
+ # "c1.medium" : { "Arch" : "32" },
84
+ # "m1.xlarge" : { "Arch" : "64" },
85
+ # "m1.large" : { "Arch" : "64" },
86
+ # "t1.micro" : { "Arch" : "64" },
87
+ # "m1.small" : { "Arch" : "32" },
88
+ # "m2.2xlarge" : { "Arch" : "64" },
89
+ # "m2.xlarge" : { "Arch" : "64" },
90
+ # "cc1.4xlarge" : { "Arch" : "64" }
91
+ # }
92
+
93
+ # Resources work similar to Parameters
94
+ AutoScalingGroup("WebServerGroup") {
95
+ UpdatePolicy("AutoScalingRollingUpdate", {
96
+ "MinInstancesInService" => "1",
97
+ "MaxBatchSize" => "1",
98
+ "PauseTime" => "PT15M"
99
+ })
100
+ AvailabilityZones FnGetAZs("")
101
+ LaunchConfigurationName Ref("LaunchConfig")
102
+ MinSize 1
103
+ MaxSize 3
104
+ LoadBalancerNames Ref( "ElasticLoadBalancer" )
105
+ }
106
+
107
+ # You can use either strings or symbols for
108
+ # Resource/Parameter/Mapping/Output names
109
+ LaunchConfiguration( :LaunchConfig ) {
110
+ KeyName Ref("KeyName")
111
+ ImageId FnFindInMap( "AWSRegionArch2AMI",
112
+ Ref("AWS::Region"),
113
+ FnFindInMap( "AWSInstanceType2Arch", Ref("InstanceType"),"Arch") )
114
+
115
+ UserData FnBase64( Ref("WebServerPort"))
116
+ SecurityGroup Ref("InstanceSecurityGroup")
117
+ InstanceType Ref("InstanceType")
118
+ }
119
+
120
+
121
+ Resource( "WebServerScaleUpPolicy" ) {
122
+ Type "AWS::AutoScaling::ScalingPolicy"
123
+ Property("AdjustmentType", "ChangeInCapacity")
124
+ Property("AutoScalingGroupName", Ref( "WebServerGroup") )
125
+ Property("Cooldown", "60")
126
+ Property("ScalingAdjustment", "1")
127
+ }
128
+
129
+ Resource("WebServerScaleDownPolicy") {
130
+ Type "AWS::AutoScaling::ScalingPolicy"
131
+ Property("AdjustmentType", "ChangeInCapacity")
132
+ Property("AutoScalingGroupName", Ref( "WebServerGroup" ))
133
+ Property("Cooldown", "60")
134
+ Property("ScalingAdjustment", "-1")
135
+ }
136
+
137
+
138
+ # You can use ruby language constructs to keep from repeating
139
+ # yourself
140
+
141
+ # declare an aray - we are going to use it to collect some
142
+ # resources that we create
143
+ alarms = [];
144
+
145
+ # When we declare a resource with "Resource", we are
146
+ # actually calling a method on CfnDsl::CloudFormationTemplate
147
+ # that sets up the resource, and then returns it. We can use
148
+ # the return value for other means.
149
+ alarms.push Resource("CPUAlarmHigh") {
150
+ Type "AWS::CloudWatch::Alarm"
151
+ Property("AlarmDescription", "Scale-up if CPU > 90% for 10 minutes")
152
+ Property("Threshold", "90")
153
+ Property("AlarmActions", [ Ref("WebServerScaleUpPolicy" ) ])
154
+ Property("ComparisonOperator", "GreaterThanThreshold")
155
+ }
156
+
157
+ # Declare a second alarm resource and add it to our list
158
+ alarms.push Resource("CPUAlarmLow") {
159
+ Type "AWS::CloudWatch::Alarm"
160
+ Property("AlarmDescription", "Scale-down if CPU < 70% for 10 minutes")
161
+ Property("Threshold", "70")
162
+ Property("AlarmActions", [ Ref("WebServerScaleDownPolicy" ) ])
163
+ Property("ComparisonOperator", "LessThanThreshold")
164
+ }
165
+
166
+ # Ok, the alarms that we previously declared actually share a bunch
167
+ # of property declarations. Here we iterate through the alarms and
168
+ # call declare on each one, passing in a code block. This works the
169
+ # same as the declarations placed in the code blocks that went along
170
+ # with the call to Resource that was used to create the resouce above.
171
+ alarms.each do |alarm|
172
+ alarm.declare {
173
+ Property("MetricName", "CPUUtilization")
174
+ Property("Namespace", "AWS/EC2")
175
+ Property("Statistic", "Average")
176
+ Property("Period", "300")
177
+ Property("EvaluationPeriods", "2")
178
+ Property("Dimensions", [
179
+ {
180
+ "Name" => "AutoScalingGroupName",
181
+ "Value" => Ref("WebServerGroup" )
182
+ }
183
+ ])
184
+
185
+ }
186
+ end
187
+
188
+
189
+ Resource( "ElasticLoadBalancer" ) {
190
+ Type "AWS::ElasticLoadBalancing::LoadBalancer"
191
+ Property( "AvailabilityZones", FnGetAZs(""))
192
+ Property( "Listeners" , [ {
193
+ "LoadBalancerPort" => "80",
194
+ "InstancePort" => Ref( "WebServerPort" ),
195
+ "Protocol" => "HTTP"
196
+ } ] )
197
+ Property( "HealthCheck" , {
198
+ # FnFormat replaces %0, %1, etc with passed in parameters
199
+ # Note that it renders to a call to Fn::Join in the json.
200
+ "Target" => FnFormat("HTTP:%0/", Ref( "WebServerPort" ) ),
201
+ "HealthyThreshold" => "3",
202
+ "UnhealthyThreshold" => "5",
203
+ "Interval" => "30",
204
+ "Timeout" => "5"
205
+ })
206
+ }
207
+
208
+ Resource("InstanceSecurityGroup" ) {
209
+ Type "AWS::EC2::SecurityGroup"
210
+ Property("GroupDescription" , "Enable SSH access and HTTP access on the inbound port")
211
+ Property("SecurityGroupIngress", [ {
212
+ "IpProtocol" => "tcp",
213
+ "FromPort" => "22",
214
+ "ToPort" => "22",
215
+ "CidrIp" => "0.0.0.0/0"
216
+ },
217
+ {
218
+ "IpProtocol" => "tcp",
219
+ "FromPort" => Ref( "WebServerPort" ),
220
+ "ToPort" => Ref( "WebServerPort" ),
221
+ "SourceSecurityGroupOwnerId" => FnGetAtt("ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"),
222
+ "SourceSecurityGroupName" => FnGetAtt("ElasticLoadBalancer", "SourceSecurityGroup.GroupName")
223
+ } ])
224
+ }
225
+
226
+ Output( "URL" ) {
227
+ Description "The URL of the website"
228
+ Value FnJoin( "", [ "http://", FnGetAtt( "ElasticLoadBalancer", "DNSName" ) ] )
229
+ }
230
+
231
+ }
@@ -0,0 +1,33 @@
1
+
2
+ CloudFormation {
3
+ AWSTemplateFormatVersion "2010-09-09"
4
+
5
+ Description "Circular Reference"
6
+
7
+ Parameter("InstanceType") {
8
+ Description "Type of EC2 instance to launch"
9
+ Type "String"
10
+ Default "m1.small"
11
+ }
12
+
13
+ Resource("WebServerGroup") {
14
+ Type "AWS::AutoScaling::AutoScalingGroup"
15
+ Property("AvailabilityZones", FnGetAZs("") )
16
+ Property("LaunchConfigurationName", Ref( "LaunchConfig") )
17
+ Property("MinSize", "1")
18
+ Property("MaxSize", "3")
19
+ }
20
+
21
+
22
+ Resource( "LaunchConfig" ) {
23
+ Type "AWS::AutoScaling::LaunchConfiguration"
24
+ DependsOn ["WebServerGroup"]
25
+ Property("InstanceType", Ref("InstanceType") )
26
+ }
27
+
28
+
29
+ Output( "URL" ) {
30
+ Description "The URL of the website"
31
+ Value FnJoin( "", [ "http://", FnGetAtt( "LaunchConfig", "DNSName" ) ] )
32
+ }
33
+ }
@@ -0,0 +1,16 @@
1
+ CloudFormation {
2
+
3
+ DESCRIPTION ||= "default description"
4
+ MACHINES ||= 1
5
+
6
+ Description DESCRIPTION
7
+
8
+ (1..MACHINES).each do |i|
9
+ name = "machine#{i}"
10
+ Instance(name) {
11
+ ImageId "ami-12345678"
12
+ Type "t1.micro"
13
+ }
14
+ end
15
+
16
+ }