ufo 4.6.3 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/docs/_docs/extras/notification-arns.md +21 -0
- data/docs/_docs/helpers.md +6 -4
- data/docs/_docs/iam-roles.md +111 -0
- data/docs/_docs/secrets.md +112 -0
- data/docs/_docs/settings/cluster.md +7 -13
- data/docs/_includes/subnav.html +3 -0
- data/docs/_reference/ufo-deploy.md +1 -2
- data/docs/_reference/ufo-logs.md +1 -1
- data/docs/_reference/ufo-rollback.md +2 -0
- data/docs/_reference/ufo-ship.md +1 -2
- data/docs/_reference/ufo-ships.md +1 -2
- data/docs/_reference/ufo-tasks-build.md +1 -2
- data/lib/template/.secrets +3 -0
- data/lib/template/.ufo/settings.yml.tt +1 -0
- data/lib/template/.ufo/settings/cfn/default.yml.tt +27 -27
- data/lib/template/.ufo/settings/network/default.yml.tt +9 -0
- data/lib/template/.ufo/templates/fargate.json.erb +3 -0
- data/lib/template/.ufo/templates/main.json.erb +3 -0
- data/lib/template/.ufo/variables/base.rb.tt +1 -0
- data/lib/ufo.rb +2 -1
- data/lib/ufo/autoloader.rb +9 -0
- data/lib/ufo/cli.rb +3 -2
- data/lib/ufo/core.rb +1 -9
- data/lib/ufo/docker/cleaner.rb +1 -1
- data/lib/ufo/dsl.rb +6 -1
- data/lib/ufo/dsl/helper.rb +19 -37
- data/lib/ufo/dsl/helper/vars.rb +98 -0
- data/lib/ufo/dsl/outputter.rb +12 -9
- data/lib/ufo/log_group.rb +1 -0
- data/lib/ufo/role/builder.rb +66 -0
- data/lib/ufo/role/dsl.rb +21 -0
- data/lib/ufo/role/registry.rb +24 -0
- data/lib/ufo/rollback.rb +2 -1
- data/lib/ufo/setting/profile.rb +11 -7
- data/lib/ufo/setting/security_groups.rb +22 -0
- data/lib/ufo/settings.rb +20 -0
- data/lib/ufo/stack.rb +24 -24
- data/lib/ufo/stack/builder.rb +26 -0
- data/lib/ufo/stack/builder/base.rb +54 -0
- data/lib/ufo/stack/builder/conditions.rb +23 -0
- data/lib/ufo/stack/builder/outputs.rb +24 -0
- data/lib/ufo/stack/builder/parameters.rb +45 -0
- data/lib/ufo/stack/builder/resources.rb +20 -0
- data/lib/ufo/stack/builder/resources/base.rb +4 -0
- data/lib/ufo/stack/builder/resources/dns.rb +17 -0
- data/lib/ufo/stack/builder/resources/ecs.rb +63 -0
- data/lib/ufo/stack/builder/resources/elb.rb +45 -0
- data/lib/ufo/stack/builder/resources/listener.rb +42 -0
- data/lib/ufo/stack/builder/resources/listener_ssl.rb +16 -0
- data/lib/ufo/stack/builder/resources/roles/base.rb +22 -0
- data/lib/ufo/stack/builder/resources/roles/execution_role.rb +4 -0
- data/lib/ufo/stack/builder/resources/roles/task_role.rb +4 -0
- data/lib/ufo/stack/builder/resources/security_group/base.rb +4 -0
- data/lib/ufo/stack/builder/resources/security_group/ecs.rb +44 -0
- data/lib/ufo/stack/builder/resources/security_group/ecs_rule.rb +25 -0
- data/lib/ufo/stack/builder/resources/security_group/elb.rb +57 -0
- data/lib/ufo/stack/builder/resources/target_group.rb +39 -0
- data/lib/ufo/stack/builder/resources/task_definition.rb +24 -0
- data/lib/ufo/stack/builder/resources/task_definition/reconstructor.rb +49 -0
- data/lib/ufo/stack/context.rb +41 -48
- data/lib/ufo/stack/custom_properties.rb +59 -0
- data/lib/ufo/stack/helper.rb +2 -5
- data/lib/ufo/stack/template_body.rb +13 -0
- data/lib/ufo/task.rb +2 -7
- data/lib/ufo/tasks.rb +1 -1
- data/lib/ufo/tasks/builder.rb +0 -1
- data/lib/ufo/template_scope.rb +1 -66
- data/lib/ufo/utils/squeezer.rb +24 -0
- data/lib/ufo/version.rb +1 -1
- data/spec/fixtures/iam_roles/task_role.rb +17 -0
- data/spec/lib/role/builder_spec.rb +67 -0
- data/spec/lib/role/dsl_spec.rb +12 -0
- data/ufo.gemspec +1 -0
- metadata +57 -3
- data/lib/cfn/stack.yml +0 -283
data/lib/ufo/stack/context.rb
CHANGED
@@ -2,13 +2,15 @@ class Ufo::Stack
|
|
2
2
|
class Context
|
3
3
|
extend Memoist
|
4
4
|
include Helper
|
5
|
+
include Ufo::Settings
|
5
6
|
|
7
|
+
attr_reader :stack_name
|
6
8
|
def initialize(options)
|
7
9
|
@options = options
|
8
10
|
@task_definition = options[:task_definition]
|
9
11
|
@service = options[:service]
|
10
12
|
# no need to adjust @cluster or @stack_name because it was adjusted in Stack#initialize
|
11
|
-
@cluster = options[:cluster]
|
13
|
+
@cluster = options[:cluster].dup # Thor options are frozen, we thaw it because CustomProperties#substitute_variables does a sub!
|
12
14
|
@stack_name = options[:stack_name]
|
13
15
|
|
14
16
|
@stack = options[:stack]
|
@@ -20,36 +22,44 @@ class Ufo::Stack
|
|
20
22
|
# Add additional variable to scope for CloudFormation template.
|
21
23
|
# Dirties the scope but needed.
|
22
24
|
vars = {
|
25
|
+
service: @service,
|
23
26
|
cluster: @cluster,
|
24
27
|
stack_name: @stack_name, # used in custom_properties
|
25
28
|
container: container,
|
29
|
+
# to reconstruct TaskDefinition in the CloudFormation template
|
30
|
+
task_definition: @task_definition,
|
31
|
+
rollback_definition_arn: @options[:rollback_definition_arn],
|
26
32
|
# elb options remember that their 'state'
|
27
33
|
create_elb: create_elb?, # helps set Ecs DependsOn
|
28
34
|
elb_type: elb_type,
|
29
35
|
subnet_mappings: subnet_mappings,
|
30
|
-
create_route53: create_elb? &&
|
36
|
+
create_route53: create_elb? && has_dns_name?,
|
31
37
|
default_target_group_protocol: default_target_group_protocol,
|
32
38
|
default_listener_protocol: default_listener_protocol,
|
33
39
|
default_listener_ssl_protocol: default_listener_ssl_protocol,
|
34
40
|
create_listener_ssl: create_listener_ssl?,
|
35
41
|
}
|
36
|
-
|
37
|
-
# pp vars
|
42
|
+
|
38
43
|
scope.assign_instance_variables(vars)
|
39
44
|
scope
|
40
45
|
end
|
41
46
|
memoize :scope
|
42
47
|
|
48
|
+
def has_dns_name?
|
49
|
+
cfn.dig(:Dns, :Name) || cfn.dig(:dns, :name) # backwards compatiblity
|
50
|
+
end
|
51
|
+
|
43
52
|
def default_target_group_protocol
|
44
53
|
return 'TCP' if elb_type == 'network'
|
45
54
|
'HTTP'
|
46
55
|
end
|
47
56
|
|
48
57
|
def default_listener_protocol
|
58
|
+
port = cfn.dig(:Listener, :Port) || cfn.dig(:listener, :port) # backwards compatiblity
|
49
59
|
if elb_type == 'network'
|
50
|
-
|
60
|
+
port == 443 ? 'TLS' : 'TCP'
|
51
61
|
else
|
52
|
-
|
62
|
+
port == 443 ? 'HTTPS' : 'HTTP'
|
53
63
|
end
|
54
64
|
end
|
55
65
|
|
@@ -59,32 +69,8 @@ class Ufo::Stack
|
|
59
69
|
|
60
70
|
# if the configuration is set to anything then enable it
|
61
71
|
def create_listener_ssl?
|
62
|
-
cfn
|
63
|
-
end
|
64
|
-
|
65
|
-
def container
|
66
|
-
resp = ecs.describe_task_definition(task_definition: @task_definition)
|
67
|
-
task_definition = resp.task_definition
|
68
|
-
|
69
|
-
container_def = task_definition["container_definitions"].first
|
70
|
-
requires_compatibilities = task_definition["requires_compatibilities"]
|
71
|
-
fargate = requires_compatibilities && requires_compatibilities == ["FARGATE"]
|
72
|
-
network_mode = task_definition["network_mode"]
|
73
|
-
|
74
|
-
mappings = container_def["port_mappings"] || []
|
75
|
-
unless mappings.empty?
|
76
|
-
port = mappings.first["container_port"]
|
77
|
-
end
|
78
|
-
|
79
|
-
result = {
|
80
|
-
name: container_def["name"],
|
81
|
-
fargate: fargate,
|
82
|
-
network_mode: network_mode, # awsvpc, bridge, etc
|
83
|
-
}
|
84
|
-
result[:port] = port if port
|
85
|
-
result
|
72
|
+
cfn.dig(:ListenerSsl, :Port) || cfn.dig(:listener_ssl, :port) # backwards compatiblity
|
86
73
|
end
|
87
|
-
memoize :container
|
88
74
|
|
89
75
|
def create_elb?
|
90
76
|
create_elb, _ = elb_options
|
@@ -135,6 +121,29 @@ class Ufo::Stack
|
|
135
121
|
[create_elb, elb_target_group]
|
136
122
|
end
|
137
123
|
|
124
|
+
def container
|
125
|
+
task_definition = Builder::Resources::TaskDefinition::Reconstructor.new(@task_definition, @options[:rollback]).reconstruct
|
126
|
+
|
127
|
+
container_def = task_definition["ContainerDefinitions"].first
|
128
|
+
requires_compatibilities = task_definition["RequiresCompatibilities"]
|
129
|
+
fargate = requires_compatibilities && requires_compatibilities == ["FARGATE"]
|
130
|
+
network_mode = task_definition["NetworkMode"]
|
131
|
+
|
132
|
+
mappings = container_def["PortMappings"] || []
|
133
|
+
unless mappings.empty?
|
134
|
+
port = mappings.first["ContainerPort"]
|
135
|
+
end
|
136
|
+
|
137
|
+
result = {
|
138
|
+
name: container_def["Name"],
|
139
|
+
fargate: fargate,
|
140
|
+
network_mode: network_mode, # awsvpc, bridge, etc
|
141
|
+
}
|
142
|
+
result[:port] = port if port
|
143
|
+
result
|
144
|
+
end
|
145
|
+
memoize :container
|
146
|
+
|
138
147
|
def get_parameter_value(stack, key)
|
139
148
|
param = stack.parameters.find do |p|
|
140
149
|
p.parameter_key == key
|
@@ -188,10 +197,8 @@ class Ufo::Stack
|
|
188
197
|
|
189
198
|
def build_subnet_mappings!(allocations)
|
190
199
|
unless allocations.size == network[:elb_subnets].size
|
191
|
-
# puts "caller:".color(:cyan)
|
192
|
-
# puts caller
|
193
200
|
puts "ERROR: The allocation_ids must match in length to the subnets.".color(:red)
|
194
|
-
puts "Please double check that .ufo/settings/network/#{settings
|
201
|
+
puts "Please double check that .ufo/settings/network/#{settings.network_profile} has the same number of subnets as the eip allocation ids are you specifying."
|
195
202
|
subnets = network[:elb_subnets]
|
196
203
|
puts "Conigured subnets: #{subnets.inspect}"
|
197
204
|
puts "Specified allocation ids: #{allocations.inspect}"
|
@@ -242,19 +249,5 @@ class Ufo::Stack
|
|
242
249
|
end
|
243
250
|
memoize :elb_type
|
244
251
|
|
245
|
-
def network
|
246
|
-
Ufo::Setting::Profile.new(:network, settings[:network_profile]).data
|
247
|
-
end
|
248
|
-
memoize :network
|
249
|
-
|
250
|
-
def cfn
|
251
|
-
Ufo::Setting::Profile.new(:cfn, settings[:cfn_profile]).data
|
252
|
-
end
|
253
|
-
memoize :cfn
|
254
|
-
|
255
|
-
def settings
|
256
|
-
Ufo.settings
|
257
|
-
end
|
258
|
-
|
259
252
|
end
|
260
253
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Ufo::Stack
|
2
|
+
class CustomProperties
|
3
|
+
include Ufo::Settings
|
4
|
+
|
5
|
+
def initialize(template, stack_name)
|
6
|
+
@template, @stack_name = template, stack_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def apply
|
10
|
+
customizations = camelize(cfn)
|
11
|
+
@template["Resources"].each do |logical_id, attrs|
|
12
|
+
custom_props = customizations[logical_id]
|
13
|
+
next unless custom_props
|
14
|
+
attrs["Properties"].deeper_merge!(custom_props, {overwrite_arrays: true})
|
15
|
+
end
|
16
|
+
|
17
|
+
substitute_variables!(@template["Resources"])
|
18
|
+
@template
|
19
|
+
end
|
20
|
+
|
21
|
+
# Keep backward compatiablity but encouraging CamelCase now because in the ufo init generator
|
22
|
+
# the .ufo/settings/cfn/default.yml is now CamelCase
|
23
|
+
def camelize(properties)
|
24
|
+
if ENV['UFO_CAMELIZE'] == '0' || settings[:auto_camelize] == false # provide a way to quickly test full camelize disable
|
25
|
+
return properties.deep_stringify_keys
|
26
|
+
end
|
27
|
+
|
28
|
+
# transform keys: camelize
|
29
|
+
properties.deep_stringify_keys.deep_transform_keys do |key|
|
30
|
+
if key == key.upcase # trying to generalize special rule for dns.TTL
|
31
|
+
key # leave key alone if key is already in all upcase
|
32
|
+
else
|
33
|
+
key.camelize
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Substitute special variables that cannot be baked into the template
|
39
|
+
# because they are dynamically assigned. Only one special variable:
|
40
|
+
#
|
41
|
+
# {stack_name}
|
42
|
+
def substitute_variables!(properties)
|
43
|
+
# transform values and substitute for special values
|
44
|
+
# https://stackoverflow.com/questions/34595142/process-nested-hash-to-convert-all-values-to-strings
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
# "{stack_name}.stag.boltops.com." => development-demo-web.stag.boltops.com.
|
48
|
+
# "{stack_name}.stag.boltops.com." => dev-demo-web-2.stag.boltops.com.
|
49
|
+
properties.deep_merge(properties) do |_,_,v|
|
50
|
+
if v.is_a?(String)
|
51
|
+
v.sub!('{stack_name}', @stack_name) # need shebang, updating in-place
|
52
|
+
else
|
53
|
+
v
|
54
|
+
end
|
55
|
+
end
|
56
|
+
properties
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/ufo/stack/helper.rb
CHANGED
@@ -2,6 +2,7 @@ class Ufo::Stack
|
|
2
2
|
module Helper
|
3
3
|
include Ufo::AwsService
|
4
4
|
include Ufo::Util
|
5
|
+
include Ufo::Settings
|
5
6
|
extend Memoist
|
6
7
|
|
7
8
|
def find_stack(stack_name)
|
@@ -34,15 +35,11 @@ class Ufo::Stack
|
|
34
35
|
when "append_nothing", "prepend_nothing"
|
35
36
|
[service, Ufo.env_extra]
|
36
37
|
else # new default. ufo v4.5 and above
|
37
|
-
[service, Ufo.env, Ufo.env_extra]
|
38
|
+
[service, Ufo.env.to_s, Ufo.env_extra]
|
38
39
|
end
|
39
40
|
parts.reject {|x| x==''}.compact.join('-') # stack_name
|
40
41
|
end
|
41
42
|
|
42
|
-
def cfn
|
43
|
-
Ufo::Setting::Profile.new(:cfn, settings[:cfn_profile]).data
|
44
|
-
end
|
45
|
-
|
46
43
|
def status
|
47
44
|
Status.new(@stack_name)
|
48
45
|
end
|
data/lib/ufo/task.rb
CHANGED
@@ -2,8 +2,9 @@ module Ufo
|
|
2
2
|
class Task < Base
|
3
3
|
extend Memoist
|
4
4
|
|
5
|
-
include Util
|
6
5
|
include AwsService
|
6
|
+
include Ufo::Settings
|
7
|
+
include Util
|
7
8
|
|
8
9
|
def initialize(task_definition, options)
|
9
10
|
@task_definition = task_definition
|
@@ -139,12 +140,6 @@ module Ufo
|
|
139
140
|
options
|
140
141
|
end
|
141
142
|
|
142
|
-
def network
|
143
|
-
settings = Ufo.settings
|
144
|
-
Setting::Profile.new(:network, settings[:network_profile]).data
|
145
|
-
end
|
146
|
-
memoize :network
|
147
|
-
|
148
143
|
def cloudwatch_info(task_arn)
|
149
144
|
config = container_definition[:log_configuration]
|
150
145
|
container_name = container_definition[:name]
|
data/lib/ufo/tasks.rb
CHANGED
@@ -2,7 +2,7 @@ module Ufo
|
|
2
2
|
class Tasks < Command
|
3
3
|
desc "build", "Build task definitions."
|
4
4
|
long_desc Help.text("tasks:build")
|
5
|
-
option :
|
5
|
+
option :image_override, desc: "Override image in task definition for quick testing"
|
6
6
|
def build
|
7
7
|
Tasks::Builder.new(options).build
|
8
8
|
end
|
data/lib/ufo/tasks/builder.rb
CHANGED
@@ -6,7 +6,6 @@ module Ufo
|
|
6
6
|
# build and register task definitions. There is little point of running them independently
|
7
7
|
# This method helps us do that.
|
8
8
|
build(options)
|
9
|
-
Tasks::Register.register(task_definition, options)
|
10
9
|
end
|
11
10
|
|
12
11
|
# ship: build and registers task definitions together
|
data/lib/ufo/template_scope.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Ufo
|
2
2
|
class TemplateScope
|
3
3
|
extend Memoist
|
4
|
+
include Ufo::Settings
|
4
5
|
|
5
6
|
attr_reader :helper
|
6
7
|
attr_reader :task_definition_name
|
@@ -44,72 +45,6 @@ module Ufo
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
def network
|
48
|
-
Ufo::Setting::Profile.new(:network, settings[:network_profile]).data
|
49
|
-
end
|
50
|
-
memoize :network
|
51
|
-
|
52
|
-
def cfn
|
53
|
-
Ufo::Setting::Profile.new(:cfn, settings[:cfn_profile]).data
|
54
|
-
end
|
55
|
-
memoize :cfn
|
56
|
-
|
57
|
-
def settings
|
58
|
-
Ufo.settings
|
59
|
-
end
|
60
|
-
|
61
|
-
def custom_properties(resource)
|
62
|
-
resource = resource.to_s.underscore
|
63
|
-
properties = cfn[resource.to_sym]
|
64
|
-
return unless properties
|
65
|
-
|
66
|
-
# transform keys: camelize
|
67
|
-
properties = properties.deep_stringify_keys.deep_transform_keys do |key|
|
68
|
-
if key == key.upcase # trying to generalize special rule for dns.TTL
|
69
|
-
key # leave key alone if key is already in all upcase
|
70
|
-
else
|
71
|
-
key.camelize
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
substitute_variables!(properties)
|
76
|
-
|
77
|
-
yaml = YAML.dump(properties)
|
78
|
-
# add spaces in front on each line
|
79
|
-
yaml.split("\n")[1..-1].map do |line|
|
80
|
-
" #{line}"
|
81
|
-
end.join("\n") + "\n"
|
82
|
-
end
|
83
|
-
|
84
|
-
# Substitute special variables that cannot be baked into the template
|
85
|
-
# because they are dynamically assigned. Only one special variable:
|
86
|
-
#
|
87
|
-
# {stack_name}
|
88
|
-
def substitute_variables!(properties)
|
89
|
-
# transform values and substitute for special values
|
90
|
-
# https://stackoverflow.com/questions/34595142/process-nested-hash-to-convert-all-values-to-strings
|
91
|
-
#
|
92
|
-
# Examples:
|
93
|
-
# "{stack_name}.stag.boltops.com." => development-demo-web.stag.boltops.com.
|
94
|
-
# "{stack_name}.stag.boltops.com." => dev-demo-web-2.stag.boltops.com.
|
95
|
-
properties.deep_merge(properties) do |_,_,v|
|
96
|
-
if v.is_a?(String)
|
97
|
-
v.sub!('{stack_name}', @stack_name) # unsure why need shebang, but it works
|
98
|
-
else
|
99
|
-
v
|
100
|
-
end
|
101
|
-
end
|
102
|
-
properties
|
103
|
-
end
|
104
|
-
|
105
|
-
def default_target_group_protocol
|
106
|
-
default_elb_protocol
|
107
|
-
end
|
108
|
-
|
109
|
-
def default_elb_protocol
|
110
|
-
@elb_type == "application" ? "HTTP" : "TCP"
|
111
|
-
end
|
112
|
-
|
113
48
|
def pretty_name?
|
114
49
|
# env variable takes highest precedence
|
115
50
|
if ENV["STATIC_NAME"]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ufo::Utils
|
2
|
+
class Squeezer
|
3
|
+
def initialize(data)
|
4
|
+
@data = data
|
5
|
+
end
|
6
|
+
|
7
|
+
def squeeze(new_data=nil)
|
8
|
+
data = new_data.nil? ? @data : new_data
|
9
|
+
|
10
|
+
case data
|
11
|
+
when Array
|
12
|
+
data.map! { |v| squeeze(v) }
|
13
|
+
when Hash
|
14
|
+
data.each_with_object({}) do |(k,v), squeezed|
|
15
|
+
# only remove nil and empty Array values within Hash structures
|
16
|
+
squeezed[k] = squeeze(v) unless v.nil? || v.is_a?(Array) && v.empty?
|
17
|
+
squeezed
|
18
|
+
end
|
19
|
+
else
|
20
|
+
data # do not transform
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/ufo/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
iam_policy("AmazonS3ReadOnlyAccess",
|
2
|
+
Action: [
|
3
|
+
"s3:Get*",
|
4
|
+
"s3:List*"
|
5
|
+
],
|
6
|
+
Effect: "Allow",
|
7
|
+
Resource: "*"
|
8
|
+
)
|
9
|
+
iam_policy("CloudwatchWrite",
|
10
|
+
Action: [
|
11
|
+
"cloudwatch:PutMetricData",
|
12
|
+
],
|
13
|
+
Effect: "Allow",
|
14
|
+
Resource: "*"
|
15
|
+
)
|
16
|
+
|
17
|
+
managed_iam_policy("AmazonS3ReadOnlyAccess", "AmazonEC2ReadOnlyAccess")
|
@@ -0,0 +1,67 @@
|
|
1
|
+
describe Ufo::Role::Builder do
|
2
|
+
let(:builder) { described_class.new(role_type) }
|
3
|
+
let(:role_type) { "task_role" }
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Ufo::Role::Registry.register_policy("task_role",
|
7
|
+
"AmazonS3ReadOnlyAccess",
|
8
|
+
{:Action=>["s3:Get*", "s3:List*"], :Effect=>"Allow", :Resource=>"*"}
|
9
|
+
)
|
10
|
+
Ufo::Role::Registry.register_policy("task_role",
|
11
|
+
"CloudwatchWrite",
|
12
|
+
{:Action=>["cloudwatch:PutMetricData"], :Effect=>"Allow", :Resource=>"*"}
|
13
|
+
)
|
14
|
+
# Called twice on purpose to show that duplicated items in the set wont create doubles.
|
15
|
+
# This allows the DSL evaluate to be ran multiple times.
|
16
|
+
Ufo::Role::Registry.register_policy("task_role",
|
17
|
+
"CloudwatchWrite",
|
18
|
+
{:Action=>["cloudwatch:PutMetricData"], :Effect=>"Allow", :Resource=>"*"}
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
Ufo::Role::Registry.register_managed_policy("task_role",
|
23
|
+
"AmazonS3ReadOnlyAccess", "AmazonEC2ReadOnlyAccess"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
context "build" do
|
28
|
+
it "builds role" do
|
29
|
+
resource = builder.build
|
30
|
+
expected = <<YAML
|
31
|
+
---
|
32
|
+
Type: AWS::IAM::Role
|
33
|
+
Properties:
|
34
|
+
AssumeRolePolicyDocument:
|
35
|
+
Version: '2012-10-17'
|
36
|
+
Statement:
|
37
|
+
- Effect: Allow
|
38
|
+
Principal:
|
39
|
+
Service: ecs-tasks.amazonaws.com
|
40
|
+
Action: sts:AssumeRole
|
41
|
+
Policies:
|
42
|
+
- PolicyName: AmazonS3ReadOnlyAccess
|
43
|
+
PolicyDocument:
|
44
|
+
Version: '2012-10-17'
|
45
|
+
Statement:
|
46
|
+
- Action:
|
47
|
+
- s3:Get*
|
48
|
+
- s3:List*
|
49
|
+
Effect: Allow
|
50
|
+
Resource: "*"
|
51
|
+
- PolicyName: CloudwatchWrite
|
52
|
+
PolicyDocument:
|
53
|
+
Version: '2012-10-17'
|
54
|
+
Statement:
|
55
|
+
- Action:
|
56
|
+
- cloudwatch:PutMetricData
|
57
|
+
Effect: Allow
|
58
|
+
Resource: "*"
|
59
|
+
ManagedPolicyArns:
|
60
|
+
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
61
|
+
- arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
|
62
|
+
YAML
|
63
|
+
yaml = YAML.dump(resource)
|
64
|
+
expect(yaml).to eq(expected)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|