stacco 0.1.7 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -309,11 +309,13 @@
309
309
  "Timeout": "5",
310
310
  "UnhealthyThreshold": "2"
311
311
  },
312
+
312
313
  "Listeners": [{
313
314
  "LoadBalancerPort": "443",
314
315
  "InstancePort": "80",
315
316
  "Protocol": "SSL",
316
317
  "InstanceProtocol": "TCP",
318
+
317
319
  "SSLCertificateId": {"Fn::Join": ["", [
318
320
  "arn:aws:iam::", {"Ref": "AWS::AccountId"}, ":server-certificate/",
319
321
  <%= j frontend_cert_path %>, ".pem"
@@ -423,6 +425,7 @@
423
425
  "InstancePort": "80",
424
426
  "Protocol": "SSL",
425
427
  "InstanceProtocol": "TCP",
428
+
426
429
  "SSLCertificateId": {"Fn::Join": ["", [
427
430
  "arn:aws:iam::", {"Ref": "AWS::AccountId"}, ":server-certificate/",
428
431
  <%= j backend_cert_path %>, ".pem"
@@ -0,0 +1,551 @@
1
+ <%
2
+ ubuntu_daily_ami = "ami-6ac2a85a"
3
+ docker_library_snapshot = "snap-d37e4721"
4
+ %>
5
+
6
+ {
7
+ "AWSTemplateFormatVersion": "2010-09-09",
8
+ "Description": <%= j @stack.description %>,
9
+
10
+ "Resources": {
11
+
12
+ "VPC": {"Type": "AWS::EC2::VPC", "Properties": {
13
+ "CidrBlock": "10.100.0.0/16",
14
+ "InstanceTenancy": "default",
15
+ "EnableDnsSupport": true,
16
+ "EnableDnsHostnames": true
17
+ }},
18
+
19
+ "InternetGateway": {"Type": "AWS::EC2::InternetGateway", "Properties": {
20
+ }},
21
+
22
+ "InternetGatewayAttachment": {"Type": "AWS::EC2::VPCGatewayAttachment", "Properties": {
23
+ "VpcId": {"Ref": "VPC"},
24
+ "InternetGatewayId": {"Ref": "InternetGateway"}
25
+ }},
26
+
27
+ "NetworkAcl": {"Type": "AWS::EC2::NetworkAcl", "Properties": {
28
+ "VpcId": {"Ref": "VPC"}
29
+ }},
30
+
31
+ "PublicSubnet": {"Type": "AWS::EC2::Subnet", "Properties": {
32
+ "VpcId": {"Ref": "VPC"},
33
+ "CidrBlock": "10.100.0.0/24"
34
+ }},
35
+ "PublicSubnetAcl": {"Type": "AWS::EC2::SubnetNetworkAclAssociation", "Properties": {
36
+ "NetworkAclId": {"Ref": "NetworkAcl"},
37
+ "SubnetId": {"Ref": "PublicSubnet"}
38
+ }},
39
+ "PublicRouteTable": {"Type": "AWS::EC2::RouteTable", "Properties": {
40
+ "VpcId": {"Ref": "VPC"}
41
+ }},
42
+ "PublicSubnetRoute": {"Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": {
43
+ "SubnetId": {"Ref": "PublicSubnet"},
44
+ "RouteTableId": {"Ref": "PublicRouteTable"}
45
+ }},
46
+ "PublicSubnetGatewayRoute": {"Type": "AWS::EC2::Route", "DependsOn": "InternetGatewayAttachment", "Properties": {
47
+ "DestinationCidrBlock": "0.0.0.0/0",
48
+ "RouteTableId": {"Ref": "PublicRouteTable"},
49
+ "GatewayId": {"Ref": "InternetGateway"}
50
+ }},
51
+ "PublicIngressAcl": {"Type": "AWS::EC2::NetworkAclEntry", "Properties": {
52
+ "NetworkAclId": {"Ref": "NetworkAcl"},
53
+ "RuleNumber": "100",
54
+
55
+ "CidrBlock": "0.0.0.0/0",
56
+ "Protocol": "-1",
57
+ "RuleAction": "allow"
58
+ }},
59
+ "PublicEgressAcl": {"Type": "AWS::EC2::NetworkAclEntry", "Properties": {
60
+ "NetworkAclId": {"Ref": "NetworkAcl"},
61
+ "RuleNumber": "100",
62
+
63
+ "Egress": true,
64
+ "CidrBlock": "0.0.0.0/0",
65
+ "Protocol": "-1",
66
+ "RuleAction": "allow"
67
+ }},
68
+
69
+ "PrivateSubnet": {"Type": "AWS::EC2::Subnet", "Properties": {
70
+ "VpcId": {"Ref": "VPC"},
71
+ "AvailabilityZone": {"Fn::GetAtt": ["PublicSubnet", "AvailabilityZone"]},
72
+ "CidrBlock": "10.100.1.0/24"
73
+ }},
74
+ "PrivateSubnetAcl": {"Type": "AWS::EC2::SubnetNetworkAclAssociation", "Properties": {
75
+ "NetworkAclId": {"Ref": "NetworkAcl"},
76
+ "SubnetId": {"Ref": "PrivateSubnet"}
77
+ }},
78
+ "PrivateRouteTable": {"Type": "AWS::EC2::RouteTable", "Properties": {
79
+ "VpcId": {"Ref": "VPC"}
80
+ }},
81
+ "PrivateSubnetRoute": {"Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": {
82
+ "SubnetId": {"Ref": "PrivateSubnet"},
83
+ "RouteTableId": {"Ref": "PrivateRouteTable"}
84
+ }},
85
+ "PrivateSubnetGatewayRoute": {"Type": "AWS::EC2::Route", "DependsOn": "InternetGatewayAttachment", "Properties": {
86
+ "DestinationCidrBlock": "0.0.0.0/0",
87
+ "RouteTableId": {"Ref": "PrivateRouteTable"},
88
+ "GatewayId": {"Ref": "InternetGateway"}
89
+ }},
90
+
91
+ "DHCPOptions": {"Type": "AWS::EC2::DHCPOptions", "Properties": {
92
+ "DomainName": <%= j domain %>,
93
+ "DomainNameServers": ["AmazonProvidedDNS"]
94
+ }},
95
+ "VPCDHCPOptionsAssociation": {"Type": "AWS::EC2::VPCDHCPOptionsAssociation", "Properties": {
96
+ "VpcId": {"Ref": "VPC"},
97
+ "DhcpOptionsId": {"Ref": "DHCPOptions"}
98
+ }},
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+ "AppS3Bucket": {"Type": "AWS::S3::Bucket", "Properties": {
107
+ "BucketName": <%= j domain %>,
108
+ "AccessControl": "PublicRead",
109
+ "WebsiteConfiguration": {
110
+ "IndexDocument": "index.html",
111
+ "ErrorDocument": "404.html"
112
+ }
113
+ }},
114
+
115
+ "AppS3BucketDistribution": {"Type": "AWS::CloudFront::Distribution", "Properties": {
116
+ "DistributionConfig": {
117
+ "Aliases": [<%= j domain %>],
118
+ "Enabled": "true",
119
+
120
+ "Origins": [{
121
+ "Id": "AppS3BucketOrigin",
122
+ "DomainName": {"Fn::Join": ["", [<%= j domain %>, ".s3-website-", {"Ref": "AWS::Region"}, ".amazonaws.com"]]},
123
+
124
+ "CustomOriginConfig": {
125
+ "HTTPPort": "80",
126
+ "HTTPSPort": "443",
127
+ "OriginProtocolPolicy": "http-only"
128
+ }
129
+ }],
130
+
131
+ "DefaultCacheBehavior": {
132
+ "TargetOriginId": "AppS3BucketOrigin",
133
+ "ForwardedValues": {"QueryString": "false"},
134
+ "ViewerProtocolPolicy": "redirect-to-https"
135
+ }
136
+ }
137
+ }},
138
+
139
+ "AppS3BucketDNSRecord": {"Type": "AWS::Route53::RecordSet", "Properties": {
140
+ "HostedZoneId": <%= j hosted_zone %>,
141
+ "Type": "A",
142
+ "Name": <%= j "#{domain}." %>,
143
+ "AliasTarget": {
144
+ "HostedZoneId": <%= j @config['cloudfront']['hosted_zone'] %>,
145
+ "DNSName": {"Fn::GetAtt": ["AppS3BucketDistribution", "DomainName"]}
146
+ }
147
+ }},
148
+
149
+ "WwwS3Bucket": {"Type": "AWS::S3::Bucket", "Properties": {
150
+ "BucketName": <%= j "www.#{domain}" %>,
151
+ "AccessControl": "PublicRead",
152
+ "WebsiteConfiguration": {
153
+ "RedirectAllRequestsTo": {
154
+ "HostName": <%= j domain %>,
155
+ "Protocol": "https"
156
+ }
157
+ }
158
+ }},
159
+
160
+ "WwwS3BucketDistribution": {"Type": "AWS::CloudFront::Distribution", "Properties": {
161
+ "DistributionConfig": {
162
+ "Aliases": [<%= j "www.#{domain}" %>],
163
+ "Enabled": "true",
164
+
165
+ "Origins": [{
166
+ "Id": "WwwS3BucketOrigin",
167
+ "DomainName": {"Fn::Join": ["", [<%= j "www.#{domain}" %>, ".s3-website-", {"Ref": "AWS::Region"}, ".amazonaws.com"]]},
168
+
169
+ "CustomOriginConfig": {
170
+ "HTTPPort": "80",
171
+ "HTTPSPort": "443",
172
+ "OriginProtocolPolicy": "http-only"
173
+ }
174
+ }],
175
+
176
+ "DefaultCacheBehavior": {
177
+ "TargetOriginId": "WwwS3BucketOrigin",
178
+ "ForwardedValues": {"QueryString": "false"},
179
+ "ViewerProtocolPolicy": "redirect-to-https"
180
+ }
181
+ }
182
+ }},
183
+
184
+ "WwwS3BucketDNSRecord": {"Type": "AWS::Route53::RecordSet", "Properties": {
185
+ "HostedZoneId": <%= j hosted_zone %>,
186
+ "Type": "CNAME", "TTL": "300",
187
+ "Name": <%= j "www.#{domain}." %>,
188
+ "ResourceRecords": [{"Fn::GetAtt": ["WwwS3BucketDistribution", "DomainName"]}]
189
+ }},
190
+
191
+
192
+ "AdminS3Bucket": {"Type": "AWS::S3::Bucket", "Properties": {
193
+ "BucketName": <%= j "admin.#{domain}" %>,
194
+ "AccessControl": "PublicRead",
195
+ "WebsiteConfiguration": {
196
+ "IndexDocument": "index.html",
197
+ "ErrorDocument": "404.html"
198
+ }
199
+ }},
200
+
201
+ "AdminS3BucketDistribution": {"Type": "AWS::CloudFront::Distribution", "Properties": {
202
+ "DistributionConfig": {
203
+ "Aliases": [<%= j "admin.#{domain}" %>],
204
+ "Enabled": "true",
205
+
206
+ "Origins": [{
207
+ "Id": "AdminS3BucketOrigin",
208
+ "DomainName": {"Fn::Join": ["", [<%= j "admin.#{domain}" %>, ".s3-website-", {"Ref": "AWS::Region"}, ".amazonaws.com"]]},
209
+
210
+ "CustomOriginConfig": {
211
+ "HTTPPort": "80",
212
+ "HTTPSPort": "443",
213
+ "OriginProtocolPolicy": "http-only"
214
+ }
215
+ }],
216
+
217
+ "DefaultCacheBehavior": {
218
+ "TargetOriginId": "AdminS3BucketOrigin",
219
+ "ForwardedValues": {"QueryString": "false"},
220
+ "ViewerProtocolPolicy": "redirect-to-https"
221
+ }
222
+ }
223
+ }},
224
+
225
+ "AdminS3BucketDNSRecord": {"Type": "AWS::Route53::RecordSet", "Properties": {
226
+ "HostedZoneId": <%= j hosted_zone %>,
227
+ "Type": "CNAME", "TTL": "300",
228
+ "Name": <%= j "admin.#{domain}." %>,
229
+ "ResourceRecords": [{"Fn::GetAtt": ["AdminS3BucketDistribution", "DomainName"]}]
230
+ }},
231
+
232
+
233
+
234
+
235
+ "InstanceBootstrapWaitHandle": {"Type": "AWS::CloudFormation::WaitConditionHandle", "Properties": {}},
236
+ "InstanceBootstrap": {"Type": "AWS::CloudFormation::WaitCondition", "DependsOn": ["Frontend", "Backend", "OpenVPN"], "Properties": {
237
+ "Handle": {"Ref": "InstanceBootstrapWaitHandle"},
238
+ "Count": "3",
239
+ "Timeout": "6000"
240
+ }},
241
+
242
+
243
+
244
+ "Frontend": {"Type": "AWS::EC2::Instance", "Properties": {
245
+ "InstanceType": "m1.small",
246
+ "ImageId": <%= j ubuntu_daily_ami %>,
247
+
248
+ "Tags": [
249
+ { "Key": "Name", "Value": "web01" },
250
+ { "Key": "Environment", "Value": <%= j environment %> }
251
+ ],
252
+
253
+ "KeyName": <%= j @stack.iam_keypair_name %>,
254
+
255
+ "BlockDeviceMappings": [
256
+ {"DeviceName": "/dev/xvdc", "Ebs": {
257
+ "SnapshotId": <%= j docker_library_snapshot %>,
258
+ "VolumeSize": "50"
259
+ }}
260
+ ],
261
+
262
+ "NetworkInterfaces": [{
263
+ "Description": "Primary network interface",
264
+ "DeviceIndex": 0,
265
+ "DeleteOnTermination": true,
266
+
267
+ "SubnetId": {"Ref": "PublicSubnet"},
268
+ "GroupSet": [{"Ref": "FrontendSecurityGroup"}]
269
+ }],
270
+
271
+ "UserData": {"Fn::Base64": {"Fn::Join": ["", [
272
+ "#!/bin/bash -e\n",
273
+ "export AWS_WAIT_HANDLE='", {"Ref": "InstanceBootstrapWaitHandle"}, "'\n",
274
+ "export BACKEND_HOST='", {"Fn::GetAtt": ["Backend", "PrivateDnsName"]}, "'\n",
275
+ <%= ja 8, userdata['frontend'] %>
276
+ ]]}}
277
+ }},
278
+
279
+ "FrontendSecurityGroup": {"Type": "AWS::EC2::SecurityGroup", "Properties": {
280
+ "GroupDescription": "Enable SSH access via port 22 and HTTP via 80",
281
+ "VpcId": {"Ref": "VPC"},
282
+
283
+ "SecurityGroupIngress": [
284
+ {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": <%= j external_ssh_cidr %>},
285
+ {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": <%= j bastion_ssh_cidr %>},
286
+ {"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "10.100.0.0/24"}
287
+ ],
288
+ "SecurityGroupEgress": [{"IpProtocol": "-1", "CidrIp": "0.0.0.0/0"}]
289
+ }},
290
+
291
+ "FrontendEIP": {"Type": "AWS::EC2::EIP", "Properties": {
292
+ "Domain": "VPC"
293
+ }},
294
+
295
+ "FrontendEIPAssociation": {"Type": "AWS::EC2::EIPAssociation", "Properties": {
296
+ "AllocationId": {"Fn::GetAtt": ["FrontendEIP", "AllocationId"]},
297
+ "InstanceId": {"Ref": "Frontend"}
298
+ }},
299
+
300
+ "FrontendEndpoint": {"Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Properties": {
301
+ "Instances": [{"Ref": "Frontend"}],
302
+ "Subnets": [{"Ref": "PublicSubnet"}],
303
+ "SecurityGroups": [{"Ref": "FrontendEndpointSecurityGroup"}],
304
+
305
+ "HealthCheck": {
306
+ "HealthyThreshold": "5",
307
+ "Interval": "30",
308
+ "Target": "HTTP:80/v1/info",
309
+ "Timeout": "5",
310
+ "UnhealthyThreshold": "2"
311
+ },
312
+
313
+ "Listeners": [{
314
+ "LoadBalancerPort": "443",
315
+ "InstancePort": "80",
316
+ "Protocol": "SSL",
317
+ "InstanceProtocol": "TCP",
318
+
319
+ "SSLCertificateId": {"Fn::Join": ["", [
320
+ "arn:aws:iam::", {"Ref": "AWS::AccountId"}, ":server-certificate/",
321
+ <%= j frontend_cert_path %>, ".pem"
322
+ ]]}
323
+ }],
324
+
325
+ "Policies": [{
326
+ "PolicyName": "EnableProxyProtocol",
327
+ "PolicyType": "ProxyProtocolPolicyType",
328
+ "Attributes": [{"Name": "ProxyProtocol", "Value": "true"}],
329
+ "InstancePorts": ["80"]
330
+ }]
331
+ }},
332
+
333
+ "FrontendEndpointDNSRecord": {"Type": "AWS::Route53::RecordSet", "Properties": {
334
+ "HostedZoneId": <%= j hosted_zone %>,
335
+ "Type": "CNAME", "TTL": "300",
336
+ "Name": <%= j "api.#{domain}." %>,
337
+ "ResourceRecords": [{"Fn::GetAtt": ["FrontendEndpoint", "DNSName"]}]
338
+ }},
339
+
340
+ "FrontendEndpointSecurityGroup": {"Type": "AWS::EC2::SecurityGroup", "Properties": {
341
+ "GroupDescription": "Frontend ELB security group",
342
+ "VpcId": {"Ref": "VPC"},
343
+
344
+ "SecurityGroupIngress": [
345
+ {"IpProtocol": "tcp", "FromPort": "443", "ToPort": "443", "CidrIp": "0.0.0.0/0"}
346
+ ],
347
+ "SecurityGroupEgress": [
348
+ {"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "0.0.0.0/0"}
349
+ ]
350
+ }},
351
+
352
+
353
+
354
+
355
+ "Backend": {"Type": "AWS::EC2::Instance", "Properties": {
356
+ "InstanceType": "m3.medium",
357
+ "ImageId": <%= j ubuntu_daily_ami %>,
358
+
359
+ "Tags": [
360
+ { "Key": "Name", "Value": "app01" },
361
+ { "Key": "Environment", "Value": <%= j environment %> }
362
+ ],
363
+
364
+ "KeyName": <%= j @stack.iam_keypair_name %>,
365
+
366
+ "BlockDeviceMappings": [
367
+ {"DeviceName": "/dev/xvdc", "Ebs": {
368
+ "SnapshotId": <%= j docker_library_snapshot %>,
369
+ "VolumeSize": "50"
370
+ }},
371
+
372
+ {"DeviceName": "/dev/xvdd", "Ebs": {
373
+ "VolumeSize": "300"
374
+ }}
375
+ ],
376
+
377
+ "NetworkInterfaces": [{
378
+ "Description": "Primary network interface",
379
+ "DeviceIndex": 0,
380
+ "DeleteOnTermination": true,
381
+
382
+ "SubnetId": {"Ref": "PrivateSubnet"},
383
+ "GroupSet": [{"Ref": "BackendSecurityGroup"}]
384
+ }],
385
+
386
+ "UserData": {"Fn::Base64": {"Fn::Join": ["", [
387
+ "#!/bin/bash -e\n",
388
+ "export AWS_WAIT_HANDLE='", {"Ref": "InstanceBootstrapWaitHandle"}, "'\n",
389
+ <%= ja 8, userdata['backend'] %>
390
+ ]]}}
391
+ }},
392
+
393
+ "BackendSecurityGroup": {"Type": "AWS::EC2::SecurityGroup", "Properties": {
394
+ "GroupDescription": "Enable SSH access via port 22",
395
+ "VpcId": {"Ref": "VPC"},
396
+
397
+ "SecurityGroupIngress": [
398
+ {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": <%= j external_ssh_cidr %>},
399
+ {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": <%= j bastion_ssh_cidr %>},
400
+ {"IpProtocol": "tcp", "FromPort": "51607", "ToPort": "51607", "CidrIp": "10.100.0.0/24"}
401
+ ],
402
+ "SecurityGroupEgress": [
403
+ {"IpProtocol": "-1", "CidrIp": "0.0.0.0/0"}
404
+ ]
405
+ }
406
+ },
407
+
408
+ "BackendEIP": {"Type": "AWS::EC2::EIP", "Properties": {
409
+ "Domain": "VPC"
410
+ }},
411
+ "BackendEIPAssociation": {"Type": "AWS::EC2::EIPAssociation", "Properties": {
412
+ "AllocationId": {"Fn::GetAtt": ["BackendEIP", "AllocationId"]},
413
+ "InstanceId": {"Ref": "Backend"}
414
+ }},
415
+
416
+ "BackendEndpoint": {"Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Properties": {
417
+ "Instances": [{"Ref": "Backend"}],
418
+ "Subnets": [{"Ref": "PrivateSubnet"}],
419
+ "SecurityGroups": [{"Ref": "BackendEndpointSecurityGroup"}],
420
+ "Scheme": "internal",
421
+
422
+ "HealthCheck": {
423
+ "HealthyThreshold": "5",
424
+ "Interval": "30",
425
+ "Target": "HTTP:80/v1/info",
426
+ "Timeout": "5",
427
+ "UnhealthyThreshold": "2"
428
+ },
429
+
430
+ "Listeners": [{
431
+ "LoadBalancerPort": "443",
432
+ "InstancePort": "80",
433
+ "Protocol": "SSL",
434
+ "InstanceProtocol": "TCP",
435
+
436
+ "SSLCertificateId": {"Fn::Join": ["", [
437
+ "arn:aws:iam::", {"Ref": "AWS::AccountId"}, ":server-certificate/",
438
+ <%= j backend_cert_path %>, ".pem"
439
+ ]]}
440
+ }],
441
+
442
+ "Policies": [{
443
+ "PolicyName": "EnableProxyProtocol",
444
+ "PolicyType": "ProxyProtocolPolicyType",
445
+ "Attributes": [{"Name": "ProxyProtocol", "Value": "true"}],
446
+ "InstancePorts": ["80"]
447
+ }]
448
+ }},
449
+
450
+ "BackendEndpointDNSRecord": {"Type": "AWS::Route53::RecordSet", "Properties": {
451
+ "HostedZoneId": <%= j hosted_zone %>,
452
+ "Type": "CNAME", "TTL": "300",
453
+ "Name": <%= j "api.admin.#{domain}." %>,
454
+ "ResourceRecords": [{"Fn::GetAtt": ["BackendEndpoint", "DNSName"]}]
455
+ }},
456
+
457
+ "BackendEndpointSecurityGroup": {"Type": "AWS::EC2::SecurityGroup", "Properties": {
458
+ "GroupDescription": "Backend ELB security group",
459
+ "VpcId": {"Ref": "VPC"},
460
+
461
+ "SecurityGroupIngress": [
462
+ {"IpProtocol": "tcp", "FromPort": "443", "ToPort": "443", "CidrIp": "10.100.0.0/24"}
463
+ ],
464
+ "SecurityGroupEgress": [
465
+ {"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "0.0.0.0/0"}
466
+ ]
467
+ }},
468
+
469
+ "BackendIngress": {"Type": "AWS::EC2::SecurityGroupIngress", "Properties": {
470
+ "GroupId": {"Ref": "BackendSecurityGroup"},
471
+ "SourceSecurityGroupId": {"Ref": "BackendEndpointSecurityGroup"},
472
+
473
+ "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80"
474
+ }},
475
+
476
+
477
+
478
+
479
+
480
+
481
+ "OpenVPN": {"Type": "AWS::EC2::Instance", "Properties": {
482
+ "InstanceType": "m1.small",
483
+ "ImageId": <%= j ubuntu_daily_ami %>,
484
+ "AvailabilityZone": {"Fn::GetAtt": ["PublicSubnet", "AvailabilityZone"]},
485
+
486
+ "Tags": [
487
+ { "Key": "Name", "Value": "vpn01" },
488
+ { "Key": "Environment", "Value": <%= j environment %> }
489
+ ],
490
+
491
+ "KeyName": <%= j @stack.iam_keypair_name %>,
492
+
493
+ "NetworkInterfaces": [
494
+ {
495
+ "NetworkInterfaceId": {"Ref": "OpenVPNPublicInterface"},
496
+ "DeviceIndex": "0"
497
+ },
498
+ {
499
+ "Description": "Private network interface",
500
+ "DeviceIndex": "1",
501
+ "DeleteOnTermination": true,
502
+
503
+ "SubnetId": {"Ref": "PrivateSubnet"},
504
+ "GroupSet": [{"Ref": "OpenVPNSecurityGroup"}]
505
+ }
506
+ ],
507
+
508
+ "UserData": {"Fn::Base64": {"Fn::Join": ["", [
509
+ "#!/bin/bash -e\n",
510
+ "export AWS_WAIT_HANDLE='", {"Ref": "InstanceBootstrapWaitHandle"}, "'\n",
511
+ <%= ja 8, userdata['openvpn'] %>
512
+ ]]}}
513
+ }},
514
+
515
+ "OpenVPNPublicInterface": {"Type": "AWS::EC2::NetworkInterface", "Properties": {
516
+ "Description": "Public network interface",
517
+
518
+ "SubnetId": {"Ref": "PublicSubnet"},
519
+ "GroupSet": [{"Ref": "OpenVPNSecurityGroup"}]
520
+ }},
521
+
522
+ "OpenVPNEIP": {"Type": "AWS::EC2::EIP", "Properties": {
523
+ "Domain": "VPC"
524
+ }},
525
+
526
+ "OpenVPNEIPAssociation": {"Type": "AWS::EC2::EIPAssociation", "Properties": {
527
+ "AllocationId": {"Fn::GetAtt": ["OpenVPNEIP", "AllocationId"]},
528
+ "NetworkInterfaceId": {"Ref": "OpenVPNPublicInterface"}
529
+ }},
530
+
531
+ "OpenVPNDNSRecord": {"Type": "AWS::Route53::RecordSet", "DependsOn": "OpenVPNEIPAssociation", "Properties": {
532
+ "HostedZoneId": <%= j hosted_zone %>,
533
+ "Type": "CNAME", "TTL": "300",
534
+ "Name": <%= j "vpn.#{domain}." %>,
535
+ "ResourceRecords": [{"Fn::GetAtt": ["OpenVPN", "PublicDnsName"]}]
536
+ }},
537
+
538
+ "OpenVPNSecurityGroup": {"Type": "AWS::EC2::SecurityGroup", "Properties": {
539
+ "GroupDescription": "Enable everything",
540
+ "VpcId": {"Ref": "VPC"},
541
+
542
+ "SecurityGroupIngress": [
543
+ {"IpProtocol": "tcp", "FromPort": "443", "ToPort": "443", "CidrIp": "0.0.0.0/0"},
544
+ {"IpProtocol": "udp", "FromPort": "1192", "ToPort": "1194", "CidrIp": "0.0.0.0/0"},
545
+ {"IpProtocol": "tcp", "FromPort": "943", "ToPort": "943", "CidrIp": "0.0.0.0/0"},
546
+ {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0"}
547
+ ]
548
+ }}
549
+
550
+ }
551
+ }
data/stacco.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'stacco'
3
- s.version = '0.1.7'
3
+ s.version = '0.1.9'
4
4
  s.licenses = ['MIT']
5
5
  s.summary = "CloudFormation stack manipulator"
6
6
  s.description = "AWS CloudFromation stack manipulation toolsuite"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stacco
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -51,6 +51,7 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - ./priv/templates/cloudformation.json.erb
54
+ - ./priv/templates/cloudformation.json.erb.with-proxy-protocol
54
55
  - ./priv/cloud-init/roles/vpn.sh
55
56
  - ./priv/cloud-init/roles/docker-host.sh
56
57
  - ./priv/cloud-init/roles/backend.sh