ufo 4.6.3 → 5.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/docs/_docs/conventions.md +1 -1
- data/docs/_docs/extras/codebuild-iam-role.md +1 -1
- data/docs/_docs/extras/dockerfile-erb.md +1 -1
- data/docs/_docs/extras/ecs-network-mode.md +1 -1
- data/docs/_docs/extras/load-balancer.md +1 -1
- data/docs/_docs/extras/minimal-deploy-iam.md +1 -1
- data/docs/_docs/extras/notification-arns.md +21 -0
- data/docs/_docs/extras/redirection-support.md +9 -9
- data/docs/_docs/extras/route53-support.md +4 -4
- data/docs/_docs/extras/security-groups.md +1 -1
- data/docs/_docs/extras/ssl-support.md +5 -5
- data/docs/_docs/faq.md +1 -1
- data/docs/_docs/helpers.md +7 -5
- data/docs/_docs/iam-roles.md +112 -0
- data/docs/_docs/install.md +0 -10
- data/docs/_docs/more/auto-completion.md +1 -1
- data/docs/_docs/more/automated-cleanup.md +1 -1
- data/docs/_docs/more/customize-cloudformation.md +1 -1
- data/docs/_docs/more/migrations.md +1 -1
- data/docs/_docs/more/run-in-pieces.md +1 -1
- data/docs/_docs/more/single-task.md +1 -1
- data/docs/_docs/more/stuck-cloudformation.md +1 -1
- data/docs/_docs/more/why-cloudformation.md +1 -1
- data/docs/_docs/next-steps.md +1 -1
- data/docs/_docs/secrets.md +135 -0
- data/docs/_docs/settings.md +10 -9
- data/docs/_docs/settings/cluster.md +7 -13
- data/docs/_docs/settings/manage-security-groups.md +24 -0
- data/docs/_docs/settings/network.md +11 -1
- data/docs/_docs/structure.md +10 -9
- data/docs/_docs/tutorial-ufo-init.md +1 -7
- data/docs/_docs/ufo-current.md +1 -1
- data/docs/_docs/ufo-env-extra.md +1 -1
- data/docs/_docs/ufo-env.md +3 -5
- data/docs/_docs/ufo-logs.md +1 -2
- data/docs/_docs/ufo-task-params.md +1 -1
- data/docs/_docs/upgrading.md +1 -1
- data/docs/_docs/upgrading/upgrade4.5.md +2 -2
- data/docs/_docs/upgrading/upgrade4.md +2 -2
- data/docs/_docs/upgrading/upgrade5.md +19 -0
- data/docs/_docs/variables.md +1 -1
- data/docs/_includes/cfn-customize.md +18 -4
- data/docs/_includes/footer.html +6 -5
- data/docs/_includes/subnav.html +3 -0
- data/docs/_reference/ufo-deploy.md +1 -2
- data/docs/_reference/ufo-init.md +14 -15
- 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/docs/articles.md +1 -1
- data/lib/template/.secrets +5 -0
- data/lib/template/.ufo/iam_roles/execution_role.rb +7 -0
- data/lib/template/.ufo/iam_roles/task_role.rb +21 -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 -1
- 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 +97 -0
- data/lib/ufo/dsl/outputter.rb +12 -9
- data/lib/ufo/ecr/auth.rb +10 -21
- data/lib/ufo/init.rb +0 -2
- 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/sequence.rb +0 -16
- data/lib/ufo/setting/profile.rb +22 -8
- 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 +71 -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/ecr_auth_spec.rb +32 -20
- data/spec/lib/role/builder_spec.rb +67 -0
- data/spec/lib/role/dsl_spec.rb +12 -0
- data/ufo.gemspec +2 -1
- metadata +66 -8
- data/lib/cfn/stack.yml +0 -283
data/lib/ufo/dsl/helper.rb
CHANGED
@@ -6,11 +6,20 @@
|
|
6
6
|
# Simply aggregates a bunch of variables that is useful for the task_definition.
|
7
7
|
module Ufo
|
8
8
|
class DSL
|
9
|
-
# provides some helperally context variables
|
10
9
|
class Helper
|
11
10
|
include Ufo::Util
|
12
11
|
extend Memoist
|
13
12
|
|
13
|
+
# Add helpers from .ufo/helpers folder
|
14
|
+
def add_project_helpers
|
15
|
+
helpers_dir = "#{Ufo.root}/.ufo/helpers"
|
16
|
+
Dir.glob("#{helpers_dir}/**/*").each do |path|
|
17
|
+
next unless File.file?(path)
|
18
|
+
klass = path.gsub(%r{.*\.ufo/helpers/},'').sub(".rb",'').camelize
|
19
|
+
self.class.send(:include, klass.constantize)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
14
23
|
##############
|
15
24
|
# helper variables
|
16
25
|
def dockerfile_port
|
@@ -27,48 +36,21 @@ module Ufo
|
|
27
36
|
|
28
37
|
#############
|
29
38
|
# helper methods
|
30
|
-
def
|
31
|
-
|
32
|
-
lines.map do |line|
|
33
|
-
key,*value = line.strip.split("=").map do |x|
|
34
|
-
remove_surrounding_quotes(x.strip)
|
35
|
-
end
|
36
|
-
value = value.join('=')
|
37
|
-
{
|
38
|
-
name: key,
|
39
|
-
value: value,
|
40
|
-
}
|
41
|
-
end
|
39
|
+
def env(text)
|
40
|
+
Vars.new(text: text).env
|
42
41
|
end
|
42
|
+
alias_method :env_vars, :env
|
43
43
|
|
44
|
-
def
|
45
|
-
|
46
|
-
s.sub(/^["]/, '').gsub(/["]$/,'') # remove surrounding double quotes
|
47
|
-
elsif s =~ /^'/ && s =~ /'$/
|
48
|
-
s.sub(/^[']/, '').gsub(/[']$/,'') # remove surrounding single quotes
|
49
|
-
else
|
50
|
-
s
|
51
|
-
end
|
44
|
+
def env_file(path)
|
45
|
+
Vars.new(file: path).env
|
52
46
|
end
|
53
47
|
|
54
|
-
def
|
55
|
-
|
56
|
-
# remove comment at the end of the line
|
57
|
-
lines.map! { |l| l.sub(/\s+#.*/,'').strip }
|
58
|
-
# filter out commented lines
|
59
|
-
lines = lines.reject { |l| l =~ /(^|\s)#/i }
|
60
|
-
# filter out empty lines
|
61
|
-
lines = lines.reject { |l| l.strip.empty? }
|
48
|
+
def secrets(text)
|
49
|
+
Vars.new(text: text).secrets
|
62
50
|
end
|
63
51
|
|
64
|
-
def
|
65
|
-
|
66
|
-
unless File.exist?(full_path)
|
67
|
-
puts "The #{full_path} env file could not be found. Are you sure it exists?"
|
68
|
-
exit 1
|
69
|
-
end
|
70
|
-
text = IO.read(full_path)
|
71
|
-
env_vars(text)
|
52
|
+
def secrets_file(path)
|
53
|
+
Vars.new(file: path).secrets
|
72
54
|
end
|
73
55
|
|
74
56
|
def current_region
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "aws_data"
|
2
|
+
|
3
|
+
class Ufo::DSL::Helper
|
4
|
+
class Vars
|
5
|
+
extend Memoist
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
# use either file or text. text takes higher precedence
|
9
|
+
@file = options[:file]
|
10
|
+
@text = options[:text]
|
11
|
+
end
|
12
|
+
|
13
|
+
def content
|
14
|
+
@text || read(@file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(path)
|
18
|
+
full_path = "#{Ufo.root}/#{path}"
|
19
|
+
unless File.exist?(full_path)
|
20
|
+
puts "The #{full_path} env file could not be found. Are you sure it exists?"
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
IO.read(full_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def env
|
27
|
+
lines = filtered_lines(content)
|
28
|
+
lines.map do |line|
|
29
|
+
key,*value = line.strip.split("=").map do |x|
|
30
|
+
remove_surrounding_quotes(x.strip)
|
31
|
+
end
|
32
|
+
value = value.join('=')
|
33
|
+
{
|
34
|
+
name: key,
|
35
|
+
value: value,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def secrets
|
41
|
+
secrets = env
|
42
|
+
secrets.map do |item|
|
43
|
+
value = item.delete(:value)
|
44
|
+
item[:valueFrom] = substitute(expand_secret(value))
|
45
|
+
end
|
46
|
+
secrets
|
47
|
+
end
|
48
|
+
|
49
|
+
def expand_secret(value)
|
50
|
+
case value
|
51
|
+
when /^ssm:/i
|
52
|
+
value.sub(/^ssm:/i, "arn:aws:ssm:#{region}:#{account}:parameter/")
|
53
|
+
when /^secretsmanager:/i
|
54
|
+
value.sub(/^secretsmanager:/i, "arn:aws:secretsmanager:#{region}:#{account}:secret:")
|
55
|
+
else
|
56
|
+
value # assume full arn has been passed
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def substitute(value)
|
61
|
+
value.gsub(":UFO_ENV", Ufo.env)
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_surrounding_quotes(s)
|
65
|
+
if s =~ /^"/ && s =~ /"$/
|
66
|
+
s.sub(/^["]/, '').gsub(/["]$/,'') # remove surrounding double quotes
|
67
|
+
elsif s =~ /^'/ && s =~ /'$/
|
68
|
+
s.sub(/^[']/, '').gsub(/[']$/,'') # remove surrounding single quotes
|
69
|
+
else
|
70
|
+
s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def filtered_lines(content)
|
75
|
+
lines = content.split("\n")
|
76
|
+
# remove comment at the end of the line
|
77
|
+
lines.map! { |l| l.sub(/\s+#.*/,'').strip }
|
78
|
+
# filter out commented lines
|
79
|
+
lines = lines.reject { |l| l =~ /(^|\s)#/i }
|
80
|
+
# filter out empty lines
|
81
|
+
lines = lines.reject { |l| l.strip.empty? }
|
82
|
+
end
|
83
|
+
|
84
|
+
def aws_data
|
85
|
+
AwsData.new
|
86
|
+
end
|
87
|
+
memoize :aws_data
|
88
|
+
|
89
|
+
def region
|
90
|
+
aws_data.region
|
91
|
+
end
|
92
|
+
|
93
|
+
def account
|
94
|
+
aws_data.account
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/ufo/dsl/outputter.rb
CHANGED
@@ -5,7 +5,6 @@ module Ufo
|
|
5
5
|
@name = name
|
6
6
|
@erb_result = erb_result
|
7
7
|
@options = options
|
8
|
-
@pretty = options[:pretty].nil? ? true : options[:pretty]
|
9
8
|
end
|
10
9
|
|
11
10
|
def write
|
@@ -16,25 +15,29 @@ module Ufo
|
|
16
15
|
path = "#{output_path}/#{@name}.json".sub(/^\.\//,'')
|
17
16
|
puts " #{path}" unless @options[:quiet]
|
18
17
|
validate(@erb_result, path)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
File.open(path, 'w') {|f| f.write(
|
18
|
+
data = JSON.parse(@erb_result)
|
19
|
+
override_image(data)
|
20
|
+
json = JSON.pretty_generate(data)
|
21
|
+
File.open(path, 'w') {|f| f.write(json) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def override_image(data)
|
25
|
+
return data unless @options[:image_override]
|
26
|
+
data["containerDefinitions"].each do |container_definition|
|
27
|
+
container_definition["image"] = @options[:image_override]
|
28
|
+
end
|
23
29
|
end
|
24
30
|
|
25
31
|
def validate(json, path)
|
26
32
|
begin
|
27
33
|
JSON.parse(json)
|
28
34
|
rescue JSON::ParserError => e
|
35
|
+
puts "#{e.class}: #{e.message}"
|
29
36
|
puts "Invalid json. Output written to #{path} for debugging".color(:red)
|
30
37
|
File.open(path, 'w') {|f| f.write(json) }
|
31
38
|
exit 1
|
32
39
|
end
|
33
40
|
end
|
34
|
-
|
35
|
-
def output_json(json)
|
36
|
-
@options[:pretty] ? JSON.pretty_generate(JSON.parse(json)) : json
|
37
|
-
end
|
38
41
|
end
|
39
42
|
end
|
40
43
|
end
|
data/lib/ufo/ecr/auth.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
=begin
|
2
4
|
Normally, you must authorized to AWS ECR to push to their registry with:
|
3
5
|
|
@@ -27,19 +29,15 @@ module Ufo
|
|
27
29
|
return unless ecr_image?
|
28
30
|
|
29
31
|
auth_token = fetch_auth_token
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
username, password = Base64.decode64(auth_token).split(':')
|
33
|
+
|
34
|
+
command = "docker login -u #{username} --password-stdin #{@repo_domain}"
|
35
|
+
puts "=> #{command}".color(:green)
|
36
|
+
*, status = Open3.capture3(command, stdin_data: password)
|
37
|
+
unless status.success?
|
38
|
+
puts "ERROR: The docker failed to login.".color(:red)
|
39
|
+
exit 1
|
35
40
|
end
|
36
|
-
|
37
|
-
# Handle legacy docker clients that still have old format with https://
|
38
|
-
legacy_entry = "https://#{@repo_domain}"
|
39
|
-
data["auths"][legacy_entry] = {auth: auth_token}
|
40
|
-
|
41
|
-
ensure_dotdocker_exists
|
42
|
-
IO.write(docker_config, JSON.pretty_generate(data))
|
43
41
|
end
|
44
42
|
|
45
43
|
def ecr_image?
|
@@ -50,14 +48,5 @@ module Ufo
|
|
50
48
|
ecr.get_authorization_token.authorization_data.first.authorization_token
|
51
49
|
end
|
52
50
|
|
53
|
-
def docker_config
|
54
|
-
"#{ENV['HOME']}/.docker/config.json"
|
55
|
-
end
|
56
|
-
|
57
|
-
def ensure_dotdocker_exists
|
58
|
-
dirname = File.dirname(docker_config)
|
59
|
-
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
|
60
|
-
end
|
61
|
-
|
62
51
|
end
|
63
52
|
end
|
data/lib/ufo/init.rb
CHANGED
@@ -9,7 +9,6 @@ module Ufo
|
|
9
9
|
[:image, required: true, desc: "Docker image name without the tag. Example: tongueroo/demo-ufo. Configures ufo/settings.yml"],
|
10
10
|
[:app, desc: "App name. Preferably one word. Used in the generated ufo/task_definitions.rb. If not specified then the app name is inferred as the folder name."],
|
11
11
|
[:launch_type, default: "ec2", desc: "ec2 or fargate."],
|
12
|
-
[:execution_role_arn, desc: "execution role arn used by tasks, required for fargate."],
|
13
12
|
[:template, desc: "Custom template to use."],
|
14
13
|
[:template_mode, desc: "Template mode: replace or additive."],
|
15
14
|
[:vpc_id, desc: "Vpc id. For settings/network/default.yml."],
|
@@ -56,7 +55,6 @@ module Ufo
|
|
56
55
|
# map variables
|
57
56
|
@app = options[:app] || inferred_app
|
58
57
|
@image = options[:image]
|
59
|
-
@execution_role_arn_input = get_execution_role_arn_input
|
60
58
|
# copy the files
|
61
59
|
puts "Setting up ufo project..."
|
62
60
|
exclude_pattern = File.exist?("#{Ufo.root}/Dockerfile") ?
|
data/lib/ufo/log_group.rb
CHANGED
@@ -11,6 +11,7 @@ module Ufo
|
|
11
11
|
def create
|
12
12
|
puts "Ensuring log group for #{@task_definition.color(:green)} task definition exists"
|
13
13
|
return if @options[:noop]
|
14
|
+
return if @options[:rollback] # dont need to create log group because previously deployed
|
14
15
|
|
15
16
|
Ufo.check_task_definition!(@task_definition)
|
16
17
|
task_def = JSON.load(IO.read(task_def_path))
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Ufo::Role
|
2
|
+
class Builder
|
3
|
+
def initialize(role_type)
|
4
|
+
@role_type = role_type
|
5
|
+
end
|
6
|
+
|
7
|
+
def build
|
8
|
+
resource(policies, managed_policy_arns)
|
9
|
+
end
|
10
|
+
|
11
|
+
def build?
|
12
|
+
!!(policies || managed_policy_arns)
|
13
|
+
end
|
14
|
+
|
15
|
+
def policies
|
16
|
+
items = Registry.policies[@role_type] # Array of Arrays
|
17
|
+
return unless items && !items.empty?
|
18
|
+
|
19
|
+
items.map do |item|
|
20
|
+
policy_name, statements = item # first element has policy name, second element has statements
|
21
|
+
{
|
22
|
+
PolicyName: policy_name,
|
23
|
+
PolicyDocument: {
|
24
|
+
Version: "2012-10-17",
|
25
|
+
Statement: statements
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def managed_policy_arns
|
32
|
+
items = Registry.managed_policies[@role_type] # Array of Arrays
|
33
|
+
return unless items && !items.empty?
|
34
|
+
|
35
|
+
items.map do |item|
|
36
|
+
item.include?('iam::aws:policy') ? item : "arn:aws:iam::aws:policy/#{item}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def resource(policies, managed_policy_arns)
|
41
|
+
properties = {
|
42
|
+
AssumeRolePolicyDocument: {
|
43
|
+
Version: "2012-10-17",
|
44
|
+
Statement: [
|
45
|
+
{
|
46
|
+
Effect: "Allow",
|
47
|
+
Principal: {
|
48
|
+
Service: "ecs-tasks.amazonaws.com"
|
49
|
+
},
|
50
|
+
Action: "sts:AssumeRole"
|
51
|
+
}
|
52
|
+
]
|
53
|
+
},
|
54
|
+
}
|
55
|
+
properties[:Policies] = policies if policies
|
56
|
+
properties[:ManagedPolicyArns] = managed_policy_arns if managed_policy_arns
|
57
|
+
|
58
|
+
attrs = {
|
59
|
+
Type: "AWS::IAM::Role",
|
60
|
+
Properties: properties
|
61
|
+
}
|
62
|
+
|
63
|
+
attrs.deep_stringify_keys
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/ufo/role/dsl.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Ufo::Role
|
2
|
+
class DSL
|
3
|
+
def initialize(path)
|
4
|
+
@path = path # IE: .ufo/iam_roles/task_role.rb
|
5
|
+
end
|
6
|
+
|
7
|
+
def evaluate
|
8
|
+
instance_eval(IO.read(@path), @path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def iam_policy(policy_name, statements)
|
12
|
+
role_type = File.basename(@path).sub('.rb','') # task_role or execution_role
|
13
|
+
Registry.register_policy(role_type, policy_name, statements)
|
14
|
+
end
|
15
|
+
|
16
|
+
def managed_iam_policy(*policies)
|
17
|
+
role_type = File.basename(@path).sub('.rb','') # task_role or execution_role
|
18
|
+
Registry.register_managed_policy(role_type, policies)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module Ufo::Role
|
4
|
+
class Registry
|
5
|
+
class_attribute :policies
|
6
|
+
self.policies = {}
|
7
|
+
class_attribute :managed_policies
|
8
|
+
self.managed_policies = {}
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def register_policy(role_type, policy_name, *statements)
|
12
|
+
statements.flatten!
|
13
|
+
self.policies[role_type] ||= Set.new
|
14
|
+
self.policies[role_type].add([policy_name, statements]) # using set so DSL can safely be evaluated multiple times
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_managed_policy(role_type, *policies)
|
18
|
+
policies.flatten!
|
19
|
+
self.managed_policies[role_type] ||= Set.new
|
20
|
+
self.managed_policies[role_type].merge(policies) # using set so DSL can safely be evaluated multiple times
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/ufo/rollback.rb
CHANGED
@@ -3,7 +3,8 @@ module Ufo
|
|
3
3
|
def deploy
|
4
4
|
task_definition = normalize_version(@options[:version])
|
5
5
|
puts "Rolling back ECS service to task definition #{task_definition}"
|
6
|
-
|
6
|
+
|
7
|
+
ship = Ship.new(@service, @options.merge(task_definition: task_definition, rollback: true))
|
7
8
|
ship.deploy
|
8
9
|
end
|
9
10
|
|
data/lib/ufo/sequence.rb
CHANGED
@@ -17,22 +17,6 @@ module Ufo
|
|
17
17
|
File.basename(Dir.pwd)
|
18
18
|
end
|
19
19
|
|
20
|
-
def get_execution_role_arn_input
|
21
|
-
return @execution_role_arn if @execution_role_arn
|
22
|
-
|
23
|
-
if @options[:execution_role_arn]
|
24
|
-
@execution_role_arn = @options[:execution_role_arn]
|
25
|
-
return @execution_role_arn
|
26
|
-
end
|
27
|
-
|
28
|
-
return unless @options[:launch_type] == "fargate"
|
29
|
-
# execution role arn required for fargate
|
30
|
-
puts "For fargate ECS tasks an ECS Task Execution IAM Role is required. "
|
31
|
-
puts "More details here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html"
|
32
|
-
print "Please provide a execution role arn role for the ecs task: "
|
33
|
-
@execution_role_arn = $stdin.gets.strip
|
34
|
-
end
|
35
|
-
|
36
20
|
def override_source_paths(*paths)
|
37
21
|
# Using string with instance_eval because block doesnt have access to
|
38
22
|
# path at runtime.
|
data/lib/ufo/setting/profile.rb
CHANGED
@@ -2,22 +2,36 @@ class Ufo::Setting
|
|
2
2
|
class Profile
|
3
3
|
extend Memoist
|
4
4
|
|
5
|
-
def initialize(type, profile=
|
5
|
+
def initialize(type, profile=nil)
|
6
6
|
@type = type.to_s # cfn or network
|
7
7
|
@profile = profile
|
8
8
|
end
|
9
9
|
|
10
10
|
def data
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
names = [
|
12
|
+
@profile, # user specified
|
13
|
+
Ufo.env, # conventional based on env
|
14
|
+
"default", # fallback to default
|
15
|
+
].compact.uniq
|
16
|
+
paths = names.map { |name| "#{Ufo.root}/.ufo/settings/#{@type}/#{name}.yml" }
|
17
|
+
found = paths.find { |p| File.exist?(p) }
|
18
|
+
unless found
|
19
|
+
puts "#{@type.camelize} profile not found. Please double check that it exists. Checked paths: #{paths}"
|
14
20
|
exit 1
|
15
21
|
end
|
16
22
|
|
17
|
-
text = RenderMePretty.result(
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
text = RenderMePretty.result(found)
|
24
|
+
specific_data = YAML.load(text).deep_symbolize_keys
|
25
|
+
|
26
|
+
base = "#{Ufo.root}/.ufo/settings/#{@type}/base.yml"
|
27
|
+
base_data = if File.exist?(base)
|
28
|
+
text = RenderMePretty.result(base)
|
29
|
+
YAML.load(text).deep_symbolize_keys
|
30
|
+
else
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
|
34
|
+
base_data.deep_merge(specific_data)
|
21
35
|
end
|
22
36
|
memoize :data
|
23
37
|
end
|