sumomo 0.8.4 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,265 +1,259 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Sumomo
3
- module Stack
4
-
5
- def sluggify(str)
6
- str.gsub(/[^0-9a-zA-Z]/, "_")
7
- end
8
-
9
- def make_ecs_role
10
- make "AWS::IAM::Role", name: "ECSServiceRole" do
11
-
12
- role_policy_doc = {
13
- "Version" => "2012-10-17",
14
- "Statement" => [{
15
- "Effect" => "Allow",
16
- "Principal" => {"Service" => ["ecs.amazonaws.com"]},
17
- "Action" => ["sts:AssumeRole"]
18
- }]
19
- }
20
-
21
- AssumeRolePolicyDocument role_policy_doc
22
- Path "/"
23
- Policies [
24
- {
25
- "PolicyName" => "ecs-service",
26
- "PolicyDocument" => {
27
- "Version" => "2012-10-17",
28
- "Statement" => [{
29
- "Effect" => "Allow",
30
- "Action" => [
31
- "ec2:AuthorizeSecurityGroupIngress",
32
- "ec2:Describe*",
33
- "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
34
- "elasticloadbalancing:DeregisterTargets",
35
- "elasticloadbalancing:Describe*",
36
- "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
37
- "elasticloadbalancing:RegisterTargets"
38
- ],
39
- "Resource" => "*"
40
- }]
41
- }
42
- }
43
- ]
44
- end
45
- end
46
-
47
- def make_ecs_cluster(name:make_default_resource_name("ECSCluster"),services:[],machine_config:{},network:,log_retention:30,dependencies:[])
48
-
49
- ecs = make "AWS::ECS::Cluster", name: "#{name}" do
50
- dependencies.each do |x|
51
- depends_on x
52
- end
53
- end
54
-
55
- volumes = []
56
- machine_volume_locations = {}
57
-
58
- service_number = 0
59
-
60
- services.each do |service|
61
-
62
- alb = service[:alb]
63
- certificate = service[:certificate]
64
- alb_ports = {}
65
-
66
- service_number += 1
67
-
68
- containers = service[:containers]
69
- service_name = service[:name] || "Service#{service_number}"
70
- service_count = service[:count] || 1
71
-
72
- container_defs = containers.map do |container|
73
- definition = {}
74
-
75
- definition["Name"] = "#{sluggify(container[:image]).camelize}"
76
- definition["Name"] = container[:name] if container[:name]
77
-
78
- definition["Memory"] = container[:memory] || 1024
79
-
80
- loggroup = make "AWS::Logs::LogGroup", name: "#{name}#{definition["Name"]}Logs" do
81
- LogGroupName "#{definition["Name"].underscore}_logs"
82
- RetentionInDays log_retention
83
- end
84
-
85
- definition["LogConfiguration"] = {
86
- "LogDriver" => "awslogs",
87
- "Options" => {
88
- "awslogs-group" => loggroup,
89
- "awslogs-region" => ref("AWS::Region")
90
- }
91
- }
92
-
93
- if container[:files]
94
- definition["MountPoints"] = container[:files].map do |file, destination|
95
-
96
- s3_location = "container_files/#{sluggify(service_name)}/#{definition["Name"]}/#{file}"
97
- volume_name = sluggify("#{definition["Name"].underscore}_#{destination}").camelize
98
-
99
- upload_file s3_location, File.read(file)
100
-
101
- machine_volume_locations[s3_location] = "/opt/s3/#{s3_location}"
102
-
103
- volumes << {
104
- "Name" => volume_name,
105
- "Host" => { "SourcePath" => machine_volume_locations[s3_location] }
106
- }
107
-
108
- {
109
- "ContainerPath" => destination,
110
- "SourceVolume" => volume_name
111
- }
112
- end
113
- container.delete(:files)
114
- end
115
-
116
- if container[:ports]
117
- if !alb
118
- definition["PortMappings"] = container[:ports].map do |from_port, to_port|
119
- {
120
- "ContainerPort" => from_port,
121
- "HostPort" => to_port
122
- }
123
- end
124
-
125
- else
126
- definition["PortMappings"] = container[:ports].map do |from_port, to_port|
127
- {
128
- "ContainerPort" => from_port
129
- }
130
- end
131
-
132
- container[:ports].each do |container_port, host_port|
133
-
134
- if alb_ports[host_port.to_i]
135
- raise "Container #{alb_ports[host_port][:name]} is already using #{host_port}"
136
- end
137
-
138
- alb_target = make "AWS::ElasticLoadBalancingV2::TargetGroup", name: "#{name}#{definition["Name"]}Target" do
139
- HealthCheckIntervalSeconds 60
140
- UnhealthyThresholdCount 10
141
- HealthCheckPath "/"
142
- Name "#{name}Port#{host_port}Target"
143
- Port container_port
144
- Protocol "HTTP"
145
- VpcId network[:vpc]
146
-
147
- if container[:alb_sticky]
148
- TargetGroupAttributes({
149
- "stickiness.enabled" => true,
150
- "stickiness.type" => "lb_cookie"
151
- }.map{|k,v| {Key: k, Value: v} })
152
- container.delete(:alb_sticky)
153
- end
154
- end
155
-
156
- alb_action = {
157
- "Type" => "forward",
158
- "TargetGroupArn" => alb_target
159
- }
160
-
161
- if certificate
162
- alb_listener = make "AWS::ElasticLoadBalancingV2::Listener", name: "#{name}#{definition["Name"]}Listener" do
163
- Certificates [{ CertificateArn: certificate }]
164
- DefaultActions [ alb_action ]
165
- LoadBalancerArn alb
166
- Port host_port
167
- Protocol "HTTPS"
168
- end
169
- else
170
- alb_listener = make "AWS::ElasticLoadBalancingV2::Listener", name: "#{name}#{definition["Name"]}Listener" do
171
- DefaultActions [ alb_action ]
172
- LoadBalancerArn alb
173
- Port host_port
174
- Protocol "HTTP"
175
- end
176
- end
177
-
178
- alb_ports[host_port.to_i] = {
179
- listener: alb_listener,
180
- target: alb_target,
181
- port: container_port,
182
- name: definition["Name"]
183
- }
184
-
185
- end
186
-
187
- end
188
- container.delete(:ports)
189
- end
190
-
191
- if container[:envvars]
192
- definition["Environment"] = container[:envvars].map do |var_name, var_value|
193
- {
194
- "Name" => var_name,
195
- "Value" => var_value
196
- }
197
- end
198
- container.delete(:envvars)
199
- end
200
-
201
- container.each do |key, value|
202
- definition["#{key}".camelize] = value
203
- end
204
-
205
- definition
206
- end
207
-
208
-
209
- deployment_config = {
210
- "MaximumPercent" => 200,
211
- "MinimumHealthyPercent" => 50
212
- }
213
-
214
- ecs_task = make "AWS::ECS::TaskDefinition", name: "#{name}#{service_name}Task" do
215
- ContainerDefinitions container_defs
216
- Volumes volumes
217
- end
218
-
219
- stack = self
220
-
221
- ecs_service = make "AWS::ECS::Service", name: "#{name}#{service_name}" do
222
- alb_ports.each do |host_port, info|
223
- depends_on info[:listener]
224
- end
225
-
226
- Cluster ecs
227
- DesiredCount service_count
228
- TaskDefinition ecs_task
229
- DeploymentConfiguration deployment_config
230
-
231
- if alb_ports.keys.count != 0
232
- Role stack.make_ecs_role
233
- LoadBalancers alb_ports.values.map { |info|
234
- {
235
- "TargetGroupArn" => info[:target],
236
- "ContainerPort" => info[:port],
237
- "ContainerName" => info[:name]
238
- }
239
- }
240
- end
241
-
242
- end
243
- end #services
244
-
245
- machine_config[:methods].each do |method_name|
246
- parameters = {ecs_cluster: ecs}
247
-
248
- method(method_name).parameters.each do |param|
249
- parameters[param[1]] = machine_config[param[1]] if (param[0] == :keyreq or param[0] == :key) and machine_config[param[1]]
250
- end
251
-
252
- parameters[:network] = network if !parameters[:network]
253
-
254
- method(method_name).call(parameters) do
255
- machine_volume_locations.each do |s3_loc, machine_loc|
256
- mkdir File.dirname(machine_loc)
257
- download_file s3_loc, machine_loc
258
- end
259
- end
260
- end
261
-
262
- ecs
263
- end
264
- end
4
+ module Stack
5
+ def sluggify(str)
6
+ str.gsub(/[^0-9a-zA-Z]/, '_')
7
+ end
8
+
9
+ def make_ecs_role
10
+ make 'AWS::IAM::Role', name: 'ECSServiceRole' do
11
+ role_policy_doc = {
12
+ 'Version' => '2012-10-17',
13
+ 'Statement' => [{
14
+ 'Effect' => 'Allow',
15
+ 'Principal' => { 'Service' => ['ecs.amazonaws.com'] },
16
+ 'Action' => ['sts:AssumeRole']
17
+ }]
18
+ }
19
+
20
+ AssumeRolePolicyDocument role_policy_doc
21
+ Path '/'
22
+ Policies [
23
+ {
24
+ 'PolicyName' => 'ecs-service',
25
+ 'PolicyDocument' => {
26
+ 'Version' => '2012-10-17',
27
+ 'Statement' => [{
28
+ 'Effect' => 'Allow',
29
+ 'Action' => [
30
+ 'ec2:AuthorizeSecurityGroupIngress',
31
+ 'ec2:Describe*',
32
+ 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer',
33
+ 'elasticloadbalancing:DeregisterTargets',
34
+ 'elasticloadbalancing:Describe*',
35
+ 'elasticloadbalancing:RegisterInstancesWithLoadBalancer',
36
+ 'elasticloadbalancing:RegisterTargets'
37
+ ],
38
+ 'Resource' => '*'
39
+ }]
40
+ }
41
+ }
42
+ ]
43
+ end
44
+ end
45
+
46
+ def make_ecs_cluster(name: make_default_resource_name('ECSCluster'), services: [], machine_config: {}, network:, log_retention: 30, dependencies: [])
47
+ ecs = make 'AWS::ECS::Cluster', name: name.to_s do
48
+ dependencies.each do |x|
49
+ depends_on x
50
+ end
51
+ end
52
+
53
+ volumes = []
54
+ machine_volume_locations = {}
55
+
56
+ service_number = 0
57
+
58
+ services.each do |service|
59
+ alb = service[:alb]
60
+ certificate = service[:certificate]
61
+ alb_ports = {}
62
+
63
+ service_number += 1
64
+
65
+ containers = service[:containers]
66
+ service_name = service[:name] || "Service#{service_number}"
67
+ service_count = service[:count] || 1
68
+
69
+ container_defs = containers.map do |container|
70
+ definition = {}
71
+
72
+ definition['Name'] = sluggify(container[:image]).camelize.to_s
73
+ definition['Name'] = container[:name] if container[:name]
74
+
75
+ definition['Memory'] = container[:memory] || 1024
76
+
77
+ loggroup = make 'AWS::Logs::LogGroup', name: "#{name}#{definition['Name']}Logs" do
78
+ LogGroupName "#{definition['Name'].underscore}_logs"
79
+ RetentionInDays log_retention
80
+ end
81
+
82
+ definition['LogConfiguration'] = {
83
+ 'LogDriver' => 'awslogs',
84
+ 'Options' => {
85
+ 'awslogs-group' => loggroup,
86
+ 'awslogs-region' => ref('AWS::Region')
87
+ }
88
+ }
89
+
90
+ if container[:files]
91
+ definition['MountPoints'] = container[:files].map do |file, destination|
92
+ s3_location = "container_files/#{sluggify(service_name)}/#{definition['Name']}/#{file}"
93
+ volume_name = sluggify("#{definition['Name'].underscore}_#{destination}").camelize
94
+
95
+ upload_file s3_location, File.read(file)
96
+
97
+ machine_volume_locations[s3_location] = "/opt/s3/#{s3_location}"
98
+
99
+ volumes << {
100
+ 'Name' => volume_name,
101
+ 'Host' => { 'SourcePath' => machine_volume_locations[s3_location] }
102
+ }
103
+
104
+ {
105
+ 'ContainerPath' => destination,
106
+ 'SourceVolume' => volume_name
107
+ }
108
+ end
109
+ container.delete(:files)
110
+ end
111
+
112
+ if container[:ports]
113
+ if !alb
114
+ definition['PortMappings'] = container[:ports].map do |from_port, to_port|
115
+ {
116
+ 'ContainerPort' => from_port,
117
+ 'HostPort' => to_port
118
+ }
119
+ end
120
+
121
+ else
122
+ definition['PortMappings'] = container[:ports].map do |from_port, _to_port|
123
+ {
124
+ 'ContainerPort' => from_port
125
+ }
126
+ end
127
+
128
+ container[:ports].each do |container_port, host_port|
129
+ if alb_ports[host_port.to_i]
130
+ raise "Container #{alb_ports[host_port][:name]} is already using #{host_port}"
131
+ end
132
+
133
+ alb_target = make 'AWS::ElasticLoadBalancingV2::TargetGroup', name: "#{name}#{definition['Name']}Target" do
134
+ HealthCheckIntervalSeconds 60
135
+ UnhealthyThresholdCount 10
136
+ HealthCheckPath '/'
137
+ Name "#{name}Port#{host_port}Target"
138
+ Port container_port
139
+ Protocol 'HTTP'
140
+ VpcId network[:vpc]
141
+
142
+ if container[:alb_sticky]
143
+ TargetGroupAttributes({
144
+ 'stickiness.enabled' => true,
145
+ 'stickiness.type' => 'lb_cookie'
146
+ }.map { |k, v| { Key: k, Value: v } })
147
+ container.delete(:alb_sticky)
148
+ end
149
+ end
150
+
151
+ alb_action = {
152
+ 'Type' => 'forward',
153
+ 'TargetGroupArn' => alb_target
154
+ }
155
+
156
+ if certificate
157
+ alb_listener = make 'AWS::ElasticLoadBalancingV2::Listener', name: "#{name}#{definition['Name']}Listener" do
158
+ Certificates [{ CertificateArn: certificate }]
159
+ DefaultActions [alb_action]
160
+ LoadBalancerArn alb
161
+ Port host_port
162
+ Protocol 'HTTPS'
163
+ end
164
+ else
165
+ alb_listener = make 'AWS::ElasticLoadBalancingV2::Listener', name: "#{name}#{definition['Name']}Listener" do
166
+ DefaultActions [alb_action]
167
+ LoadBalancerArn alb
168
+ Port host_port
169
+ Protocol 'HTTP'
170
+ end
171
+ end
172
+
173
+ alb_ports[host_port.to_i] = {
174
+ listener: alb_listener,
175
+ target: alb_target,
176
+ port: container_port,
177
+ name: definition['Name']
178
+ }
179
+ end
180
+
181
+ end
182
+ container.delete(:ports)
183
+ end
184
+
185
+ if container[:envvars]
186
+ definition['Environment'] = container[:envvars].map do |var_name, var_value|
187
+ {
188
+ 'Name' => var_name,
189
+ 'Value' => var_value
190
+ }
191
+ end
192
+ container.delete(:envvars)
193
+ end
194
+
195
+ container.each do |key, value|
196
+ definition[key.to_s.camelize] = value
197
+ end
198
+
199
+ definition
200
+ end
201
+
202
+ deployment_config = {
203
+ 'MaximumPercent' => 200,
204
+ 'MinimumHealthyPercent' => 50
205
+ }
206
+
207
+ ecs_task = make 'AWS::ECS::TaskDefinition', name: "#{name}#{service_name}Task" do
208
+ ContainerDefinitions container_defs
209
+ Volumes volumes
210
+ end
211
+
212
+ stack = self
213
+
214
+ ecs_service = make 'AWS::ECS::Service', name: "#{name}#{service_name}" do
215
+ alb_ports.each do |_host_port, info|
216
+ depends_on info[:listener]
217
+ end
218
+
219
+ Cluster ecs
220
+ DesiredCount service_count
221
+ TaskDefinition ecs_task
222
+ DeploymentConfiguration deployment_config
223
+
224
+ if alb_ports.keys.count != 0
225
+ Role stack.make_ecs_role
226
+ LoadBalancers alb_ports.values.map { |info|
227
+ {
228
+ 'TargetGroupArn' => info[:target],
229
+ 'ContainerPort' => info[:port],
230
+ 'ContainerName' => info[:name]
231
+ }
232
+ }
233
+ end
234
+ end
235
+ end # services
236
+
237
+ machine_config[:methods].each do |method_name|
238
+ parameters = { ecs_cluster: ecs }
239
+
240
+ method(method_name).parameters.each do |param|
241
+ if ((param[0] == :keyreq) || (param[0] == :key)) && machine_config[param[1]]
242
+ parameters[param[1]] = machine_config[param[1]]
243
+ end
244
+ end
245
+
246
+ parameters[:network] = network unless parameters[:network]
247
+
248
+ method(method_name).call(parameters) do
249
+ machine_volume_locations.each do |s3_loc, machine_loc|
250
+ mkdir File.dirname(machine_loc)
251
+ download_file s3_loc, machine_loc
252
+ end
253
+ end
254
+ end
255
+
256
+ ecs
257
+ end
258
+ end
265
259
  end