enscalator 0.4.0.pre.alpha.pre.16
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.
- 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
|