rubycfn 0.4.10 → 0.5.4

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/Gemfile.lock +48 -46
  4. data/README.md +46 -71
  5. data/bin/rubycfn +17 -73
  6. data/lib/cli_methods.rb +2 -2
  7. data/lib/rubycfn/version.rb +1 -1
  8. data/rubycfn.gemspec +1 -1
  9. data/templates/.env +2 -0
  10. data/templates/.env.acceptance +1 -0
  11. data/templates/.env.dependencies.rspec +6 -0
  12. data/templates/.env.development +1 -0
  13. data/templates/.env.production +1 -0
  14. data/templates/.env.rspec +1 -0
  15. data/templates/.env.test +1 -0
  16. data/templates/{.gitignore.erb → .gitignore} +7 -0
  17. data/templates/{.rubocop.yml.erb → .rubocop.yml} +17 -1
  18. data/templates/{Gemfile.erb → Gemfile} +0 -1
  19. data/templates/README.md +58 -0
  20. data/templates/{Rakefile.erb → Rakefile} +15 -8
  21. data/templates/config.yaml +68 -0
  22. data/templates/lib/aws_helper/aws_sdk.rb +30 -0
  23. data/templates/{compiler.rb.erb → lib/aws_helper/compiler.rb} +15 -9
  24. data/templates/lib/aws_helper/dependencies.rb +35 -0
  25. data/templates/{deploy.rb.erb → lib/aws_helper/deploy.rb} +5 -4
  26. data/templates/lib/aws_helper/helpers.rb +3 -0
  27. data/templates/{main_aws_helper.rb.erb → lib/aws_helper/main.rb} +0 -0
  28. data/templates/{upload_stack.rb.erb → lib/aws_helper/upload_stack.rb} +8 -6
  29. data/templates/lib/core/applications.rb +625 -0
  30. data/templates/lib/core/assume_role.rb +40 -0
  31. data/templates/lib/core/classes.rb +25 -0
  32. data/templates/{core_compile.rb.erb → lib/core/compile.rb} +1 -0
  33. data/templates/lib/core/dependencies.rb +29 -0
  34. data/templates/{core_deploy.rb.erb → lib/core/deploy.rb} +20 -10
  35. data/templates/lib/core/git.rb +15 -0
  36. data/templates/lib/core/init.rb +221 -0
  37. data/templates/{core_upload.rb.erb → lib/core/upload.rb} +0 -0
  38. data/templates/{main.rb.erb → lib/main.rb} +8 -6
  39. data/templates/lib/shared_concerns/global_variables.rb +56 -0
  40. data/templates/{helper_methods.rb.erb → lib/shared_concerns/helper_functions.rb} +0 -0
  41. data/templates/lib/shared_concerns/helper_methods.rb +3 -0
  42. data/templates/{shared_methods.rb.erb → lib/shared_concerns/shared_methods.rb} +11 -0
  43. data/templates/lib/stacks/acm_stack/certificate_manager.rb +79 -0
  44. data/templates/{new_stack.rb.erb → lib/stacks/acm_stack/main.rb} +3 -4
  45. data/templates/lib/stacks/ecs_stack/ecs_cluster.rb +344 -0
  46. data/templates/lib/stacks/ecs_stack/lifecycle_hook.rb +190 -0
  47. data/templates/lib/stacks/ecs_stack/load_balancer.rb +70 -0
  48. data/templates/{ecs_stack.rb.erb → lib/stacks/ecs_stack/main.rb} +3 -0
  49. data/templates/lib/stacks/ecs_stack/rollback.rb +77 -0
  50. data/templates/{project_stack.rb.erb → lib/stacks/parent_stack/main.rb} +2 -2
  51. data/templates/lib/stacks/parent_stack/parent.rb +18 -0
  52. data/templates/lib/stacks/vpc_stack/infra_vpc.rb +193 -0
  53. data/templates/{vpc_stack.rb.erb → lib/stacks/vpc_stack/main.rb} +1 -2
  54. data/templates/{parent_stack_spec.rb.erb → spec/lib/parent_spec.rb} +2 -5
  55. data/templates/{spec_helper.rb.erb → spec/spec_helper.rb} +2 -2
  56. metadata +61 -51
  57. data/format.vim +0 -3
  58. data/templates/.env.erb +0 -4
  59. data/templates/.env.production.erb +0 -6
  60. data/templates/.env.rspec.erb +0 -6
  61. data/templates/.env.test.erb +0 -6
  62. data/templates/.gitlab-ci.yml.erb +0 -75
  63. data/templates/aws_sdk.rb.erb +0 -18
  64. data/templates/core_diff.rb.erb +0 -59
  65. data/templates/dependencies.rb.erb +0 -23
  66. data/templates/ecs_stack_concern.rb.erb +0 -20
  67. data/templates/global_variables.rb.erb +0 -16
  68. data/templates/helpers.rb.erb +0 -7
  69. data/templates/new_concern.rb.erb +0 -10
  70. data/templates/project_concern.rb.erb +0 -26
  71. data/templates/subnets.rb.erb +0 -18
  72. data/templates/vpc_concerns.rb.erb +0 -87
  73. data/templates/vpc_spec.rb.erb +0 -39
@@ -0,0 +1,3 @@
1
+ def file_to_inline(filename)
2
+ File.open(filename).read.split("\n")
3
+ end
@@ -33,6 +33,17 @@ module Concerns
33
33
  "#{stack_name}-#{Git::Revision.commit}" \
34
34
  "#{Git::Revision.dirty? ? "-dirty" : ""}"
35
35
  end
36
+
37
+ def generate_bootstrap_parameters
38
+ warn "WARNING: .env.dependencies.#{ENV["ENVIRONMENT"]} does not exist. Run `rake dependencies` first!" unless File.file?(".env.dependencies.#{ENV["ENVIRONMENT"]}")
39
+ filename = File.file?(".env.dependencies.#{ENV["ENVIRONMENT"]}") && ".env.dependencies#{environment == "rspec" && ".rspec" || ".#{ENV["ENVIRONMENT"]}"}" || ".env.dependencies.rspec"
40
+ File.open(filename).read.each_line do |line|
41
+ line.strip!
42
+ param, _value = line.split("=")
43
+ parameter param.to_sym,
44
+ description: param
45
+ end
46
+ end
36
47
  end
37
48
  end
38
49
  end
@@ -0,0 +1,79 @@
1
+ module AcmStack
2
+ module CertificateManager
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ resource :certificate_provider_function,
6
+ type: "AWS::Lambda::Function" do |r|
7
+ r.property(:code) do
8
+ {
9
+ "S3Bucket": "xebia-${AWS::Region}".fnsub,
10
+ "S3Key": "cfn-certificate-provider-0.2.4.zip"
11
+ }
12
+ end
13
+ r.property(:handler) { "provider.handler" }
14
+ r.property(:role) { :lambda_execution_role.ref(:arn) }
15
+ r.property(:runtime) { "python3.6" }
16
+ r.property(:memory_size) { 128 }
17
+ r.property(:timeout) { 300 }
18
+ end
19
+
20
+ resource :lambda_execution_role,
21
+ type: "AWS::IAM::Role" do |r|
22
+ r.property(:assume_role_policy_document) do
23
+ {
24
+ "Version": "2012-10-17",
25
+ "Statement": [
26
+ {
27
+ "Effect": "Allow",
28
+ "Principal": {
29
+ "Service": [
30
+ "lambda.amazonaws.com"
31
+ ]
32
+ },
33
+ "Action": [
34
+ "sts:AssumeRole"
35
+ ]
36
+ }
37
+ ]
38
+ }
39
+ end
40
+ r.property(:path) { "/" }
41
+ r.property(:policies) do
42
+ [
43
+ {
44
+ "PolicyName": "CertificateProviderExecutionRole",
45
+ "PolicyDocument": {
46
+ "Version": "2012-10-17",
47
+ "Statement": [
48
+ {
49
+ "Effect": "Allow",
50
+ "Resource": "*",
51
+ "Action": [
52
+ "acm:RequestCertificate",
53
+ "acm:DescribeCertificate",
54
+ "acm:UpdateCertificateOptions",
55
+ "acm:DeleteCertificate"
56
+ ]
57
+ },
58
+ {
59
+ "Effect": "Allow",
60
+ "Action": "lambda:InvokeFunction",
61
+ "Resource": "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:*".fnsub
62
+ },
63
+ {
64
+ "Effect": "Allow",
65
+ "Action": %w(logs:CreateLogGroup logs:CreateLogStream logs:PutLogEvents),
66
+ "Resource": "arn:aws:logs:*:*:*"
67
+ }
68
+ ]
69
+ }
70
+ }
71
+ ]
72
+ end
73
+ end
74
+
75
+ output :certificate_provider_function_arn,
76
+ value: :certificate_provider_function.ref(:arn)
77
+ end
78
+ end
79
+ end
@@ -1,12 +1,11 @@
1
- module <%= stack_name %>
1
+ module AcmStack
2
2
  extend ActiveSupport::Concern
3
3
  include Rubycfn
4
-
5
4
  included do
6
5
  include Concerns::GlobalVariables
7
6
  include Concerns::SharedMethods
8
- include <%= stack_name %>::MyModule
7
+ include AcmStack::CertificateManager
9
8
 
10
- description generate_stack_description("<%= stack_name %>")
9
+ description generate_stack_description("AcmStack")
11
10
  end
12
11
  end
@@ -0,0 +1,344 @@
1
+ module EcsStack
2
+ module EcsCluster
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ parameter :vpc,
6
+ description: "VPC ID"
7
+ parameter :subnets,
8
+ description: "Subnets for ECS"
9
+ parameter :ecs_ami,
10
+ description: "ECS-Optimized AMI ID",
11
+ type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
12
+ default: "/aws/service/ecs/optimized-ami/amazon-linux/recommended/image_id"
13
+
14
+ variable :cluster_size,
15
+ default: "1",
16
+ value: infra_config["environments"][environment]["cluster_size"]
17
+
18
+ variable :cluster_instance_type,
19
+ default: "t2.micro",
20
+ value: infra_config["environments"][environment]["cluster_instance_type"]
21
+
22
+ resource :ecs_cluster,
23
+ type: "AWS::ECS::Cluster"
24
+
25
+ unless infra_config["environments"][environment]["cluster_size"].nil? || infra_config["environments"][environment]["cluster_size"].to_i.zero?
26
+ resource :ecs_auto_scaling_group,
27
+ type: "AWS::AutoScaling::AutoScalingGroup" do |r|
28
+ r.property(:vpc_zone_identifier) { :subnets.ref.fnsplit(",") }
29
+ r.property(:launch_configuration_name) { :ecs_launch_configuration.ref }
30
+ r.property(:min_size) { cluster_size.to_i }
31
+ r.property(:max_size) { cluster_size.to_i + 1 }
32
+ r.property(:desired_capacity) { cluster_size.to_i }
33
+ r.property(:tags) do
34
+ [
35
+ {
36
+ "Key": "Name",
37
+ "Value": "#{environment} ECS host",
38
+ "PropagateAtLaunch": true
39
+ }
40
+ ]
41
+ end
42
+ end
43
+
44
+ resource :ecs_launch_configuration,
45
+ metadata: {
46
+ "AWS::CloudFormation::Init": {
47
+ "config": {
48
+ "packages": {
49
+ "yum": {
50
+ "collectd": []
51
+ }
52
+ },
53
+ "commands": {
54
+ "01_add_instance_to_cluster": {
55
+ "command": "echo ECS_CLUSTER=${EcsCluster} >> /etc/ecs/ecs.config".fnsub
56
+ },
57
+ "02_enable_cloudwatch_agent": {
58
+ "command": "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:${EcsCloudWatchParameter} -s".fnsub
59
+ }
60
+ },
61
+ "files": {
62
+ "/etc/cfn/cfn-hup.conf": {
63
+ "mode": 256,
64
+ "owner": "root",
65
+ "group": "root",
66
+ "content": "[main]\nstack=${AWS::StackId}\nregion=${AWS::Region}\n".fnsub
67
+ },
68
+ "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
69
+ "content": "[cfn-auto-reloader-hook]\ntriggers=post.update\npath=Resources.EcsLaunchConfiguration.Metadata.AWS::CloudFormation::Init\naction=/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource EcsLaunchConfiguration\n".fnsub
70
+ }
71
+ },
72
+ "services": {
73
+ "sysvinit": {
74
+ "cfn-hup": {
75
+ "enabled": true,
76
+ "ensureRunning": true,
77
+ "files": [
78
+ "/etc/cfn/cfn-hup.conf",
79
+ "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
80
+ ]
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ },
87
+ type: "AWS::AutoScaling::LaunchConfiguration" do |r|
88
+ r.property(:image_id) { :ecs_ami.ref }
89
+ r.property(:instance_type) { cluster_instance_type }
90
+ r.property(:security_groups) do
91
+ [
92
+ :ecs_host_security_group.ref,
93
+ :load_balancer_security_group.ref # Not sure if necessary
94
+ ]
95
+ end
96
+ r.property(:iam_instance_profile) { :ecs_instance_profile.ref }
97
+ r.property(:user_data) { "#!/bin/bash\nyum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm\nyum install -y https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm\nyum install -y aws-cfn-bootstrap hibagent \n/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource EcsLaunchConfiguration\n/opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource EcsAutoScalingGroup\n/usr/bin/enable-ec2-spot-hibernation\n".fnsub.fnbase64 }
98
+ end
99
+
100
+ ecs_ssm_parameter_value = {
101
+ "logs": {
102
+ "force_flush_interval": 5,
103
+ "logs_collected": {
104
+ "files": {
105
+ "collect_list": [
106
+ {
107
+ "file_path": "/var/log/messages",
108
+ "log_group_name": "${EcsCluster}-/var/log/messages",
109
+ "log_stream_name": "{instance_id}",
110
+ "timestamp_format": "%b %d %H:%M:%S"
111
+ },
112
+ {
113
+ "file_path": "/var/log/dmesg",
114
+ "log_group_name": "${EcsCluster}-/var/log/dmesg",
115
+ "log_stream_name": "{instance_id}"
116
+ },
117
+ {
118
+ "file_path": "/var/log/docker",
119
+ "log_group_name": "${EcsCluster}-/var/log/docker",
120
+ "log_stream_name": "{instance_id}",
121
+ "timestamp_format": "%Y-%m-%dT%H:%M:%S.%f"
122
+ },
123
+ {
124
+ "file_path": "/var/log/ecs/ecs-init.log",
125
+ "log_group_name": "${EcsCluster}-/var/log/ecs/ecs-init.log",
126
+ "log_stream_name": "{instance_id}",
127
+ "timestamp_format": "%Y-%m-%dT%H:%M:%SZ"
128
+ },
129
+ {
130
+ "file_path": "/var/log/ecs/ecs-agent.log.*",
131
+ "log_group_name": "${EcsCluster}-/var/log/ecs/ecs-agent.log",
132
+ "log_stream_name": "{instance_id}",
133
+ "timestamp_format": "%Y-%m-%dT%H:%M:%SZ"
134
+ },
135
+ {
136
+ "file_path": "/var/log/ecs/audit.log",
137
+ "log_group_name": "${EcsCluster}-/var/log/ecs/audit.log",
138
+ "log_stream_name": "{instance_id}",
139
+ "timestamp_format": "%Y-%m-%dT%H:%M:%SZ"
140
+ }
141
+ ]
142
+ }
143
+ }
144
+ },
145
+ "metrics": {
146
+ "append_dimensions": {
147
+ "AutoScalingGroupName": "${!aws:AutoScalingGroupName}",
148
+ "InstanceId": "${!aws:InstanceId}",
149
+ "InstanceType": "${!aws:InstanceType}"
150
+ },
151
+ "metrics_collected": {
152
+ "collectd": {
153
+ "metrics_aggregation_interval": 60
154
+ },
155
+ "disk": {
156
+ "measurement": [
157
+ "used_percent"
158
+ ],
159
+ "metrics_collection_interval": 60,
160
+ "resources": [
161
+ "/"
162
+ ]
163
+ },
164
+ "mem": {
165
+ "measurement": [
166
+ "mem_used_percent"
167
+ ],
168
+ "metrics_collection_interval": 60
169
+ },
170
+ "statsd": {
171
+ "metrics_aggregation_interval": 60,
172
+ "metrics_collection_interval": 10,
173
+ "service_address": ":8125"
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ resource :ecs_cloud_watch_parameter,
180
+ type: "AWS::SSM::Parameter" do |r|
181
+ r.property(:description) { "ECS" }
182
+ r.property(:name) { "AmazonCloudWatch-${EcsCluster}-ECS".fnsub }
183
+ r.property(:type) { "String" }
184
+ r.property(:value) { JSON.pretty_generate(ecs_ssm_parameter_value).fnsub }
185
+ end
186
+
187
+ resource :ecs_host_security_group,
188
+ type: "AWS::EC2::SecurityGroup" do |r|
189
+ r.property(:vpc_id) { :vpc.ref }
190
+ r.property(:group_description) { "Access to the ECS hosts and the tasks/containers that run on them" }
191
+ r.property(:security_group_ingress) do
192
+ [
193
+ {
194
+ "SourceSecurityGroupId": :load_balancer_security_group.ref,
195
+ "IpProtocol": -1
196
+ }
197
+ ]
198
+ end
199
+ r.property(:tags) do
200
+ [
201
+ {
202
+ "Key": "Name",
203
+ "Value": "#{environment}-ECS-Hosts"
204
+ }
205
+ ]
206
+ end
207
+ end
208
+
209
+ resource :load_balancer_security_group,
210
+ type: "AWS::EC2::SecurityGroup" do |r|
211
+ r.property(:vpc_id) { :vpc.ref }
212
+ r.property(:group_description) { "Access to the load balancer that sits in front of ECS" }
213
+ r.property(:security_group_ingress) do
214
+ [
215
+ {
216
+ "CidrIp": "0.0.0.0/0",
217
+ "IpProtocol": -1
218
+ }
219
+ ]
220
+ end
221
+ r.property(:tags) do
222
+ [
223
+ {
224
+ "Key": "Name",
225
+ "Value": "#{environment}-ECS-LoadBalancers"
226
+ }
227
+ ]
228
+ end
229
+ end
230
+
231
+ ecs_role_assume_role_policy_document = {
232
+ "Statement": [
233
+ {
234
+ "Action": "sts:AssumeRole",
235
+ "Effect": "Allow",
236
+ "Principal": {
237
+ "Service": "ec2.amazonaws.com"
238
+ }
239
+ }
240
+ ]
241
+ }
242
+
243
+ ecs_role_policy_document = {
244
+ "Statement": [{
245
+ "Effect": "Allow",
246
+ "Action": [
247
+ "ecs:CreateCluster",
248
+ "ecs:DeregisterContainerInstance",
249
+ "ecs:DiscoverPollEndpoint",
250
+ "ecs:Poll",
251
+ "ecs:RegisterContainerInstance",
252
+ "ecs:StartTelemetrySession",
253
+ "ecs:Submit*",
254
+ "ecr:BatchCheckLayerAvailability",
255
+ "ecr:BatchGetImage",
256
+ "ecr:GetDownloadUrlForLayer",
257
+ "ecr:GetAuthorizationToken"
258
+ ],
259
+ "Resource": "*"
260
+ }]
261
+ }
262
+
263
+ resource :ecs_role,
264
+ type: "AWS::IAM::Role" do |r|
265
+ r.property(:path) { "/" }
266
+ r.property(:role_name) { "#{environment}-ECSRole-${AWS::Region}".fnsub }
267
+ r.property(:assume_role_policy_document) { JSON.pretty_generate(ecs_role_assume_role_policy_document) }
268
+ r.property(:managed_policy_arns) do
269
+ [
270
+ "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM",
271
+ "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy",
272
+ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
273
+ ]
274
+ end
275
+ r.property(:policies) do
276
+ [
277
+ {
278
+ "PolicyName": "ecs-service",
279
+ "PolicyDocument": JSON.pretty_generate(ecs_role_policy_document)
280
+ }
281
+ ]
282
+ end
283
+ end
284
+
285
+ resource :ecs_instance_profile,
286
+ type: "AWS::IAM::InstanceProfile" do |r|
287
+ r.property(:path) { "/" }
288
+ r.property(:roles) do
289
+ [
290
+ :ecs_role.ref
291
+ ]
292
+ end
293
+ end
294
+
295
+ resource :ecs_service_auto_scaling_role,
296
+ type: "AWS::IAM::Role" do |r|
297
+ r.property(:assume_role_policy_document) do
298
+ {
299
+ "Version": "2012-10-17",
300
+ "Statement": {
301
+ "Action": [
302
+ "sts:AssumeRole"
303
+ ],
304
+ "Effect": "Allow",
305
+ "Principal": {
306
+ "Service": [
307
+ "application-autoscaling.amazonaws.com"
308
+ ]
309
+ }
310
+ }
311
+ }
312
+ end
313
+ r.property(:path) { "/" }
314
+ r.property(:policies) do
315
+ [
316
+ {
317
+ "PolicyName": "ecs-service-autoscaling",
318
+ "PolicyDocument": {
319
+ "Statement": {
320
+ "Effect": "Allow",
321
+ "Action": [
322
+ "application-autoscaling:*",
323
+ "cloudwatch:DescribeAlarms",
324
+ "cloudwatch:PutMetricAlarm",
325
+ "ecs:DescribeServices",
326
+ "ecs:UpdateService"
327
+ ],
328
+ "Resource": "*"
329
+ }
330
+ }
331
+ }
332
+ ]
333
+ end
334
+ end
335
+ output :ecs_auto_scaling_role_arn,
336
+ value: :ecs_service_auto_scaling_role.ref(:arn)
337
+ end
338
+ output :ecs_cluster,
339
+ value: :ecs_cluster.ref
340
+ output :ecs_cluster_arn,
341
+ value: :ecs_cluster.ref(:arn)
342
+ end
343
+ end
344
+ end