admiral-cloudformation 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +79 -0
- data/Rakefile +1 -0
- data/admiral.gemspec +24 -0
- data/examples/elasticsearch/CloudFormation.template +315 -0
- data/examples/elasticsearch/production.json +16 -0
- data/examples/meteor/CloudFormation.template +249 -0
- data/examples/meteor/production.json +10 -0
- data/examples/mongo/CloudFormation.template +132 -0
- data/examples/mongo/production.json +7 -0
- data/lib/admiral-cloudformation.rb +1 -0
- data/lib/admiral-cloudformation/tasks.rb +50 -0
- data/lib/admiral-cloudformation/util.rb +100 -0
- data/spec/test.json +3 -0
- data/spec/test.template +1 -0
- metadata +147 -0
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p547
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Peter T. Brown
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Admiral for AWS CloudFormation
|
2
|
+
|
3
|
+
An Admiral module that implements tasks for wielding AWS CloudFormation templates. Use it to manage CloudFormation templates and their parameters.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile (recommended):
|
8
|
+
|
9
|
+
gem 'admiral-cloudformation'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install admiral-cloudformation
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
On your command line type:
|
22
|
+
|
23
|
+
$ admiral cf help
|
24
|
+
|
25
|
+
To see a list of available commands. Make sure your bundle bin is in your PATH.
|
26
|
+
|
27
|
+
The following commands are available:
|
28
|
+
|
29
|
+
```
|
30
|
+
Commands:
|
31
|
+
admiral cf create # Create new CloudFormation stack for environment.
|
32
|
+
admiral cf destroy # Destroy the existing CloudFormation stack.
|
33
|
+
admiral cf help [COMMAND] # Describe subcommands or one specific subcommand
|
34
|
+
admiral cf update # Update the existing CloudFormation stack
|
35
|
+
|
36
|
+
Options:
|
37
|
+
--env, [--environment=ENVIRONMENT] # The environment (e.g. staging or production). Can also be specified with ADMIRAL_ENV.
|
38
|
+
# Default: production
|
39
|
+
[--template=TEMPLATE] # Path to CloudFormation JSON template.
|
40
|
+
# Default: CloudFormation.template
|
41
|
+
[--params=PARAMS] # Path to override parameter definitions file. Defaults to <environment>.json
|
42
|
+
```
|
43
|
+
|
44
|
+
# Setup and Configuration
|
45
|
+
|
46
|
+
Admiral CloudFormation is designed around the concept of deployment environments. You parameterize your CloudFormation templates, then encode specific parameter values in JSON files for each distinct environment.
|
47
|
+
|
48
|
+
For example you may have CloudFormation templates for your database servers and your web application servers, and distinct configurations for production, staging and test environments.
|
49
|
+
|
50
|
+
CloudFormation provides a facility to parameterize templates via the [`Parameters`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) section. For example:
|
51
|
+
|
52
|
+
```javascript
|
53
|
+
...
|
54
|
+
"InstanceType": {
|
55
|
+
"Description": "The type of instance to launch.",
|
56
|
+
"Type": "String",
|
57
|
+
"Default": "t2.small"
|
58
|
+
},
|
59
|
+
...
|
60
|
+
```
|
61
|
+
|
62
|
+
Admiral CloudFormation let's you specify specific values. For example:
|
63
|
+
|
64
|
+
```javascript
|
65
|
+
{
|
66
|
+
"InstanceCount":"2",
|
67
|
+
"InstanceType": "t2.medium",
|
68
|
+
}
|
69
|
+
```
|
70
|
+
|
71
|
+
## Examples
|
72
|
+
|
73
|
+
To create a new CloudFormation stack (and its associated resources) using a staging configuration:
|
74
|
+
|
75
|
+
$ admiral cf create --environment staging --template ./CloudFormation.template
|
76
|
+
|
77
|
+
# CloudFormation Templates
|
78
|
+
|
79
|
+
Example CloudFormation templates for ElasticSearch, Meteor and MongoDB are included in the `examples` directory.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/admiral.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "admiral-cloudformation"
|
7
|
+
spec.version = '0.0.2'
|
8
|
+
spec.authors = ["Peter T. Brown"]
|
9
|
+
spec.email = ["p@ptb.io"]
|
10
|
+
spec.description = %q{An Admiral module that implements tasks for wielding AWS CloudFormation templates. Use it to manage CloudFormation templates and their parameters.}
|
11
|
+
spec.summary = %q{A command line tool for wielding cloudformation templates.}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
20
|
+
spec.add_development_dependency "rake"
|
21
|
+
spec.add_dependency 'aws-sdk', '< 2'
|
22
|
+
spec.add_dependency 'thor', '~> 0.19'
|
23
|
+
spec.add_dependency 'admiral', '~> 0.0.1'
|
24
|
+
end
|
@@ -0,0 +1,315 @@
|
|
1
|
+
{
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
3
|
+
"Parameters": {
|
4
|
+
"CookbookRepo": {
|
5
|
+
"Description": "GitURL",
|
6
|
+
"Type": "String",
|
7
|
+
"Default": "https://github.com/ThoughtWorksStudios/opsworks-elasticsearch-cookbook"
|
8
|
+
},
|
9
|
+
|
10
|
+
"CookbookRepoRevision": {
|
11
|
+
"Description": "Git Revision/Tag",
|
12
|
+
"Type": "String",
|
13
|
+
"Default": "0.0.1"
|
14
|
+
},
|
15
|
+
|
16
|
+
"ElasticSearchVersion": {
|
17
|
+
"Description": "The version of ElasticSearch to install.",
|
18
|
+
"Type": "String",
|
19
|
+
"Default": "1.3.5"
|
20
|
+
},
|
21
|
+
|
22
|
+
"AwsRegion": {
|
23
|
+
"Description": "The AWS region",
|
24
|
+
"Type": "String",
|
25
|
+
"Default": "us-west-2"
|
26
|
+
},
|
27
|
+
|
28
|
+
"ElasticSearchAWSCloudPluginVersion": {
|
29
|
+
"Description": "The version of the ElasticSearch AWS Cloud Plugin to install. Note that this version MUST correspond to the targeted version of ElasticSearch. See https://github.com/elasticsearch/elasticsearch-cloud-aws for the version compatibility table.",
|
30
|
+
"Type": "String",
|
31
|
+
"Default": "2.3.0"
|
32
|
+
},
|
33
|
+
|
34
|
+
"RecipeList": {
|
35
|
+
"Description": "The list of cookbooks to include when setting up the cluster.",
|
36
|
+
"Type": "CommaDelimitedList",
|
37
|
+
"Default":"apt, ark,elasticsearch, elasticsearch::aws, elasticsearch::proxy, java, layer-custom::esplugins, layer-custom::allocation-awareness, layer-custom::esmonit, layer-custom::cloudwatch-custom"
|
38
|
+
},
|
39
|
+
|
40
|
+
"SSLCertificateName": {
|
41
|
+
"Description": "The SSL certificate.",
|
42
|
+
"Type": "String"
|
43
|
+
},
|
44
|
+
|
45
|
+
"InstanceCount": {
|
46
|
+
"Description": "Number of nodes to spin up in the cluster. This also configures the `expected_nodes` setting in ElasticSearch, which serves as a hint when the cluster considers shard reallocation.",
|
47
|
+
"Type": "String"
|
48
|
+
},
|
49
|
+
|
50
|
+
"InstanceType": {
|
51
|
+
"Description": "The type of instance to launch.",
|
52
|
+
"Type": "String",
|
53
|
+
"Default": "t2.small"
|
54
|
+
},
|
55
|
+
|
56
|
+
"MinMasterNodes": {
|
57
|
+
"Description": "Number of master eligible nodes visible to a given node before accepting requests. When this criterion is not satisfied, a given node will assume it has split off from from the cluster. This setting this helps avoid a catastrophic split-brain scenario in the cluster. This is typically is set to [N/2 + 1] nodes.",
|
58
|
+
"Type": "String"
|
59
|
+
},
|
60
|
+
|
61
|
+
"SearchUser": {
|
62
|
+
"Description": "username to access the ElasticSearch cluster.",
|
63
|
+
"Type": "String"
|
64
|
+
},
|
65
|
+
|
66
|
+
"SearchPassword": {
|
67
|
+
"Description": "password to access the ElasticSearch cluster.",
|
68
|
+
"Type": "String"
|
69
|
+
},
|
70
|
+
|
71
|
+
"ClusterName": {
|
72
|
+
"Description": "The name of the ElasticSearch cluster.",
|
73
|
+
"Type": "String"
|
74
|
+
},
|
75
|
+
|
76
|
+
"Route53ZoneName": {
|
77
|
+
"Description": "Route53 zone under which to setup the DNS record.",
|
78
|
+
"Type": "String"
|
79
|
+
},
|
80
|
+
|
81
|
+
"SearchDomainName": {
|
82
|
+
"Description": "Domain name to register for the cluster under Route53.",
|
83
|
+
"Type": "String"
|
84
|
+
},
|
85
|
+
|
86
|
+
"SshKeyName": {
|
87
|
+
"Description": "SSH key name for EC2 instances.",
|
88
|
+
"Type": "String"
|
89
|
+
},
|
90
|
+
|
91
|
+
"PaperTrailHost": {
|
92
|
+
"Description": "The PaperTrail endpoint hostname. Only required if you add the papertrail cookbook.",
|
93
|
+
"Type": "String",
|
94
|
+
"Default": "logs.papertrailapp.com"
|
95
|
+
},
|
96
|
+
|
97
|
+
"PaperTrailPort": {
|
98
|
+
"Description": "The PaperTrail endpoint port. Only required if you add the papertrail cookbook.",
|
99
|
+
"Type": "Number",
|
100
|
+
"Default": 0,
|
101
|
+
"MinValue" : "0",
|
102
|
+
"MaxValue" : "65535"
|
103
|
+
},
|
104
|
+
|
105
|
+
"SecurityGroupLoadBalancer": {
|
106
|
+
"Description": "The load balancer security group.",
|
107
|
+
"Type": "String"
|
108
|
+
},
|
109
|
+
|
110
|
+
"SecurityGroupSearchLayer": {
|
111
|
+
"Description": "The search layer security group.",
|
112
|
+
"Type": "String"
|
113
|
+
}
|
114
|
+
|
115
|
+
},
|
116
|
+
|
117
|
+
"Outputs": {
|
118
|
+
"StackId": {
|
119
|
+
"Description": "opsworks stack id ",
|
120
|
+
"Value": { "Ref": "SearchStack"}
|
121
|
+
},
|
122
|
+
|
123
|
+
"LayerId": {
|
124
|
+
"Description": "opsworks search layer id ",
|
125
|
+
"Value": { "Ref": "SearchLayer"}
|
126
|
+
}
|
127
|
+
|
128
|
+
},
|
129
|
+
|
130
|
+
"Resources": {
|
131
|
+
|
132
|
+
"LoadBalancer" : {
|
133
|
+
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
|
134
|
+
"Properties" : {
|
135
|
+
"AvailabilityZones" : { "Fn::GetAZs" : "" },
|
136
|
+
"Listeners" : [
|
137
|
+
{
|
138
|
+
"LoadBalancerPort" : "443",
|
139
|
+
"InstancePort" : "80",
|
140
|
+
"Protocol" : "HTTPS",
|
141
|
+
"SSLCertificateId": {
|
142
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":server-certificate/", { "Ref" : "SSLCertificateName" }]]
|
143
|
+
}
|
144
|
+
}
|
145
|
+
],
|
146
|
+
"HealthCheck" : {
|
147
|
+
"Target" : "TCP:80",
|
148
|
+
"HealthyThreshold" : "2",
|
149
|
+
"UnhealthyThreshold" : "8",
|
150
|
+
"Interval" : "30",
|
151
|
+
"Timeout" : "20"
|
152
|
+
},
|
153
|
+
"SecurityGroups": [
|
154
|
+
{"Ref": "SecurityGroupLoadBalancer"}
|
155
|
+
]
|
156
|
+
}
|
157
|
+
},
|
158
|
+
|
159
|
+
"DNSRecord": {
|
160
|
+
"Type" : "AWS::Route53::RecordSet",
|
161
|
+
"Properties" : {
|
162
|
+
"HostedZoneName" : {"Ref": "Route53ZoneName"},
|
163
|
+
"Type" : "CNAME",
|
164
|
+
"Name" : { "Ref": "SearchDomainName"},
|
165
|
+
"ResourceRecords" : [ {"Fn::GetAtt":["LoadBalancer","DNSName"]}],
|
166
|
+
"TTL" : "30"
|
167
|
+
}
|
168
|
+
},
|
169
|
+
|
170
|
+
"ELBAttachment" : {
|
171
|
+
"Type" : "AWS::OpsWorks::ElasticLoadBalancerAttachment",
|
172
|
+
"Properties" : {
|
173
|
+
"ElasticLoadBalancerName" : { "Ref" : "LoadBalancer" },
|
174
|
+
"LayerId" : { "Ref" : "SearchLayer" }
|
175
|
+
}
|
176
|
+
},
|
177
|
+
|
178
|
+
|
179
|
+
"SearchStack": {
|
180
|
+
"Type": "AWS::OpsWorks::Stack",
|
181
|
+
"Properties": {
|
182
|
+
"Name": {
|
183
|
+
"Ref": "AWS::StackName"
|
184
|
+
},
|
185
|
+
"CustomJson": {
|
186
|
+
"java": {
|
187
|
+
"jdk_version": "7",
|
188
|
+
"oracle": {
|
189
|
+
"accept_oracle_download_terms": "true"
|
190
|
+
},
|
191
|
+
"accept_license_agreement": "true",
|
192
|
+
"install_flavor": "oracle"
|
193
|
+
},
|
194
|
+
"papertrail": {
|
195
|
+
"remote_host": { "Ref": "PaperTrailHost" },
|
196
|
+
"remote_port": { "Ref": "PaperTrailPort" },
|
197
|
+
"watch_files": [
|
198
|
+
{ "filename": { "Fn::Join": ["", ["/usr/local/var/log/elasticsearch/", { "Ref": "ClusterName" }, ".log"]] }, "tag": "search" },
|
199
|
+
{ "filename": { "Fn::Join": ["", ["/usr/local/var/log/elasticsearch/", { "Ref": "ClusterName" }, "_index_indexing_slowlog.log"]] }, "tag": "indexing-slowlog" },
|
200
|
+
{ "filename": { "Fn::Join": ["", ["/usr/local/var/log/elasticsearch/", { "Ref": "ClusterName" }, "_index_search_slowlog.log"]] }, "tag": "search-slowlog" }
|
201
|
+
]
|
202
|
+
},
|
203
|
+
"elasticsearch": {
|
204
|
+
"version": { "Ref": "ElasticSearchVersion" },
|
205
|
+
"plugins" : {
|
206
|
+
"elasticsearch/elasticsearch-cloud-aws": {
|
207
|
+
"version": { "Ref": "ElasticSearchAWSCloudPluginVersion" }
|
208
|
+
}
|
209
|
+
},
|
210
|
+
"nginx": {
|
211
|
+
"users": [{
|
212
|
+
"username": { "Ref": "SearchUser" },
|
213
|
+
"password": { "Ref": "SearchPassword" }
|
214
|
+
}],
|
215
|
+
"allow_cluster_api": "true",
|
216
|
+
"port": 80
|
217
|
+
},
|
218
|
+
"cluster": {
|
219
|
+
"name": { "Ref" : "ClusterName" }
|
220
|
+
},
|
221
|
+
"gateway": {
|
222
|
+
"expected_nodes": { "Ref": "InstanceCount" }
|
223
|
+
},
|
224
|
+
"discovery": {
|
225
|
+
"type": "ec2",
|
226
|
+
"zen": {
|
227
|
+
"minimum_master_nodes": { "Ref": "MinMasterNodes" },
|
228
|
+
"ping": {
|
229
|
+
"multicast": {
|
230
|
+
"enabled": false
|
231
|
+
}
|
232
|
+
}
|
233
|
+
},
|
234
|
+
"ec2": {
|
235
|
+
"tag": {
|
236
|
+
"opsworks:stack": {
|
237
|
+
"Ref": "AWS::StackName"
|
238
|
+
}
|
239
|
+
}
|
240
|
+
}
|
241
|
+
},
|
242
|
+
"path": {
|
243
|
+
"data": "/mnt/elasticsearch-data"
|
244
|
+
},
|
245
|
+
"cloud": {
|
246
|
+
"aws": {
|
247
|
+
"region": { "Ref": "AwsRegion" }
|
248
|
+
}
|
249
|
+
},
|
250
|
+
"custom_config": {
|
251
|
+
"cluster.routing.allocation.awareness.attributes": "rack_id",
|
252
|
+
"index": "\n analysis:\n analyzer:\n default_index:\n filter:\n - standard\n - lowercase\n - snowball\n tokenizer: standard\n default_search:\n tokenizer: standard\n filter:\n - standard\n - lowercase\n - snowball\n"
|
253
|
+
}
|
254
|
+
}
|
255
|
+
},
|
256
|
+
"ServiceRoleArn": {
|
257
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":role/aws-opsworks-service-role"]]
|
258
|
+
},
|
259
|
+
"DefaultInstanceProfileArn": {
|
260
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":instance-profile/aws-opsworks-ec2-role"]]
|
261
|
+
},
|
262
|
+
"ConfigurationManager": {
|
263
|
+
"Name": "Chef",
|
264
|
+
"Version": "11.10"
|
265
|
+
},
|
266
|
+
"ChefConfiguration": {
|
267
|
+
"BerkshelfVersion": "3.1.3",
|
268
|
+
"ManageBerkshelf": true
|
269
|
+
},
|
270
|
+
"DefaultOs": "Amazon Linux 2015.03",
|
271
|
+
"DefaultRootDeviceType": "ebs",
|
272
|
+
"DefaultSshKeyName": { "Ref": "SshKeyName" },
|
273
|
+
"UseCustomCookbooks": true,
|
274
|
+
"UseOpsworksSecurityGroups": false,
|
275
|
+
"CustomCookbooksSource": {
|
276
|
+
"Type": "git",
|
277
|
+
"Url": {
|
278
|
+
"Ref": "CookbookRepo"
|
279
|
+
},
|
280
|
+
"Revision": { "Ref": "CookbookRepoRevision" }
|
281
|
+
}
|
282
|
+
}
|
283
|
+
},
|
284
|
+
|
285
|
+
"SearchLayer": {
|
286
|
+
"Type": "AWS::OpsWorks::Layer",
|
287
|
+
"Properties": {
|
288
|
+
"StackId": {
|
289
|
+
"Ref": "SearchStack"
|
290
|
+
},
|
291
|
+
"Name": "Search",
|
292
|
+
"Type": "custom",
|
293
|
+
"Shortname": "search",
|
294
|
+
"CustomRecipes": {
|
295
|
+
"Setup": { "Ref": "RecipeList" }
|
296
|
+
},
|
297
|
+
"EnableAutoHealing": false,
|
298
|
+
"AutoAssignElasticIps": false,
|
299
|
+
"AutoAssignPublicIps": true,
|
300
|
+
"VolumeConfigurations": [
|
301
|
+
{
|
302
|
+
"MountPoint": "/mnt/elasticsearch-data",
|
303
|
+
"NumberOfDisks": 1,
|
304
|
+
"Size": 200,
|
305
|
+
"VolumeType": "gp2"
|
306
|
+
}
|
307
|
+
],
|
308
|
+
"CustomSecurityGroupIds": [
|
309
|
+
{"Ref": "SecurityGroupSearchLayer"}
|
310
|
+
]
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
}
|
315
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"Route53ZoneName": "example.io.",
|
3
|
+
"SearchDomainName": "search.example.io",
|
4
|
+
"SSLCertificateName": "search.example.io",
|
5
|
+
"SshKeyName": "production",
|
6
|
+
"InstanceCount":"2",
|
7
|
+
"InstanceType": "t2.medium",
|
8
|
+
"ElasticSearchVersion": "1.4.4",
|
9
|
+
"ElasticSearchAWSCloudPluginVersion": "2.4.1",
|
10
|
+
"SearchUser":"admin",
|
11
|
+
"SearchPassword":"example-password",
|
12
|
+
"ClusterName": "staging-cluster",
|
13
|
+
"MinMasterNodes": "1",
|
14
|
+
"SecurityGroupLoadBalancer": "sg-8aab365ef",
|
15
|
+
"SecurityGroupSearchLayer": "sg-9e9d35f8"
|
16
|
+
}
|
@@ -0,0 +1,249 @@
|
|
1
|
+
{
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
3
|
+
"Parameters": {
|
4
|
+
"CookbookRepo": {
|
5
|
+
"Description": "GitURL",
|
6
|
+
"Type": "String",
|
7
|
+
"Default": "https://github.com/flippyhead/chef-mongodb"
|
8
|
+
},
|
9
|
+
|
10
|
+
"CookbookRepoRevision": {
|
11
|
+
"Description": "Git Revision/Tag",
|
12
|
+
"Type": "String",
|
13
|
+
"Default": "0.0.1"
|
14
|
+
},
|
15
|
+
|
16
|
+
"Route53ZoneName": {
|
17
|
+
"Description": "Route53 zone under which to setup the DNS record.",
|
18
|
+
"Type": "String"
|
19
|
+
},
|
20
|
+
|
21
|
+
"AppDomainName": {
|
22
|
+
"Description": "Domain name to register for the app under Route53.",
|
23
|
+
"Type": "String"
|
24
|
+
},
|
25
|
+
|
26
|
+
"SSLCertificateName": {
|
27
|
+
"Description": "The SSL certificate.",
|
28
|
+
"Type": "String"
|
29
|
+
},
|
30
|
+
|
31
|
+
"SshKeyName": {
|
32
|
+
"Description": "SSH key name for EC2 instances.",
|
33
|
+
"Type": "String"
|
34
|
+
},
|
35
|
+
|
36
|
+
"InstanceCount": {
|
37
|
+
"Description": "The number of instances to launch.",
|
38
|
+
"Type": "Number",
|
39
|
+
"Default": 1
|
40
|
+
},
|
41
|
+
|
42
|
+
"InstanceType": {
|
43
|
+
"Description": "The type of instance to launch.",
|
44
|
+
"Type": "String",
|
45
|
+
"Default": "t2.small"
|
46
|
+
},
|
47
|
+
|
48
|
+
"SecurityGroupLoadBalancer": {
|
49
|
+
"Description": "The load balancer security group.",
|
50
|
+
"Type": "String"
|
51
|
+
},
|
52
|
+
|
53
|
+
"SecurityGroupMeteorLayer": {
|
54
|
+
"Description": "The meteor layer security group.",
|
55
|
+
"Type": "String"
|
56
|
+
}
|
57
|
+
|
58
|
+
},
|
59
|
+
|
60
|
+
"Outputs": {
|
61
|
+
"StackId": {
|
62
|
+
"Description": "opsworks stack id ",
|
63
|
+
"Value": { "Ref": "MeteorStack"}
|
64
|
+
},
|
65
|
+
|
66
|
+
"LayerId": {
|
67
|
+
"Description": "opsworks search layer id ",
|
68
|
+
"Value": { "Ref": "MeteorLayer"}
|
69
|
+
},
|
70
|
+
|
71
|
+
"PrimaryAppId": {
|
72
|
+
"Description": "fetching app id ",
|
73
|
+
"Value": { "Ref": "FetchingApp"}
|
74
|
+
},
|
75
|
+
|
76
|
+
"SecondaryAppId": {
|
77
|
+
"Description": "exporter app id ",
|
78
|
+
"Value": { "Ref": "FetchingExporter"}
|
79
|
+
}
|
80
|
+
|
81
|
+
},
|
82
|
+
|
83
|
+
"Resources": {
|
84
|
+
|
85
|
+
"LoadBalancer" : {
|
86
|
+
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
|
87
|
+
"Properties" : {
|
88
|
+
"AvailabilityZones" : { "Fn::GetAZs" : "" },
|
89
|
+
"Listeners" : [
|
90
|
+
{
|
91
|
+
"LoadBalancerPort" : "443",
|
92
|
+
"InstancePort" : "80",
|
93
|
+
"Protocol" : "SSL",
|
94
|
+
"SSLCertificateId": {
|
95
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":server-certificate/", { "Ref" : "SSLCertificateName" }]]
|
96
|
+
}
|
97
|
+
},
|
98
|
+
{
|
99
|
+
"LoadBalancerPort" : "80",
|
100
|
+
"InstancePort" : "80",
|
101
|
+
"Protocol" : "HTTP"
|
102
|
+
}
|
103
|
+
],
|
104
|
+
"HealthCheck" : {
|
105
|
+
"Target" : "TCP:80",
|
106
|
+
"HealthyThreshold" : "2",
|
107
|
+
"UnhealthyThreshold" : "8",
|
108
|
+
"Interval" : "30",
|
109
|
+
"Timeout" : "20"
|
110
|
+
},
|
111
|
+
"SecurityGroups": [
|
112
|
+
{"Ref": "SecurityGroupLoadBalancer"}
|
113
|
+
]
|
114
|
+
}
|
115
|
+
},
|
116
|
+
|
117
|
+
"DNSRecord": {
|
118
|
+
"Type" : "AWS::Route53::RecordSet",
|
119
|
+
"Properties" : {
|
120
|
+
"HostedZoneName" : {"Ref": "Route53ZoneName"},
|
121
|
+
"Type" : "CNAME",
|
122
|
+
"Name" : { "Ref": "AppDomainName"},
|
123
|
+
"ResourceRecords" : [ {"Fn::GetAtt":["LoadBalancer","DNSName"]}],
|
124
|
+
"TTL" : "30"
|
125
|
+
}
|
126
|
+
},
|
127
|
+
|
128
|
+
"ELBAttachment" : {
|
129
|
+
"Type" : "AWS::OpsWorks::ElasticLoadBalancerAttachment",
|
130
|
+
"Properties" : {
|
131
|
+
"ElasticLoadBalancerName" : { "Ref" : "LoadBalancer" },
|
132
|
+
"LayerId" : { "Ref" : "MeteorLayer" }
|
133
|
+
}
|
134
|
+
},
|
135
|
+
|
136
|
+
"MeteorStack": {
|
137
|
+
"Type": "AWS::OpsWorks::Stack",
|
138
|
+
"Properties": {
|
139
|
+
"Name": {
|
140
|
+
"Ref": "AWS::StackName"
|
141
|
+
},
|
142
|
+
"CustomJson": {
|
143
|
+
"opsworks_nodejs":{
|
144
|
+
"version":"0.10.38"
|
145
|
+
},
|
146
|
+
"deploy": {
|
147
|
+
"primary-app": {
|
148
|
+
"nodejs": {
|
149
|
+
"port": 80
|
150
|
+
},
|
151
|
+
"environment_variables": {
|
152
|
+
"METEOR_SETTINGS": "{}"
|
153
|
+
}
|
154
|
+
},
|
155
|
+
"secondary-app": {
|
156
|
+
"nodejs": {
|
157
|
+
"port": 8081
|
158
|
+
},
|
159
|
+
"environment_variables": {
|
160
|
+
"METEOR_SETTINGS": "{}"
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
},
|
165
|
+
"ServiceRoleArn": {
|
166
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":role/aws-opsworks-service-role"]]
|
167
|
+
},
|
168
|
+
"DefaultInstanceProfileArn": {
|
169
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":instance-profile/aws-opsworks-ec2-role"]]
|
170
|
+
},
|
171
|
+
"ConfigurationManager": {
|
172
|
+
"Name": "Chef",
|
173
|
+
"Version": "11.10"
|
174
|
+
},
|
175
|
+
"ChefConfiguration": {
|
176
|
+
"BerkshelfVersion": "3.1.3",
|
177
|
+
"ManageBerkshelf": true
|
178
|
+
},
|
179
|
+
"DefaultOs": "Amazon Linux 2015.03",
|
180
|
+
"DefaultRootDeviceType": "ebs",
|
181
|
+
"DefaultSshKeyName": { "Ref": "SshKeyName" },
|
182
|
+
"UseCustomCookbooks": false,
|
183
|
+
"UseOpsworksSecurityGroups": false,
|
184
|
+
"CustomCookbooksSource": {
|
185
|
+
"Type": "git",
|
186
|
+
"Url": {
|
187
|
+
"Ref": "CookbookRepo"
|
188
|
+
},
|
189
|
+
"Revision": { "Ref": "CookbookRepoRevision" }
|
190
|
+
}
|
191
|
+
}
|
192
|
+
},
|
193
|
+
|
194
|
+
"MeteorLayer": {
|
195
|
+
"Type": "AWS::OpsWorks::Layer",
|
196
|
+
"Properties": {
|
197
|
+
"StackId": {
|
198
|
+
"Ref": "MeteorStack"
|
199
|
+
},
|
200
|
+
"Name": "Meteor",
|
201
|
+
"Type": "nodejs-app",
|
202
|
+
"Shortname": "meteor",
|
203
|
+
"EnableAutoHealing": false,
|
204
|
+
"AutoAssignElasticIps": false,
|
205
|
+
"AutoAssignPublicIps": true,
|
206
|
+
"CustomSecurityGroupIds": [
|
207
|
+
{"Ref": "SecurityGroupMeteorLayer"}
|
208
|
+
]
|
209
|
+
}
|
210
|
+
},
|
211
|
+
|
212
|
+
"PrimaryApp": {
|
213
|
+
"Type":"AWS::OpsWorks::App",
|
214
|
+
"Properties": {
|
215
|
+
"Type": "nodejs",
|
216
|
+
"Name": "Fetching Application",
|
217
|
+
"Shortname": "fetching-app",
|
218
|
+
"StackId": {
|
219
|
+
"Ref": "MeteorStack"
|
220
|
+
},
|
221
|
+
"AppSource": {
|
222
|
+
"Username": "AKDIKDSKSKEWS",
|
223
|
+
"Password": "x6gYSTr+qDSKDFJSLdksldjfLAKDjdRE8mKi1bAZXm",
|
224
|
+
"Type": "s3",
|
225
|
+
"Url":"https://s3-us-west-2.amazonaws.com/primary-builds/primary-app.tar.gz"
|
226
|
+
}
|
227
|
+
}
|
228
|
+
},
|
229
|
+
|
230
|
+
"SecondaryApp": {
|
231
|
+
"Type":"AWS::OpsWorks::App",
|
232
|
+
"Properties": {
|
233
|
+
"Type": "nodejs",
|
234
|
+
"Name": "Fetching Exporter",
|
235
|
+
"Shortname": "fetching-exporter",
|
236
|
+
"StackId": {
|
237
|
+
"Ref": "MeteorStack"
|
238
|
+
},
|
239
|
+
"AppSource": {
|
240
|
+
"Username": "AKDIKDSKSKEWS",
|
241
|
+
"Password": "x6gYSTr+qDSKDFJSLdksldjfLAKDjdRE8mKi1bAZXm",
|
242
|
+
"Type": "s3",
|
243
|
+
"Url":"https://s3-us-west-2.amazonaws.com/secondary-builds/secondary-app.tar.gz"
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
}
|
249
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
{
|
2
|
+
"Route53ZoneName": "example.io.",
|
3
|
+
"AppDomainName": "app.example.io",
|
4
|
+
"SSLCertificateName": "app.example.io",
|
5
|
+
"SshKeyName": "production",
|
6
|
+
"InstanceCount":"1",
|
7
|
+
"InstanceType": "t2.small",
|
8
|
+
"SecurityGroupLoadBalancer": "sg-8ad62234ef",
|
9
|
+
"SecurityGroupMeteorLayer": "sg-2265dsd7"
|
10
|
+
}
|
@@ -0,0 +1,132 @@
|
|
1
|
+
{
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
3
|
+
"Parameters": {
|
4
|
+
"CookbookRepo": {
|
5
|
+
"Description": "GitURL",
|
6
|
+
"Type": "String",
|
7
|
+
"Default": "https://github.com/flippyhead/chef-mongodb"
|
8
|
+
},
|
9
|
+
|
10
|
+
"MongoVersion": {
|
11
|
+
"Description": "The version of MongoDB to install.",
|
12
|
+
"Type": "String",
|
13
|
+
"Default": "2.6.1"
|
14
|
+
},
|
15
|
+
|
16
|
+
"RecipeList": {
|
17
|
+
"Description": "The list of cookbooks to include when setting up the cluster.",
|
18
|
+
"Type": "CommaDelimitedList",
|
19
|
+
"Default": "mongodb::10gen_repo, mongodb::default"
|
20
|
+
},
|
21
|
+
|
22
|
+
"SshKeyName": {
|
23
|
+
"Description": "SSH key name for EC2 instances.",
|
24
|
+
"Type": "String"
|
25
|
+
},
|
26
|
+
|
27
|
+
"InstanceCount": {
|
28
|
+
"Description": "The number of instances to launch.",
|
29
|
+
"Type": "Number",
|
30
|
+
"Default": 1
|
31
|
+
},
|
32
|
+
|
33
|
+
"InstanceType": {
|
34
|
+
"Description": "The type of instance to launch.",
|
35
|
+
"Type": "String",
|
36
|
+
"Default": "t2.small"
|
37
|
+
},
|
38
|
+
|
39
|
+
"SecurityGroupMongoLayer": {
|
40
|
+
"Description": "The mongo layer security group.",
|
41
|
+
"Type": "String"
|
42
|
+
}
|
43
|
+
|
44
|
+
},
|
45
|
+
|
46
|
+
"Outputs": {
|
47
|
+
"StackId": {
|
48
|
+
"Description": "opsworks stack id ",
|
49
|
+
"Value": { "Ref": "MongoStack"}
|
50
|
+
},
|
51
|
+
|
52
|
+
"LayerId": {
|
53
|
+
"Description": "opsworks mongo layer id ",
|
54
|
+
"Value": { "Ref": "MongoLayer"}
|
55
|
+
}
|
56
|
+
|
57
|
+
},
|
58
|
+
|
59
|
+
"Resources": {
|
60
|
+
|
61
|
+
"MongoStack": {
|
62
|
+
"Type": "AWS::OpsWorks::Stack",
|
63
|
+
"Properties": {
|
64
|
+
"Name": {
|
65
|
+
"Ref": "AWS::StackName"
|
66
|
+
},
|
67
|
+
"CustomJson": {
|
68
|
+
"mongodb": {
|
69
|
+
"config":{
|
70
|
+
"dbpath": "/mnt/mongodb-data"
|
71
|
+
}
|
72
|
+
}
|
73
|
+
},
|
74
|
+
"ServiceRoleArn": {
|
75
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":role/aws-opsworks-service-role"]]
|
76
|
+
},
|
77
|
+
"DefaultInstanceProfileArn": {
|
78
|
+
"Fn::Join": ["", ["arn:aws:iam::", { "Ref": "AWS::AccountId" }, ":instance-profile/aws-opsworks-ec2-role"]]
|
79
|
+
},
|
80
|
+
"ConfigurationManager": {
|
81
|
+
"Name": "Chef",
|
82
|
+
"Version": "11.10"
|
83
|
+
},
|
84
|
+
"ChefConfiguration": {
|
85
|
+
"BerkshelfVersion": "3.1.3",
|
86
|
+
"ManageBerkshelf": true
|
87
|
+
},
|
88
|
+
"DefaultOs": "Ubuntu 14.04 LTS",
|
89
|
+
"DefaultRootDeviceType": "ebs",
|
90
|
+
"DefaultSshKeyName": { "Ref": "SshKeyName" },
|
91
|
+
"UseCustomCookbooks": true,
|
92
|
+
"UseOpsworksSecurityGroups": false,
|
93
|
+
"CustomCookbooksSource": {
|
94
|
+
"Type": "git",
|
95
|
+
"Url": {
|
96
|
+
"Ref": "CookbookRepo"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
},
|
101
|
+
|
102
|
+
"MongoLayer": {
|
103
|
+
"Type": "AWS::OpsWorks::Layer",
|
104
|
+
"Properties": {
|
105
|
+
"StackId": {
|
106
|
+
"Ref": "MongoStack"
|
107
|
+
},
|
108
|
+
"Name": "Mongo",
|
109
|
+
"Type": "custom",
|
110
|
+
"Shortname": "mongo",
|
111
|
+
"CustomRecipes": {
|
112
|
+
"Setup": { "Ref": "RecipeList" }
|
113
|
+
},
|
114
|
+
"EnableAutoHealing": false,
|
115
|
+
"AutoAssignElasticIps": false,
|
116
|
+
"AutoAssignPublicIps": true,
|
117
|
+
"VolumeConfigurations": [
|
118
|
+
{
|
119
|
+
"MountPoint": "/mnt/mongodb-data",
|
120
|
+
"NumberOfDisks": 1,
|
121
|
+
"Size": 200,
|
122
|
+
"VolumeType": "gp2"
|
123
|
+
}
|
124
|
+
],
|
125
|
+
"CustomSecurityGroupIds": [
|
126
|
+
{"Ref": "SecurityGroupMongoLayer"}
|
127
|
+
]
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
}
|
132
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
require "admiral-cloudformation/tasks"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'thor'
|
3
|
+
require 'admiral/base'
|
4
|
+
require_relative 'util'
|
5
|
+
|
6
|
+
module Admiral
|
7
|
+
module Tasks
|
8
|
+
class CloudFormation < Thor
|
9
|
+
extend Admiral::Base
|
10
|
+
include Util::CloudFormation
|
11
|
+
|
12
|
+
NAME = 'cf'
|
13
|
+
USAGE = 'cf <command> <options>'
|
14
|
+
DESCRIPTION = 'Commands for wielding AWS CloudFormation templates.'
|
15
|
+
|
16
|
+
namespace :cf
|
17
|
+
|
18
|
+
class_option :template,
|
19
|
+
desc: 'Path to CloudFormation JSON template.',
|
20
|
+
default: 'CloudFormation.template'
|
21
|
+
|
22
|
+
class_option :params,
|
23
|
+
desc: 'Path to override parameter definitions file. Defaults to <environment>.json'
|
24
|
+
|
25
|
+
|
26
|
+
desc 'create', 'Create new CloudFormation stack for environment.'
|
27
|
+
|
28
|
+
def create
|
29
|
+
template = File.read options[:template]
|
30
|
+
create_stack stack_name(options[:environment]), template, params(options[:environment])
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
desc 'update', 'Update the existing CloudFormation stack'
|
35
|
+
|
36
|
+
def update
|
37
|
+
template = File.read options[:template]
|
38
|
+
update_stack stack_name(options[:environment]), template, params(options[:environment])
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
desc 'destroy', 'Destroy the existing CloudFormation stack.'
|
43
|
+
|
44
|
+
def destroy
|
45
|
+
super stack_name options[:environment]
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'aws-sdk-v1'
|
2
|
+
|
3
|
+
module Admiral
|
4
|
+
module Util
|
5
|
+
module CloudFormation
|
6
|
+
|
7
|
+
SUCCESS_STATS = [:create_complete, :update_complete, :update_rollback_complete]
|
8
|
+
FAILED_STATS = [:create_failed, :update_failed, :rollback_complete]
|
9
|
+
DEFAULT_RECIPES = [].join(",")
|
10
|
+
|
11
|
+
def client
|
12
|
+
AWS::CloudFormation.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_stack(stack_name, template, params)
|
16
|
+
stack = client.stacks[stack_name]
|
17
|
+
|
18
|
+
if stack.exists?
|
19
|
+
raise '[admiral] Stack already exists. Use update command instead.'
|
20
|
+
end
|
21
|
+
|
22
|
+
puts "[admiral] Creating CloudFormation stack #{stack_name}."
|
23
|
+
begin
|
24
|
+
stack = client.stacks.create(stack_name, template, :parameters => params)
|
25
|
+
wait_for_stack_op_to_finish stack
|
26
|
+
rescue => e
|
27
|
+
puts "[admiral] Error creating stack #{stack_name}: #{e}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_stack(stack_name, template, params)
|
32
|
+
stack = client.stacks[stack_name]
|
33
|
+
|
34
|
+
unless stack.exists?
|
35
|
+
raise "[admiral] CloudFormation stack #{stack_name} doesn't exist. Use create instead."
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
puts "[admiral] Updating CloudFormation stack #{stack_name}"
|
40
|
+
stack.update(:template => template, :parameters => params)
|
41
|
+
wait_for_stack_op_to_finish stack
|
42
|
+
rescue => e
|
43
|
+
puts "[admiral] Error updating stack #{stack_name}: #{e}"
|
44
|
+
# raise unless e.message =~ /No updates are to be performed/
|
45
|
+
# puts "Your CloudFormation stack is already up to date"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def destroy(stack_name)
|
50
|
+
stack = client.stacks[stack_name]
|
51
|
+
|
52
|
+
if stack.exists?
|
53
|
+
puts "Deleting stack #{stack_name}"
|
54
|
+
stack.delete
|
55
|
+
else
|
56
|
+
puts "Environment does not exist"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def stack_name(env)
|
61
|
+
"#{env}-#{name}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def name
|
65
|
+
ENV["ADMIRAL_NAME"] || "test"
|
66
|
+
end
|
67
|
+
|
68
|
+
def params(env, options = {})
|
69
|
+
JSON.parse File.read(options[:params] || "#{env}.json")
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def wait_for_stack_op_to_finish(stack)
|
75
|
+
stats = stack.status.downcase.to_sym
|
76
|
+
puts "[admiral] Stack #{stack.name} current status: #{stats}"
|
77
|
+
|
78
|
+
while !SUCCESS_STATS.include?(stats)
|
79
|
+
sleep 15
|
80
|
+
stats = stack.status.downcase.to_sym
|
81
|
+
raise "[admiral] Resource stack update failed." if FAILED_STATS.include?(stats)
|
82
|
+
puts "[admiral] Stack #{stack.name} current status: #{stats}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def cf_query_output(stack, key)
|
87
|
+
output = stack.outputs.find do |o|
|
88
|
+
/#{key}/i =~ o.key
|
89
|
+
end
|
90
|
+
output && output.value
|
91
|
+
end
|
92
|
+
|
93
|
+
def all_availability_zones
|
94
|
+
ec2 = AWS::EC2.new
|
95
|
+
ec2.availability_zones.map(&:name)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/spec/test.json
ADDED
data/spec/test.template
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{}
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: admiral-cloudformation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Peter T. Brown
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-05-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: aws-sdk
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - <
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - <
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: thor
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.19'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.19'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: admiral
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.0.1
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.0.1
|
94
|
+
description: An Admiral module that implements tasks for wielding AWS CloudFormation
|
95
|
+
templates. Use it to manage CloudFormation templates and their parameters.
|
96
|
+
email:
|
97
|
+
- p@ptb.io
|
98
|
+
executables: []
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- .ruby-version
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- admiral.gemspec
|
109
|
+
- examples/elasticsearch/CloudFormation.template
|
110
|
+
- examples/elasticsearch/production.json
|
111
|
+
- examples/meteor/CloudFormation.template
|
112
|
+
- examples/meteor/production.json
|
113
|
+
- examples/mongo/CloudFormation.template
|
114
|
+
- examples/mongo/production.json
|
115
|
+
- lib/admiral-cloudformation.rb
|
116
|
+
- lib/admiral-cloudformation/tasks.rb
|
117
|
+
- lib/admiral-cloudformation/util.rb
|
118
|
+
- spec/test.json
|
119
|
+
- spec/test.template
|
120
|
+
homepage: ''
|
121
|
+
licenses:
|
122
|
+
- MIT
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 1.8.23.2
|
142
|
+
signing_key:
|
143
|
+
specification_version: 3
|
144
|
+
summary: A command line tool for wielding cloudformation templates.
|
145
|
+
test_files:
|
146
|
+
- spec/test.json
|
147
|
+
- spec/test.template
|