ufo 3.3.2 → 3.4.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 +9 -0
- data/Gemfile.lock +9 -7
- data/docs/README.md +1 -2
- data/docs/_docs/params.md +72 -0
- data/docs/_docs/settings.md +1 -6
- data/docs/_docs/tutorial-ufo-init.md +0 -5
- data/docs/_docs/ufo-env.md +1 -1
- data/docs/_includes/subnav.html +1 -0
- data/docs/_reference/ufo-deploy.md +9 -1
- data/docs/_reference/ufo-init.md +30 -9
- data/docs/_reference/ufo-task.md +11 -12
- data/docs/_reference/ufo-upgrade3_3_to_3_4.md +23 -0
- data/docs/reference.md +1 -0
- data/lib/template/.ufo/params.yml.tt +65 -0
- data/lib/template/.ufo/settings.yml.tt +0 -4
- data/lib/template/.ufo/templates/fargate.json.erb +37 -0
- data/lib/template/.ufo/variables/base.rb.tt +15 -0
- data/lib/template/.ufo/variables/development.rb +1 -1
- data/lib/ufo.rb +3 -1
- data/lib/ufo/cli.rb +7 -3
- data/lib/ufo/default/settings.yml +0 -4
- data/lib/ufo/destroy.rb +1 -1
- data/lib/ufo/docker/builder.rb +1 -5
- data/lib/ufo/docker/cleaner.rb +1 -2
- data/lib/ufo/docker/pusher.rb +1 -5
- data/lib/ufo/dsl.rb +1 -1
- data/lib/ufo/dsl/helper.rb +3 -8
- data/lib/ufo/dsl/task_definition.rb +7 -45
- data/lib/ufo/ecr/cleaner.rb +2 -2
- data/lib/ufo/help/deploy.md +9 -1
- data/lib/ufo/help/init.md +18 -0
- data/lib/ufo/help/task.md +6 -6
- data/lib/ufo/init.rb +9 -2
- data/lib/ufo/param.rb +24 -0
- data/lib/ufo/scale.rb +1 -1
- data/lib/ufo/sequence.rb +14 -0
- data/lib/ufo/ship.rb +6 -6
- data/lib/ufo/task.rb +9 -1
- data/lib/ufo/tasks/register.rb +21 -1
- data/lib/ufo/template_scope.rb +45 -0
- data/lib/ufo/upgrade/params.yml +47 -0
- data/lib/ufo/upgrade33_to_34.rb +32 -0
- data/lib/ufo/util.rb +25 -0
- data/lib/ufo/version.rb +1 -1
- data/spec/fixtures/settings.yml +0 -4
- data/spec/lib/setting_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -1
- data/ufo.gemspec +1 -0
- metadata +25 -4
- data/lib/template/.ufo/variables/base.rb +0 -6
- data/lib/ufo/default.rb +0 -40
@@ -0,0 +1,15 @@
|
|
1
|
+
# Example ufo/variables/base.rb
|
2
|
+
# More info on how variables work: http://ufoships.com/docs/variables/
|
3
|
+
@image = helper.full_image_name # includes the git sha tongueroo/hi:ufo-[sha].
|
4
|
+
@environment = helper.env_file(".env")
|
5
|
+
<% if @options[:launch_type] == "fargate" -%>
|
6
|
+
# Ensure that the cpu and memory values are a supported combination by Fargate.
|
7
|
+
# More info: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html"
|
8
|
+
<% end -%>
|
9
|
+
@cpu = 256
|
10
|
+
@memory = 512
|
11
|
+
@memory_reservation = 256
|
12
|
+
|
13
|
+
<% if @execution_role_arn_input -%>
|
14
|
+
@execution_role_arn = "<%= @execution_role_arn_input %>"
|
15
|
+
<% end -%>
|
data/lib/ufo.rb
CHANGED
@@ -7,7 +7,6 @@ require 'render_me_pretty'
|
|
7
7
|
|
8
8
|
module Ufo
|
9
9
|
autoload :Core, 'ufo/core'
|
10
|
-
autoload :Default, 'ufo/default'
|
11
10
|
autoload :AwsService, 'ufo/aws_service'
|
12
11
|
autoload :Command, 'ufo/command'
|
13
12
|
autoload :Setting, 'ufo/setting'
|
@@ -23,6 +22,8 @@ module Ufo
|
|
23
22
|
autoload :Scale, 'ufo/scale'
|
24
23
|
autoload :LogGroup, 'ufo/log_group'
|
25
24
|
autoload :ECS, 'ufo/ecs'
|
25
|
+
autoload :Param, 'ufo/param'
|
26
|
+
autoload :TemplateScope, 'ufo/template_scope'
|
26
27
|
|
27
28
|
autoload :Docker, 'ufo/docker'
|
28
29
|
autoload :Ecr, 'ufo/ecr'
|
@@ -30,6 +31,7 @@ module Ufo
|
|
30
31
|
autoload :Completion, "ufo/completion"
|
31
32
|
autoload :Completer, "ufo/completer"
|
32
33
|
autoload :Upgrade3, "ufo/upgrade3"
|
34
|
+
autoload :Upgrade33_to_34, "ufo/upgrade33_to_34"
|
33
35
|
|
34
36
|
extend Core
|
35
37
|
end
|
data/lib/ufo/cli.rb
CHANGED
@@ -77,9 +77,9 @@ module Ufo
|
|
77
77
|
desc "task TASK_DEFINITION", "Run a one-time task."
|
78
78
|
long_desc Help.text(:task)
|
79
79
|
option :docker, type: :boolean, desc: "Enable docker build and push", default: true
|
80
|
-
option :command, type: :array, desc: "Override the command used for the container"
|
80
|
+
option :command, type: :array, aliases: 'c', desc: "Override the command used for the container"
|
81
81
|
def task(task_definition)
|
82
|
-
Docker::Builder.build(options)
|
82
|
+
Docker::Builder.build(options) if @options[:docker]
|
83
83
|
Tasks::Builder.ship(task_definition, options)
|
84
84
|
Task.new(task_definition, options).run
|
85
85
|
end
|
@@ -111,11 +111,15 @@ module Ufo
|
|
111
111
|
end
|
112
112
|
|
113
113
|
desc "upgrade3", "Upgrade from version 2 to 3."
|
114
|
-
long_desc Help.text("upgrade3")
|
115
114
|
def upgrade3
|
116
115
|
Upgrade3.new(options).run
|
117
116
|
end
|
118
117
|
|
118
|
+
desc "upgrade3_3_to_3_4", "Upgrade from version 3.3 to 3.4"
|
119
|
+
def upgrade3_3_to_3_4
|
120
|
+
Upgrade33_to_34.new(options).run
|
121
|
+
end
|
122
|
+
|
119
123
|
desc "version", "Prints version number of installed ufo."
|
120
124
|
def version
|
121
125
|
puts VERSION
|
data/lib/ufo/destroy.rb
CHANGED
data/lib/ufo/docker/builder.rb
CHANGED
@@ -51,7 +51,7 @@ class Ufo::Docker
|
|
51
51
|
|
52
52
|
# full_image - does not include the tag
|
53
53
|
def image_name
|
54
|
-
|
54
|
+
settings["image"]
|
55
55
|
end
|
56
56
|
|
57
57
|
# full_image - includes the tag
|
@@ -97,10 +97,6 @@ class Ufo::Docker
|
|
97
97
|
@git_sha.strip!
|
98
98
|
end
|
99
99
|
|
100
|
-
def setting
|
101
|
-
@setting ||= Ufo::Setting.new(Ufo.root)
|
102
|
-
end
|
103
|
-
|
104
100
|
def update_dockerfile
|
105
101
|
dockerfile = Dockerfile.new(full_image_name, @options)
|
106
102
|
dockerfile.update
|
data/lib/ufo/docker/cleaner.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module Ufo
|
2
2
|
class Docker::Cleaner
|
3
3
|
include Util
|
4
|
-
include Default
|
5
4
|
|
6
5
|
def initialize(docker_image_name, options)
|
7
6
|
# docker_image_name does not containg the tag
|
8
7
|
# Example: 123456789.dkr.ecr.us-east-1.amazonaws.com/image
|
9
8
|
@docker_image_name = docker_image_name
|
10
9
|
@options = options
|
11
|
-
@keep = options[:keep] ||
|
10
|
+
@keep = options[:keep] || settings["clean_keep"] || 3
|
12
11
|
@tag_prefix = options[:tag_prefix] || "ufo"
|
13
12
|
end
|
14
13
|
|
data/lib/ufo/docker/pusher.rb
CHANGED
data/lib/ufo/dsl.rb
CHANGED
data/lib/ufo/dsl/helper.rb
CHANGED
@@ -8,9 +8,7 @@ module Ufo
|
|
8
8
|
class DSL
|
9
9
|
# provides some helperally context variables
|
10
10
|
class Helper
|
11
|
-
|
12
|
-
@options = options
|
13
|
-
end
|
11
|
+
include Ufo::Util
|
14
12
|
|
15
13
|
##############
|
16
14
|
# helper variables
|
@@ -22,7 +20,8 @@ module Ufo
|
|
22
20
|
end
|
23
21
|
|
24
22
|
def full_image_name
|
25
|
-
|
23
|
+
# Dont need to use @options here. Helps simplify the Helper initialization.
|
24
|
+
Docker::Builder.new({}).full_image_name
|
26
25
|
end
|
27
26
|
|
28
27
|
#############
|
@@ -64,10 +63,6 @@ module Ufo
|
|
64
63
|
@current_region ||= `aws configure get region`.strip rescue 'us-east-1'
|
65
64
|
end
|
66
65
|
|
67
|
-
def setting
|
68
|
-
@setting ||= Setting.new(Ufo.root)
|
69
|
-
end
|
70
|
-
|
71
66
|
def parse_for_dockerfile_port(dockerfile_path)
|
72
67
|
lines = IO.read(dockerfile_path).split("\n")
|
73
68
|
expose_line = lines.find { |l| l =~ /^EXPOSE / }
|
@@ -17,52 +17,14 @@ module Ufo
|
|
17
17
|
@dsl.helper
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
22
|
-
instance_eval(&@block)
|
23
|
-
|
24
|
-
hash = assign_instance_variables
|
25
|
-
RenderMePretty.result(source_path, hash)
|
26
|
-
end
|
27
|
-
|
28
|
-
def assign_instance_variables
|
29
|
-
# copy over the instance variables from TaskDefinition scope to RenderMePretty's scope
|
30
|
-
hash = {}
|
31
|
-
instance_variables.each do |var|
|
32
|
-
key = var.to_s.sub('@','') # rid of the leading @
|
33
|
-
hash[key.to_sym] = instance_variable_get(var)
|
34
|
-
end
|
35
|
-
hash
|
36
|
-
end
|
37
|
-
|
38
|
-
def load_variables
|
39
|
-
load_variables_file("base")
|
40
|
-
load_variables_file(Ufo.env)
|
20
|
+
def template_scope
|
21
|
+
@template_scope ||= Ufo::TemplateScope.new(helper)
|
41
22
|
end
|
42
23
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
#
|
48
|
-
# `ufo/variables/base.rb`:
|
49
|
-
# @name = "docker-process-name"
|
50
|
-
# @image = "docker-image-name"
|
51
|
-
#
|
52
|
-
# `ufo/templates/main.json.erb`:
|
53
|
-
# {
|
54
|
-
# "containerDefinitions": [
|
55
|
-
# {
|
56
|
-
# "name": "<%= @name %>",
|
57
|
-
# "image": "<%= @image %>",
|
58
|
-
# ....
|
59
|
-
# }
|
60
|
-
#
|
61
|
-
# NOTE: Only able to make instance variables avaialble with instance_eval
|
62
|
-
# Wasnt able to make local variables available.
|
63
|
-
def load_variables_file(filename)
|
64
|
-
path = "#{Ufo.root}/.ufo/variables/#{filename}.rb"
|
65
|
-
instance_eval(IO.read(path)) if File.exist?(path)
|
24
|
+
def build
|
25
|
+
instance_eval(&@block)
|
26
|
+
vars = template_scope.assign_instance_variables
|
27
|
+
RenderMePretty.result(source_path, vars)
|
66
28
|
end
|
67
29
|
|
68
30
|
# at this point instance_eval has been called and source has possibly been called
|
@@ -75,7 +37,7 @@ module Ufo
|
|
75
37
|
if instance_variable_defined?("@#{var}")
|
76
38
|
puts "WARNING: The instance variable @#{var} is already used internally with ufo. Please name you variable another name!"
|
77
39
|
end
|
78
|
-
instance_variable_set("@#{var}", value)
|
40
|
+
template_scope.instance_variable_set("@#{var}", value)
|
79
41
|
end
|
80
42
|
end
|
81
43
|
|
data/lib/ufo/ecr/cleaner.rb
CHANGED
@@ -5,15 +5,15 @@ require "json"
|
|
5
5
|
# ufo ship app-web --cluster prod --noop
|
6
6
|
module Ufo
|
7
7
|
class Ecr::Cleaner
|
8
|
+
include Util
|
8
9
|
include AwsService
|
9
|
-
include Default
|
10
10
|
|
11
11
|
def initialize(docker_image_name, options={})
|
12
12
|
# docker_image_name does not containg the tag
|
13
13
|
# Example: 123456789.dkr.ecr.us-east-1.amazonaws.com/image
|
14
14
|
@docker_image_name = docker_image_name
|
15
15
|
@options = options
|
16
|
-
@keep = options[:ecr_keep] ||
|
16
|
+
@keep = options[:ecr_keep] || settings["ecr_keep"]
|
17
17
|
@tag_prefix = options[:tag_prefix] || "ufo"
|
18
18
|
end
|
19
19
|
|
data/lib/ufo/help/deploy.md
CHANGED
@@ -7,7 +7,15 @@ The above command does the following:
|
|
7
7
|
1. register the `.ufo/output/hi-web.json` task definition to ECS untouched.
|
8
8
|
2. deploys it to ECS by updating the service
|
9
9
|
|
10
|
-
|
10
|
+
### ufo tasks build
|
11
|
+
|
12
|
+
To regenerate a `.ufo/output/hi-web.json` definition:
|
13
|
+
|
14
|
+
ufo tasks build
|
15
|
+
|
16
|
+
### ufo ship
|
17
|
+
|
18
|
+
The `ufo deploy` command does less than the `ufo ship` command. Normally, it is recommended to use `ufo ship` over the `ufo deploy` command to do everything in one step:
|
11
19
|
|
12
20
|
1. build the Docker image
|
13
21
|
2. register the ECS task definition
|
data/lib/ufo/help/init.md
CHANGED
@@ -19,6 +19,12 @@ For this example we will use [tongueroo/hi](https://github.com/tongueroo/hi) whi
|
|
19
19
|
append .gitignore
|
20
20
|
Starter ufo files created.
|
21
21
|
|
22
|
+
## More Short Examples
|
23
|
+
|
24
|
+
ufo init --image httpd --app demo
|
25
|
+
ufo init --image 123456789012.dkr.ecr.us-west-2.amazonaws.com/myimage --app demo
|
26
|
+
ufo init --image tongueroo/hi --app hi --launch-type fargate --execution-role-arn arn:aws:iam::536766270177:role/ecsTaskExecutionRole
|
27
|
+
|
22
28
|
## Options: app and image
|
23
29
|
|
24
30
|
The `app` is that application name that you want to show up on the ECS dashboard. It is encouraged to have the app name be a single word.
|
@@ -46,6 +52,18 @@ The standard directory structure of the `.ufo` folder that was created looks lik
|
|
46
52
|
|
47
53
|
For a explanation of the folders and files refer to [Structure]({% link _docs/structure.md %}).
|
48
54
|
|
55
|
+
## Fargate Support
|
56
|
+
|
57
|
+
For ECS Fargate, the ECS task definition structure is a bit different. To initialize a project to support Fargate use the `--launch-type fargate` option. You'll be prompted for a execution role arn. This value gets added to the generated `.ufo/variables/base.rb` and used in the `.ufo/templates/main.json.erb`.
|
58
|
+
|
59
|
+
ufo init --image tongueroo/hi --app hi --force --launch-type fargate
|
60
|
+
|
61
|
+
You can also generate the init ufo files and bypass the prompt by providing the `----execution-role-arn` option upfront.
|
62
|
+
|
63
|
+
ufo init --image tongueroo/hi --app hi --force --launch-type fargate --execution-role-arn arn:aws:iam::536766270177:role/ecsTaskExecutionRole
|
64
|
+
|
65
|
+
Important: You will need to adjust adjust the generated `.ufo/params.yml` and set the subnet and security_group values which are required for Fargate.
|
66
|
+
|
49
67
|
## Custom Templates
|
50
68
|
|
51
69
|
If you would like the `ufo init` command to use your own custom templates, you can achieve this with the `--template` and `--template-mode` options. Example:
|
data/lib/ufo/help/task.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
## Examples
|
2
2
|
|
3
|
-
|
3
|
+
You can use the `--command` or `-c` option to override the Docker container command.
|
4
4
|
|
5
|
-
|
5
|
+
ufo task hi-migrate # default command
|
6
|
+
ufo task hi-web --command bin/migrate
|
7
|
+
ufo task hi-web --command bin/with_env bundle exec rake db:migrate:redo VERSION=xxx
|
8
|
+
ufo task hi-web -c uptime
|
9
|
+
ufo task hi-web -c pwd
|
6
10
|
|
7
|
-
You can also override the command used by the Docker container in the task definitions via command.
|
8
|
-
|
9
|
-
ufo task hi-web --command bin/migrate
|
10
|
-
ufo task hi-web --command bin/with_env bundle exec rake db:migrate:redo VERSION=xxx
|
data/lib/ufo/init.rb
CHANGED
@@ -9,6 +9,8 @@ module Ufo
|
|
9
9
|
[:force, type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files."],
|
10
10
|
[:image, required: true, desc: "Docker image name without the tag. Example: tongueroo/hi. Configures ufo/settings.yml"],
|
11
11
|
[:app, required: true, desc: "App name. Preferably one word. Used in the generated ufo/task_definitions.rb."],
|
12
|
+
[:launch_type, default: "ec2", desc: "ec2 or fargate."],
|
13
|
+
[:execution_role_arn, desc: "execution role arn used by tasks, required for fargate."],
|
12
14
|
[:template, desc: "Custom template to use."],
|
13
15
|
[:template_mode, desc: "Template mode: replace or additive."],
|
14
16
|
]
|
@@ -50,11 +52,16 @@ module Ufo
|
|
50
52
|
# map variables
|
51
53
|
@app = options[:app]
|
52
54
|
@image = options[:image]
|
55
|
+
@execution_role_arn_input = get_execution_role_arn_input
|
53
56
|
# copy the files
|
54
57
|
puts "Setting up ufo project..."
|
58
|
+
directory ".", exclude_pattern: /(\.git|templates)/
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
if @options[:launch_type] == "fargate"
|
61
|
+
copy_file ".ufo/templates/fargate.json.erb", ".ufo/templates/main.json.erb"
|
62
|
+
else
|
63
|
+
copy_file ".ufo/templates/main.json.erb"
|
64
|
+
end
|
58
65
|
end
|
59
66
|
|
60
67
|
def upsert_gitignore
|
data/lib/ufo/param.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'memoist'
|
3
|
+
|
4
|
+
module Ufo
|
5
|
+
class Param
|
6
|
+
extend Memoist
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@params_path = "#{Ufo.root}/.ufo/params.yml"
|
10
|
+
end
|
11
|
+
|
12
|
+
def helper
|
13
|
+
dsl = DSL.new("#{Ufo.root}/.ufo/task_definitions.rb", quiet: true, mute: true)
|
14
|
+
dsl.helper
|
15
|
+
end
|
16
|
+
|
17
|
+
def data
|
18
|
+
vars = Ufo::TemplateScope.new(helper).assign_instance_variables
|
19
|
+
result = RenderMePretty.result(@params_path, vars)
|
20
|
+
YAML.load(result)
|
21
|
+
end
|
22
|
+
memoize :data
|
23
|
+
end
|
24
|
+
end
|
data/lib/ufo/scale.rb
CHANGED
data/lib/ufo/sequence.rb
CHANGED
@@ -11,6 +11,20 @@ module Ufo
|
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
14
|
+
def get_execution_role_arn_input
|
15
|
+
return @execution_role_arn if @execution_role_arn
|
16
|
+
|
17
|
+
if @options[:execution_role_arn]
|
18
|
+
@execution_role_arn = @options[:execution_role_arn]
|
19
|
+
return @execution_role_arn
|
20
|
+
end
|
21
|
+
|
22
|
+
return unless @options[:launch_type] == "fargate"
|
23
|
+
# execution role arn required for fargate
|
24
|
+
print "Please provide a execution role arn role for the ecs task: "
|
25
|
+
@execution_role_arn = $stdin.gets.strip
|
26
|
+
end
|
27
|
+
|
14
28
|
def override_source_paths(*paths)
|
15
29
|
# Using string with instance_eval because block doesnt have access to
|
16
30
|
# path at runtime.
|
data/lib/ufo/ship.rb
CHANGED
@@ -5,7 +5,6 @@ module Ufo
|
|
5
5
|
class ShipmentOverridden < UfoError; end
|
6
6
|
|
7
7
|
class Ship
|
8
|
-
include Default
|
9
8
|
include AwsService
|
10
9
|
include Util
|
11
10
|
|
@@ -209,16 +208,14 @@ module Ufo
|
|
209
208
|
options = {
|
210
209
|
cluster: @cluster,
|
211
210
|
service_name: @service,
|
212
|
-
desired_count: default_desired_count,
|
213
|
-
deployment_configuration: {
|
214
|
-
maximum_percent: default_maximum_percent,
|
215
|
-
minimum_healthy_percent: default_minimum_healthy_percent
|
216
|
-
},
|
217
211
|
task_definition: @task_definition
|
218
212
|
}
|
213
|
+
options = options.merge(default_params[:create_service])
|
219
214
|
unless target_group.nil? || target_group.empty?
|
220
215
|
add_load_balancer!(container, options, target_group)
|
221
216
|
end
|
217
|
+
puts "Creating ECS service with params:"
|
218
|
+
display_params(options)
|
222
219
|
response = ecs.create_service(options)
|
223
220
|
service = response.service # must set service here since this might never be called if @wait_for_deployment is false
|
224
221
|
end
|
@@ -248,6 +245,9 @@ module Ufo
|
|
248
245
|
service: ecs_service.service_arn, # can use the service name also since it is unique
|
249
246
|
task_definition: @task_definition
|
250
247
|
}
|
248
|
+
params = params.merge(default_params[:update_service] || {})
|
249
|
+
puts "Updating ECS service with params:"
|
250
|
+
display_params(params)
|
251
251
|
response = ecs.update_service(params)
|
252
252
|
service = response.service # must set service here since this might never be called if @wait_for_deployment is false
|
253
253
|
end
|