enscalator 0.4.0.pre.alpha.pre.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +59 -0
- data/.travis.yml +22 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +148 -0
- data/Rakefile +43 -0
- data/bin/console +11 -0
- data/bin/setup +7 -0
- data/enscalator.gemspec +57 -0
- data/exe/enscalator +13 -0
- data/lib/enscalator/core/cf_parameters.rb +146 -0
- data/lib/enscalator/core/cf_resources.rb +225 -0
- data/lib/enscalator/core/instance_type.rb +205 -0
- data/lib/enscalator/core/network_config.rb +21 -0
- data/lib/enscalator/core.rb +10 -0
- data/lib/enscalator/enapp.rb +248 -0
- data/lib/enscalator/helpers/dns.rb +62 -0
- data/lib/enscalator/helpers/stack.rb +107 -0
- data/lib/enscalator/helpers/sub_process.rb +72 -0
- data/lib/enscalator/helpers/wrappers.rb +55 -0
- data/lib/enscalator/helpers.rb +127 -0
- data/lib/enscalator/plugins/amazon_linux.rb +93 -0
- data/lib/enscalator/plugins/auto_scale.rb +80 -0
- data/lib/enscalator/plugins/core_os.rb +88 -0
- data/lib/enscalator/plugins/couchbase.rb +98 -0
- data/lib/enscalator/plugins/debian.rb +71 -0
- data/lib/enscalator/plugins/elastic_beanstalk.rb +74 -0
- data/lib/enscalator/plugins/elasticache.rb +168 -0
- data/lib/enscalator/plugins/elasticsearch_amazon.rb +75 -0
- data/lib/enscalator/plugins/elasticsearch_bitnami.rb +198 -0
- data/lib/enscalator/plugins/elasticsearch_opsworks.rb +225 -0
- data/lib/enscalator/plugins/elb.rb +139 -0
- data/lib/enscalator/plugins/nat_gateway.rb +71 -0
- data/lib/enscalator/plugins/rds.rb +141 -0
- data/lib/enscalator/plugins/redis.rb +38 -0
- data/lib/enscalator/plugins/rethink_db.rb +21 -0
- data/lib/enscalator/plugins/route53.rb +143 -0
- data/lib/enscalator/plugins/ubuntu.rb +85 -0
- data/lib/enscalator/plugins/user-data/elasticsearch +367 -0
- data/lib/enscalator/plugins/vpc_peering_connection.rb +48 -0
- data/lib/enscalator/plugins.rb +30 -0
- data/lib/enscalator/rich_template_dsl.rb +209 -0
- data/lib/enscalator/templates/vpc_peering.rb +112 -0
- data/lib/enscalator/templates.rb +20 -0
- data/lib/enscalator/version.rb +5 -0
- data/lib/enscalator/vpc.rb +11 -0
- data/lib/enscalator/vpc_with_nat_gateway.rb +311 -0
- data/lib/enscalator/vpc_with_nat_instance.rb +402 -0
- data/lib/enscalator.rb +103 -0
- metadata +427 -0
@@ -0,0 +1,402 @@
|
|
1
|
+
module Enscalator
|
2
|
+
module Templates
|
3
|
+
# Amazon AWS Virtual Private Cloud template with NAT instance
|
4
|
+
class VPCWithNATInstance < Enscalator::RichTemplateDSL
|
5
|
+
# Subnet size (256 addresses)
|
6
|
+
SUBNET_CIDR_BLOCK_SIZE = 24
|
7
|
+
|
8
|
+
# Template method
|
9
|
+
def tpl
|
10
|
+
description = <<-EOS.gsub(/^\s+\|/, '')
|
11
|
+
|AWS CloudFormation template for the VPC environment.
|
12
|
+
|For each availability zone stack creates: the public subnet, internet gateway, NAT EC2 instance
|
13
|
+
|internet access from private subnets, routing configuration for corresponding subnets
|
14
|
+
|and security groups.
|
15
|
+
EOS
|
16
|
+
value Description: description
|
17
|
+
|
18
|
+
nat_key_name = gen_ssh_key_name('vpc-nat', region, stack_name)
|
19
|
+
pre_run { create_ssh_key nat_key_name, region, force_create: false }
|
20
|
+
|
21
|
+
parameter_ec2_instance_type 'NAT', type: 'c4.large'
|
22
|
+
|
23
|
+
mapping 'AWSNATAMI',
|
24
|
+
'us-east-1': { AMI: 'ami-68115b02' },
|
25
|
+
'us-west-1': { AMI: 'ami-ef1a718f' },
|
26
|
+
'us-west-2': { AMI: 'ami-77a4b816' },
|
27
|
+
'eu-west-1': { AMI: 'ami-c0993ab3' },
|
28
|
+
'eu-central-1': { AMI: 'ami-0b322e67' },
|
29
|
+
'ap-northeast-1': { AMI: 'ami-f885ae96' },
|
30
|
+
'ap-southeast-1': { AMI: 'ami-e2fc3f81' },
|
31
|
+
'ap-southeast-2': { AMI: 'ami-e3217a80' },
|
32
|
+
'sa-east-1': { AMI: 'ami-8631b5ea' }
|
33
|
+
|
34
|
+
mapping 'AWSRegionNetConfig', Core::NetworkConfig.mapping_vpc_net
|
35
|
+
|
36
|
+
resource 'VPC',
|
37
|
+
Type: 'AWS::EC2::VPC',
|
38
|
+
Properties: {
|
39
|
+
CidrBlock: find_in_map('AWSRegionNetConfig', ref('AWS::Region'), 'VPC'),
|
40
|
+
EnableDnsSupport: 'true',
|
41
|
+
EnableDnsHostnames: 'true',
|
42
|
+
Tags: [
|
43
|
+
{
|
44
|
+
Key: 'Name',
|
45
|
+
Value: aws_stack_name
|
46
|
+
},
|
47
|
+
{
|
48
|
+
Key: 'Application',
|
49
|
+
Value: aws_stack_name
|
50
|
+
},
|
51
|
+
{
|
52
|
+
Key: 'Network',
|
53
|
+
Value: 'Public'
|
54
|
+
}
|
55
|
+
]
|
56
|
+
}
|
57
|
+
|
58
|
+
resource 'InternetGateway',
|
59
|
+
Type: 'AWS::EC2::InternetGateway',
|
60
|
+
Properties: {
|
61
|
+
Tags: [
|
62
|
+
{
|
63
|
+
Key: 'Name',
|
64
|
+
Value: 'Public Gateway'
|
65
|
+
},
|
66
|
+
{
|
67
|
+
Key: 'Application',
|
68
|
+
Value: aws_stack_name
|
69
|
+
},
|
70
|
+
{
|
71
|
+
Key: 'Network',
|
72
|
+
Value: 'Public'
|
73
|
+
}
|
74
|
+
]
|
75
|
+
}
|
76
|
+
|
77
|
+
resource 'GatewayToInternet',
|
78
|
+
DependsOn: %w( VPC InternetGateway ),
|
79
|
+
Type: 'AWS::EC2::VPCGatewayAttachment',
|
80
|
+
Properties: {
|
81
|
+
VpcId: ref('VPC'),
|
82
|
+
InternetGatewayId: ref('InternetGateway')
|
83
|
+
}
|
84
|
+
|
85
|
+
resource 'PublicRouteTable',
|
86
|
+
DependsOn: ['VPC'],
|
87
|
+
Type: 'AWS::EC2::RouteTable',
|
88
|
+
Properties: {
|
89
|
+
VpcId: ref('VPC'),
|
90
|
+
Tags: [
|
91
|
+
{
|
92
|
+
Key: 'Name',
|
93
|
+
Value: 'Public'
|
94
|
+
},
|
95
|
+
{
|
96
|
+
Key: 'Application',
|
97
|
+
Value: aws_stack_name
|
98
|
+
},
|
99
|
+
{
|
100
|
+
Key: 'Network',
|
101
|
+
Value: 'Public'
|
102
|
+
}
|
103
|
+
]
|
104
|
+
}
|
105
|
+
|
106
|
+
resource 'PublicRoute',
|
107
|
+
DependsOn: %w( PublicRouteTable InternetGateway ),
|
108
|
+
Type: 'AWS::EC2::Route',
|
109
|
+
Properties: {
|
110
|
+
RouteTableId: ref('PublicRouteTable'),
|
111
|
+
DestinationCidrBlock: '0.0.0.0/0',
|
112
|
+
GatewayId: ref('InternetGateway')
|
113
|
+
}
|
114
|
+
|
115
|
+
resource 'PublicNetworkAcl',
|
116
|
+
DependsOn: ['VPC'],
|
117
|
+
Type: 'AWS::EC2::NetworkAcl',
|
118
|
+
Properties: {
|
119
|
+
VpcId: ref('VPC'),
|
120
|
+
Tags: [
|
121
|
+
{
|
122
|
+
Key: 'Name',
|
123
|
+
Value: 'Public'
|
124
|
+
},
|
125
|
+
{
|
126
|
+
Key: 'Application',
|
127
|
+
Value: aws_stack_name
|
128
|
+
},
|
129
|
+
{
|
130
|
+
Key: 'Network',
|
131
|
+
Value: 'Public'
|
132
|
+
}
|
133
|
+
]
|
134
|
+
}
|
135
|
+
|
136
|
+
resource 'InboundHTTPPublicNetworkAclEntry',
|
137
|
+
DependsOn: ['PublicNetworkAcl'],
|
138
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
139
|
+
Properties: {
|
140
|
+
NetworkAclId: ref('PublicNetworkAcl'),
|
141
|
+
RuleNumber: '100',
|
142
|
+
Protocol: '-1',
|
143
|
+
RuleAction: 'allow',
|
144
|
+
Egress: 'false',
|
145
|
+
CidrBlock: '0.0.0.0/0',
|
146
|
+
PortRange: { From: '0', To: '65535' }
|
147
|
+
}
|
148
|
+
|
149
|
+
resource 'OutboundHTTPPublicNetworkAclEntry',
|
150
|
+
DependsOn: ['PublicNetworkAcl'],
|
151
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
152
|
+
Properties: {
|
153
|
+
NetworkAclId: ref('PublicNetworkAcl'),
|
154
|
+
RuleNumber: '100',
|
155
|
+
Protocol: '-1',
|
156
|
+
RuleAction: 'allow',
|
157
|
+
Egress: 'true',
|
158
|
+
CidrBlock: '0.0.0.0/0',
|
159
|
+
PortRange: { From: '0', To: '65535' }
|
160
|
+
}
|
161
|
+
|
162
|
+
resource 'PrivateNetworkAcl',
|
163
|
+
DependsOn: ['VPC'],
|
164
|
+
Type: 'AWS::EC2::NetworkAcl',
|
165
|
+
Properties: {
|
166
|
+
VpcId: ref('VPC'),
|
167
|
+
Tags: [
|
168
|
+
{
|
169
|
+
Key: 'Name',
|
170
|
+
Value: 'Private'
|
171
|
+
},
|
172
|
+
{
|
173
|
+
Key: 'Application',
|
174
|
+
Value: aws_stack_name
|
175
|
+
},
|
176
|
+
{
|
177
|
+
Key: 'Network',
|
178
|
+
Value: 'Private'
|
179
|
+
}
|
180
|
+
]
|
181
|
+
}
|
182
|
+
|
183
|
+
resource 'InboundPrivateNetworkAclEntry',
|
184
|
+
DependsOn: ['PrivateNetworkAcl'],
|
185
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
186
|
+
Properties: {
|
187
|
+
NetworkAclId: ref('PrivateNetworkAcl'),
|
188
|
+
RuleNumber: '100',
|
189
|
+
Protocol: '6',
|
190
|
+
RuleAction: 'allow',
|
191
|
+
Egress: 'false',
|
192
|
+
CidrBlock: '0.0.0.0/0',
|
193
|
+
PortRange: { From: '0', To: '65535' }
|
194
|
+
}
|
195
|
+
|
196
|
+
resource 'OutBoundPrivateNetworkAclEntry',
|
197
|
+
DependsOn: ['PrivateNetworkAcl'],
|
198
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
199
|
+
Properties: {
|
200
|
+
NetworkAclId: ref('PrivateNetworkAcl'),
|
201
|
+
RuleNumber: '100',
|
202
|
+
Protocol: '6',
|
203
|
+
RuleAction: 'allow',
|
204
|
+
Egress: 'true',
|
205
|
+
CidrBlock: '0.0.0.0/0',
|
206
|
+
PortRange: { From: '0', To: '65535' }
|
207
|
+
}
|
208
|
+
|
209
|
+
resource 'NATSecurityGroup',
|
210
|
+
DependsOn: ['PrivateSecurityGroup'],
|
211
|
+
Type: 'AWS::EC2::SecurityGroup',
|
212
|
+
Properties: {
|
213
|
+
GroupDescription: 'Enable internal access to the NAT device',
|
214
|
+
VpcId: ref('VPC'),
|
215
|
+
SecurityGroupIngress: [
|
216
|
+
{
|
217
|
+
IpProtocol: 'tcp',
|
218
|
+
FromPort: '22',
|
219
|
+
ToPort: '22',
|
220
|
+
SourceSecurityGroupId: ref('PrivateSecurityGroup')
|
221
|
+
},
|
222
|
+
{
|
223
|
+
IpProtocol: 'tcp',
|
224
|
+
FromPort: '80',
|
225
|
+
ToPort: '80',
|
226
|
+
SourceSecurityGroupId: ref('PrivateSecurityGroup')
|
227
|
+
},
|
228
|
+
{
|
229
|
+
IpProtocol: 'tcp',
|
230
|
+
FromPort: '443',
|
231
|
+
ToPort: '443',
|
232
|
+
SourceSecurityGroupId: ref('PrivateSecurityGroup')
|
233
|
+
},
|
234
|
+
{
|
235
|
+
IpProtocol: 'tcp',
|
236
|
+
FromPort: '465',
|
237
|
+
ToPort: '465',
|
238
|
+
SourceSecurityGroupId: ref('PrivateSecurityGroup')
|
239
|
+
},
|
240
|
+
{
|
241
|
+
IpProtocol: 'icmp',
|
242
|
+
FromPort: '-1',
|
243
|
+
ToPort: '-1',
|
244
|
+
CidrIp: '10.0.0.0/8'
|
245
|
+
}
|
246
|
+
],
|
247
|
+
SecurityGroupEgress: [
|
248
|
+
{
|
249
|
+
IpProtocol: '-1',
|
250
|
+
FromPort: '0',
|
251
|
+
ToPort: '65535',
|
252
|
+
CidrIp: '0.0.0.0/0'
|
253
|
+
}
|
254
|
+
],
|
255
|
+
Tags: [
|
256
|
+
{
|
257
|
+
Key: 'Name',
|
258
|
+
Value: 'NAT'
|
259
|
+
}
|
260
|
+
]
|
261
|
+
}
|
262
|
+
|
263
|
+
resource 'PrivateSecurityGroup',
|
264
|
+
DependsOn: ['VPC'],
|
265
|
+
Type: 'AWS::EC2::SecurityGroup',
|
266
|
+
Properties: {
|
267
|
+
GroupDescription: 'Allow the Application instances to access the NAT device',
|
268
|
+
VpcId: ref('VPC'),
|
269
|
+
SecurityGroupEgress: [
|
270
|
+
{
|
271
|
+
IpProtocol: 'tcp',
|
272
|
+
FromPort: '0',
|
273
|
+
ToPort: '65535',
|
274
|
+
CidrIp: '10.0.0.0/8'
|
275
|
+
}
|
276
|
+
],
|
277
|
+
SecurityGroupIngress: [
|
278
|
+
{
|
279
|
+
IpProtocol: 'tcp',
|
280
|
+
FromPort: '0',
|
281
|
+
ToPort: '65535',
|
282
|
+
CidrIp: '10.0.0.0/8'
|
283
|
+
}
|
284
|
+
],
|
285
|
+
Tags: [
|
286
|
+
{
|
287
|
+
Key: 'Name',
|
288
|
+
Value: 'Private'
|
289
|
+
}
|
290
|
+
]
|
291
|
+
}
|
292
|
+
|
293
|
+
current_cidr_block = Core::NetworkConfig.mapping_vpc_net[region.to_sym][:VPC]
|
294
|
+
public_cidr_blocks =
|
295
|
+
IPAddress(current_cidr_block).subnet(SUBNET_CIDR_BLOCK_SIZE).map(&:to_string).first(availability_zones.size)
|
296
|
+
|
297
|
+
availability_zones.zip(public_cidr_blocks).each do |pair, cidr_block|
|
298
|
+
suffix = pair.first
|
299
|
+
public_subnet_name = "PublicSubnet#{suffix.upcase}"
|
300
|
+
resource public_subnet_name,
|
301
|
+
DependsOn: ['VPC'],
|
302
|
+
Type: 'AWS::EC2::Subnet',
|
303
|
+
Properties: {
|
304
|
+
VpcId: ref('VPC'),
|
305
|
+
AvailabilityZone: join('', ref('AWS::Region'), suffix.to_s),
|
306
|
+
CidrBlock: cidr_block,
|
307
|
+
Tags: [
|
308
|
+
{
|
309
|
+
Key: 'Name',
|
310
|
+
Value: "Public #{suffix.upcase}"
|
311
|
+
},
|
312
|
+
{
|
313
|
+
Key: 'Application',
|
314
|
+
Value: aws_stack_name
|
315
|
+
},
|
316
|
+
{
|
317
|
+
Key: 'Network',
|
318
|
+
Value: 'Public'
|
319
|
+
}
|
320
|
+
]
|
321
|
+
}
|
322
|
+
|
323
|
+
resource "PublicSubnetRouteTableAssociation#{suffix.upcase}",
|
324
|
+
DependsOn: [public_subnet_name, 'PublicRouteTable'],
|
325
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
326
|
+
Properties: {
|
327
|
+
SubnetId: ref(public_subnet_name),
|
328
|
+
RouteTableId: ref('PublicRouteTable')
|
329
|
+
}
|
330
|
+
|
331
|
+
nat_device_name = "NATDevice#{suffix.upcase}"
|
332
|
+
resource nat_device_name,
|
333
|
+
DependsOn: [public_subnet_name, 'NATSecurityGroup'],
|
334
|
+
Type: 'AWS::EC2::Instance',
|
335
|
+
Properties: {
|
336
|
+
InstanceType: ref('NATInstanceType'),
|
337
|
+
KeyName: nat_key_name,
|
338
|
+
SourceDestCheck: 'false',
|
339
|
+
ImageId: find_in_map('AWSNATAMI', ref('AWS::Region'), 'AMI'),
|
340
|
+
NetworkInterfaces: [
|
341
|
+
{
|
342
|
+
AssociatePublicIpAddress: 'true',
|
343
|
+
DeviceIndex: '0',
|
344
|
+
SubnetId: ref(public_subnet_name),
|
345
|
+
GroupSet: [ref('NATSecurityGroup')]
|
346
|
+
}
|
347
|
+
],
|
348
|
+
Tags: [
|
349
|
+
{
|
350
|
+
Key: 'Name',
|
351
|
+
Value: nat_device_name
|
352
|
+
}
|
353
|
+
]
|
354
|
+
}
|
355
|
+
|
356
|
+
private_route_table_name = "PrivateRouteTable#{suffix.upcase}"
|
357
|
+
resource private_route_table_name,
|
358
|
+
DependsOn: ['VPC'],
|
359
|
+
Type: 'AWS::EC2::RouteTable',
|
360
|
+
Properties: {
|
361
|
+
VpcId: ref('VPC'),
|
362
|
+
Tags: [
|
363
|
+
{
|
364
|
+
Key: 'Name',
|
365
|
+
Value: "Private #{suffix.upcase}"
|
366
|
+
},
|
367
|
+
{
|
368
|
+
Key: 'Application',
|
369
|
+
Value: aws_stack_name
|
370
|
+
},
|
371
|
+
{
|
372
|
+
Key: 'Network',
|
373
|
+
Value: 'Private'
|
374
|
+
}
|
375
|
+
]
|
376
|
+
}
|
377
|
+
|
378
|
+
resource "PrivateRoute#{suffix.upcase}",
|
379
|
+
DependsOn: [private_route_table_name, nat_device_name],
|
380
|
+
Type: 'AWS::EC2::Route',
|
381
|
+
Properties: {
|
382
|
+
RouteTableId: ref(private_route_table_name),
|
383
|
+
DestinationCidrBlock: '0.0.0.0/0',
|
384
|
+
InstanceId: ref(nat_device_name)
|
385
|
+
}
|
386
|
+
|
387
|
+
output public_subnet_name,
|
388
|
+
Description: "Created Subnet #{suffix.upcase}",
|
389
|
+
Value: ref(public_subnet_name)
|
390
|
+
end
|
391
|
+
|
392
|
+
output 'VpcId',
|
393
|
+
Description: 'Created VPC',
|
394
|
+
Value: ref('VPC')
|
395
|
+
|
396
|
+
output 'PrivateSecurityGroup',
|
397
|
+
Description: 'SecurityGroup to add private resources',
|
398
|
+
Value: ref('PrivateSecurityGroup')
|
399
|
+
end # def tpl
|
400
|
+
end # class VPC
|
401
|
+
end # module Templates
|
402
|
+
end # module Enscalator
|
data/lib/enscalator.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'ipaddr'
|
3
|
+
require 'ipaddress'
|
4
|
+
require 'digest'
|
5
|
+
require 'aws-sdk'
|
6
|
+
require 'active_support'
|
7
|
+
require 'active_support/core_ext'
|
8
|
+
require 'active_support/inflector'
|
9
|
+
require 'active_support/inflector/inflections'
|
10
|
+
require 'enscalator/version'
|
11
|
+
require 'enscalator/helpers'
|
12
|
+
require 'enscalator/core'
|
13
|
+
require 'enscalator/plugins'
|
14
|
+
require 'enscalator/rich_template_dsl'
|
15
|
+
require 'enscalator/vpc_with_nat_gateway'
|
16
|
+
require 'enscalator/vpc_with_nat_instance'
|
17
|
+
require 'enscalator/vpc'
|
18
|
+
require 'enscalator/enapp'
|
19
|
+
require 'enscalator/templates'
|
20
|
+
|
21
|
+
# Namespace for Enscalator related code
|
22
|
+
module Enscalator
|
23
|
+
# Main method to actually run Enscalator
|
24
|
+
# @param [Array] argv list of command-line arguments
|
25
|
+
def self.run!(argv)
|
26
|
+
argv_dup = argv.dup
|
27
|
+
display_name = name.downcase
|
28
|
+
parser = Trollop::Parser.new do
|
29
|
+
banner "Usage: #{display_name} [arguments]"
|
30
|
+
|
31
|
+
opt :list_templates, 'List all available templates', default: false, short: 'l'
|
32
|
+
opt :template, 'Template name', type: String, short: 't'
|
33
|
+
opt :template_file, 'Template filename', type: String, short: 'f'
|
34
|
+
opt :region, 'AWS Region', type: String, default: 'us-east-1', short: 'r'
|
35
|
+
opt :parameters, "Parameters 'Key1=Value1;Key2=Value2'", type: String, short: 'p'
|
36
|
+
opt :stack_name, 'Stack name', type: String, short: 's'
|
37
|
+
opt :private_hosted_zone, "Private hosted zone (e.x. 'default-vpc.internal')", type: String, short: 'z'
|
38
|
+
opt :public_hosted_zone, 'Public hosted zone', type: String, short: 'g'
|
39
|
+
opt :create_stack, 'Create the stack', default: false, short: 'c'
|
40
|
+
opt :update_stack, 'Update already deployed stack', default: false, short: 'u'
|
41
|
+
opt :pre_run, 'Use pre-run hooks', default: true, short: 'e'
|
42
|
+
opt :post_run, 'Use post-run hooks', default: true, short: 'o'
|
43
|
+
opt :expand, 'Print generated JSON template', default: false, short: 'x'
|
44
|
+
opt :capabilities, 'AWS capabilities', default: 'CAPABILITY_IAM', short: 'a'
|
45
|
+
opt :vpc_stack_name, 'VPC stack name', default: 'default-vpc', short: 'n'
|
46
|
+
opt :availability_zone, 'Deploy to specific availability zone', default: 'all', short: 'd'
|
47
|
+
opt :profile, 'Use a specific profile from your credential file', type: String, default: nil
|
48
|
+
|
49
|
+
conflicts :list_templates, :create_stack, :update_stack, :expand
|
50
|
+
end
|
51
|
+
|
52
|
+
opts = Trollop.with_standard_exception_handling(parser) do
|
53
|
+
fail Trollop::HelpNeeded if argv.empty?
|
54
|
+
parser.parse argv
|
55
|
+
end
|
56
|
+
|
57
|
+
if opts[:availability_zone_given]
|
58
|
+
valid_values = ('a'..'e').to_a << 'all'
|
59
|
+
unless valid_values.include? opts[:availability_zone]
|
60
|
+
STDERR.puts %(Availability zone can be only one off "#{valid_values.join(',')}")
|
61
|
+
exit
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# fallback to create_stack action when no action was given
|
66
|
+
if !opts[:create_stack] && !opts[:update_stack]
|
67
|
+
opts[:create_stack] = true
|
68
|
+
end
|
69
|
+
|
70
|
+
# load template from given file and update template list
|
71
|
+
if opts[:template_file]
|
72
|
+
unless File.exist?(opts[:template_file])
|
73
|
+
abort(format('Unable to find file "%s"', opts[:template_file]))
|
74
|
+
end
|
75
|
+
load(opts[:template_file])
|
76
|
+
unless Enscalator::Templates.all_valid?
|
77
|
+
STDERR.puts 'Some templates missing required tpl method:'
|
78
|
+
Enscalator::Templates.all.select { |a| !a.instance_methods.include?(:tpl) }.each do |tpl|
|
79
|
+
STDERR.puts tpl.name.demodulize
|
80
|
+
end
|
81
|
+
exit
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
templates = Enscalator::Templates.constants.map(&:to_s)
|
86
|
+
|
87
|
+
if opts[:list_templates]
|
88
|
+
STDERR.puts 'Available templates:'
|
89
|
+
STDERR.puts templates.sort
|
90
|
+
exit
|
91
|
+
end
|
92
|
+
|
93
|
+
if opts[:template] && templates.include?(opts[:template])
|
94
|
+
# for stack_name use template name as a base and convert it from camelcase to underscore case
|
95
|
+
opts[:stack_name] ||= opts[:template].underscore.gsub(/[_]/, '-')
|
96
|
+
Object.const_get("Enscalator::Templates::#{opts[:template]}").new(opts.merge(ARGV: argv_dup)).exec!
|
97
|
+
elsif opts[:template_given] && !opts[:template].empty?
|
98
|
+
STDERR.puts %(Template "#{opts[:template]}" doesn't exist)
|
99
|
+
else
|
100
|
+
STDERR.puts 'Template name cannot be an empty string'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|