rubycfn 0.5.0 → 0.5.5

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.
@@ -10,11 +10,18 @@ ENV["AWS_DEFAULT_REGION"] ||= "eu-west-1"
10
10
  ENV["AWS_REGION"] ||= ENV["AWS_DEFAULT_REGION"]
11
11
 
12
12
  client = Aws::CloudFormation::Client.new(region: ENV["AWS_REGION"])
13
- res = client.describe_stacks(
14
- stack_name: "DependencyStack"
15
- )
16
13
 
17
- dep_file = File.open(".env.dependencies", "w")
14
+ begin
15
+ res = client.describe_stacks(
16
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack"
17
+ )
18
+ rescue Aws::CloudFormation::Errors::InvalidClientTokenId, Aws::CloudFormation::Errors::ValidationError => e
19
+ puts "E: #{e.class}"
20
+ raise "ERROR: Your AWS credentials are not set or invalid." if e.class == Aws::CloudFormation::Errors::InvalidClientTokenId
21
+ raise "ERROR: <%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack does not exist. Run `rake init` first!" if e.class == Aws::CloudFormation::Errors::ValidationError
22
+ end
23
+
24
+ dep_file = File.open(".env.dependencies.#{ENV["ENVIRONMENT"]}", "w")
18
25
  res[:stacks].each do |stack|
19
26
  stack[:outputs].each do |output|
20
27
  dep_file.puts "#{output[:output_key].upcase}=#{output[:output_value]}"
@@ -7,8 +7,8 @@ require "aws-sdk"
7
7
  require_relative "../aws_helper/main"
8
8
 
9
9
  Dotenv.load(".env.private")
10
- Dotenv.load(".env.dependencies")
11
- raise "CLOUDFORMATIONBUCKET not found in DependencyStack outputs" unless ENV["CLOUDFORMATIONBUCKET"]
10
+ Dotenv.load(".env.dependencies.#{ENV["ENVIRONMENT"]}")
11
+ raise "CLOUDFORMATIONBUCKET not set. Run `rake init` and `rake update` first!" unless ENV["CLOUDFORMATIONBUCKET"]
12
12
 
13
13
  env_vars = load_env_vars
14
14
 
@@ -26,7 +26,7 @@ s3_filename = get_parent_stack_s3_location(
26
26
  client = Aws::CloudFormation::Client.new
27
27
 
28
28
  parent_parameters = []
29
- File.open(".env.dependencies").read.each_line do |line|
29
+ File.open(".env.dependencies.#{ENV["ENVIRONMENT"]}").read.each_line do |line|
30
30
  line.strip!
31
31
  param, value = line.split("=")
32
32
  parent_parameters.push(
@@ -30,7 +30,7 @@ def inject_dummy_resource(stack)
30
30
  end
31
31
 
32
32
  def read_domain_name
33
- config = YAML.safe_load(File.read("config.yaml"))
33
+ config = YAML.safe_load(File.read("config.yaml"), [Symbol])
34
34
  config["applications"] ||= {}
35
35
  config["environments"] ||= {}
36
36
  config["subnets"] ||= {}
@@ -60,16 +60,64 @@ subdomain, domain_name = read_domain_name
60
60
  raise "ENVIRONMENT not set" unless ENV["ENVIRONMENT"]
61
61
  warn "WARNING: domain_name not set in config.yaml... Route53 Hosted Zone will not be created" if domain_name.empty?
62
62
 
63
- module DependencyStack
63
+ module Project<%= project_name %>DependencyStack
64
64
  extend ActiveSupport::Concern
65
65
  include Rubycfn
66
66
 
67
67
  included do
68
- self.class_eval(File.open("bootstrap/dependency_stack.rb").read)
68
+ description "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}Dependency Stack"
69
+
70
+ parameter :environment,
71
+ description: "Environment name",
72
+ type: "String"
73
+
74
+ parameter :domain_name,
75
+ description: "Domain name",
76
+ type: "String"
77
+
78
+ condition :has_environment,
79
+ [["", :environment.ref].fnequals].fnnot
80
+
81
+ condition :has_domain_name,
82
+ [["", :domain_name.ref].fnequals].fnnot
83
+
84
+ %i(
85
+ artifact_bucket
86
+ cloudformation_bucket
87
+ lambda_bucket
88
+ logging_bucket
89
+ ).each do |bucket|
90
+ resource bucket,
91
+ deletion_policy: "Retain",
92
+ update_replace_policy: "Retain",
93
+ type: "AWS::S3::Bucket"
94
+
95
+ output bucket,
96
+ value: bucket.ref
97
+ end
98
+
99
+ resource :hosted_zone,
100
+ condition: "HasDomainName",
101
+ type: "AWS::Route53::HostedZone" do |r|
102
+ r.property(:hosted_zone_config) do
103
+ {
104
+ "Comment": ["Hosted zone for ", ["HasEnvironment", [:environment.ref, "."].fnjoin, ""].fnif, :domain_name.ref].fnjoin
105
+ }
106
+ end
107
+ r.property(:name) { [["HasEnvironment", [:environment.ref, "."].fnjoin, ""].fnif, :domain_name.ref].fnjoin }
108
+ end
109
+
110
+ output :hosted_zone_id,
111
+ condition: "HasDomainName",
112
+ value: :hosted_zone.ref
113
+
114
+ output :hosted_zone_name,
115
+ condition: "HasDomainName",
116
+ value: [["HasEnvironment", [:environment.ref, "."].fnjoin, ""].fnif, :domain_name.ref].fnjoin
69
117
  end
70
118
  end
71
119
 
72
- stack = include DependencyStack # rubocop:disable Style/MixinUsage
120
+ stack = include Project<%= project_name %>DependencyStack # rubocop:disable Style/MixinUsage
73
121
  template = stack.render_template
74
122
 
75
123
  client = Aws::CloudFormation::Client.new
@@ -77,7 +125,7 @@ client = Aws::CloudFormation::Client.new
77
125
  stack_exists = false
78
126
  previous_statuses = []
79
127
  80.times do
80
- previous_events = get_prior_events(client, "DependencyStack")
128
+ previous_events = get_prior_events(client, "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack")
81
129
  previous_statuses = previous_events.map(&:event_id)
82
130
  stack_exists = previous_events.size.to_i.positive? ? true : false
83
131
  break unless stack_exists
@@ -85,8 +133,8 @@ previous_statuses = []
85
133
  events_last_deploy = get_events_last_deploy(previous_events)
86
134
  last_event = events_last_deploy.shift
87
135
  break if last_event \
88
- && (last_event.logical_resource_id == "DependencyStack") \
89
- && (last_event.stack_name == "DependencyStack") \
136
+ && (last_event.logical_resource_id == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
137
+ && (last_event.stack_name == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
90
138
  && (DEPLOYABLE_STATES.include? last_event.resource_status)
91
139
  puts "Stack is currently in #{last_event.resource_status} mode. Waiting for it to finish..." if last_event
92
140
  sleep 15
@@ -107,7 +155,7 @@ parameters = [
107
155
 
108
156
  if stack_exists
109
157
  client.update_stack(
110
- stack_name: "DependencyStack",
158
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack",
111
159
  template_body: template,
112
160
  capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
113
161
  parameters: parameters,
@@ -120,7 +168,7 @@ if stack_exists
120
168
  )
121
169
  else
122
170
  client.create_stack(
123
- stack_name: "DependencyStack",
171
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack",
124
172
  template_body: template,
125
173
  timeout_in_minutes: 60,
126
174
  capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
@@ -140,7 +188,7 @@ shown_log_lines = {}
140
188
 
141
189
  360.times do
142
190
  resp = client.describe_stack_events(
143
- stack_name: "DependencyStack"
191
+ stack_name: "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack"
144
192
  )
145
193
  resp.stack_events.to_a.reverse.each_with_index do |event, index|
146
194
  next if previous_statuses.include? event.event_id
@@ -155,8 +203,8 @@ shown_log_lines = {}
155
203
  "#{@resource_status.white} #{@resource_status_reason.to_s.red}"
156
204
  puts log_line unless shown_log_lines[log_line]
157
205
  shown_log_lines[log_line] = true
158
- if (@stack_name == "DependencyStack") \
159
- && (@logical_resource_id == "DependencyStack") \
206
+ if (@stack_name == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
207
+ && (@logical_resource_id == "<%= project_name %>#{ENV["ENVIRONMENT"].capitalize}DependencyStack") \
160
208
  && (END_STATES.include? @resource_status) \
161
209
  && (index + 1 == resp.stack_events.to_a.size)
162
210
  @completed = true
@@ -3,7 +3,7 @@ require "dotenv"
3
3
  require_relative "core/classes"
4
4
 
5
5
  Dotenv.load(".env.private")
6
- Dotenv.load(".env.dependencies")
6
+ Dotenv.load(".env.dependencies.#{ENV["ENVIRONMENT"]}")
7
7
  Dotenv.load(".env")
8
8
  Dotenv.load(".env.#{ENV["ENVIRONMENT"]}")
9
9
 
@@ -6,7 +6,7 @@ module Concerns
6
6
 
7
7
  included do
8
8
  def load_config(_val)
9
- config = YAML.safe_load(File.read("config.yaml"))
9
+ config = YAML.safe_load(File.read("config.yaml"), [Symbol])
10
10
  config["applications"] ||= {}
11
11
  config["environments"] ||= {}
12
12
  config["subnets"] ||= {}
@@ -35,7 +35,9 @@ module Concerns
35
35
  end
36
36
 
37
37
  def generate_bootstrap_parameters
38
- File.open(".env.dependencies#{environment == "rspec" && ".rspec" || ""}").read.each_line do |line|
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|
39
41
  line.strip!
40
42
  param, _value = line.split("=")
41
43
  parameter param.to_sym,
@@ -22,323 +22,323 @@ module EcsStack
22
22
  resource :ecs_cluster,
23
23
  type: "AWS::ECS::Cluster"
24
24
 
25
- resource :ecs_auto_scaling_group,
26
- type: "AWS::AutoScaling::AutoScalingGroup" do |r|
27
- r.property(:vpc_zone_identifier) { :subnets.ref.fnsplit(",") }
28
- r.property(:launch_configuration_name) { :ecs_launch_configuration.ref }
29
- r.property(:min_size) { cluster_size.to_i }
30
- r.property(:max_size) { cluster_size.to_i }
31
- r.property(:desired_capacity) { cluster_size.to_i }
32
- r.property(:tags) do
33
- [
34
- {
35
- "Key": "Name",
36
- "Value": "#{environment} ECS host",
37
- "PropagateAtLaunch": true
38
- }
39
- ]
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
40
42
  end
41
- end
42
43
 
43
- resource :ecs_launch_configuration,
44
- metadata: {
45
- "AWS::CloudFormation::Init": {
46
- "config": {
47
- "packages": {
48
- "yum": {
49
- "collectd": []
50
- }
51
- },
52
- "commands": {
53
- "01_add_instance_to_cluster": {
54
- "command": "echo ECS_CLUSTER=${SfsEcsCluster} >> /etc/ecs/ecs.config".fnsub
44
+ resource :ecs_launch_configuration,
45
+ metadata: {
46
+ "AWS::CloudFormation::Init": {
47
+ "config": {
48
+ "packages": {
49
+ "yum": {
50
+ "collectd": []
51
+ }
55
52
  },
56
- "02_enable_cloudwatch_agent": {
57
- "command": "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:${EcsCloudWatchParameter} -s".fnsub
58
- }
59
- },
60
- "files": {
61
- "/etc/cfn/cfn-hup.conf": {
62
- "mode": 256,
63
- "owner": "root",
64
- "group": "root",
65
- "content": "[main]\nstack=${AWS::StackId}\nregion=${AWS::Region}\n".fnsub
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
+ }
66
60
  },
67
- "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
68
- "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
69
- }
70
- },
71
- "services": {
72
- "sysvinit": {
73
- "cfn-hup": {
74
- "enabled": true,
75
- "ensureRunning": true,
76
- "files": [
77
- "/etc/cfn/cfn-hup.conf",
78
- "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
79
- ]
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
+ }
80
82
  }
81
83
  }
82
84
  }
83
85
  }
84
- }
85
- },
86
- type: "AWS::AutoScaling::LaunchConfiguration" do |r|
87
- r.property(:image_id) { :ecs_ami.ref }
88
- r.property(:key_name) { "sfs-keypair-#{environment}" }
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
- ]
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 }
95
98
  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
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": "${SfsEcsCluster}-/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": "${SfsEcsCluster}-/var/log/dmesg",
115
- "log_stream_name": "{instance_id}"
116
- },
117
- {
118
- "file_path": "/var/log/docker",
119
- "log_group_name": "${SfsEcsCluster}-/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": "${SfsEcsCluster}-/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": "${SfsEcsCluster}-/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": "${SfsEcsCluster}-/var/log/ecs/audit.log",
138
- "log_stream_name": "{instance_id}",
139
- "timestamp_format": "%Y-%m-%dT%H:%M:%SZ"
140
- }
141
- ]
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
+ }
142
143
  }
143
- }
144
- },
145
- "metrics": {
146
- "append_dimensions": {
147
- "AutoScalingGroupName": "${!aws:AutoScalingGroupName}",
148
- "InstanceId": "${!aws:InstanceId}",
149
- "InstanceType": "${!aws:InstanceType}"
150
144
  },
151
- "metrics_collected": {
152
- "collectd": {
153
- "metrics_aggregation_interval": 60
145
+ "metrics": {
146
+ "append_dimensions": {
147
+ "AutoScalingGroupName": "${!aws:AutoScalingGroupName}",
148
+ "InstanceId": "${!aws:InstanceId}",
149
+ "InstanceType": "${!aws:InstanceType}"
154
150
  },
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"
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
+ }
174
175
  }
175
176
  }
176
177
  }
177
- }
178
178
 
179
- resource :ecs_cloud_watch_parameter,
180
- type: "AWS::SSM::Parameter" do |r|
181
- r.property(:description) { "ECS" }
182
- r.property(:name) { "AmazonCloudWatch-${SfsEcsCluster}-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
- ]
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 }
198
185
  end
199
- r.property(:tags) do
200
- [
201
- {
202
- "Key": "Name",
203
- "Value": "#{environment}-ECS-Hosts"
204
- }
205
- ]
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
206
207
  end
207
- end
208
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
- ]
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
220
229
  end
221
- r.property(:tags) do
222
- [
230
+
231
+ ecs_role_assume_role_policy_document = {
232
+ "Statement": [
223
233
  {
224
- "Key": "Name",
225
- "Value": "#{environment}-ECS-LoadBalancers"
234
+ "Action": "sts:AssumeRole",
235
+ "Effect": "Allow",
236
+ "Principal": {
237
+ "Service": "ec2.amazonaws.com"
238
+ }
226
239
  }
227
240
  ]
228
- end
229
- end
241
+ }
230
242
 
231
- ecs_role_assume_role_policy_document = {
232
- "Statement": [
233
- {
234
- "Action": "sts:AssumeRole",
243
+ ecs_role_policy_document = {
244
+ "Statement": [{
235
245
  "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
- }
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
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
- ]
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
282
283
  end
283
- end
284
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
- ]
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
292
293
  end
293
- end
294
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
- [
295
+ resource :ecs_service_auto_scaling_role,
296
+ type: "AWS::IAM::Role" do |r|
297
+ r.property(:assume_role_policy_document) do
316
298
  {
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": "*"
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
+ ]
329
309
  }
330
310
  }
331
311
  }
332
- ]
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
333
334
  end
335
+ output :ecs_auto_scaling_role_arn,
336
+ value: :ecs_service_auto_scaling_role.ref(:arn)
334
337
  end
335
-
336
338
  output :ecs_cluster,
337
339
  value: :ecs_cluster.ref
338
340
  output :ecs_cluster_arn,
339
341
  value: :ecs_cluster.ref(:arn)
340
- output :ecs_auto_scaling_role_arn,
341
- value: :ecs_service_auto_scaling_role.ref(:arn)
342
342
  end
343
343
  end
344
344
  end