ufo 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f4295c61395db86047326a8b5cca89b35735ac5
4
- data.tar.gz: fa3eda92853d988e5f95f673eccb296f1f85526d
3
+ metadata.gz: 7789e9644d6d70e458722decdc1212590dcc2941
4
+ data.tar.gz: 686742062dc6728297aecad1a4fb89583ba24b2a
5
5
  SHA512:
6
- metadata.gz: 2bd0122e097ef64e815caac9c1b4ad3a7f16e12fa60b15d47ba5033d7ea818b237bd80004e6c589e447a2866678ff734118060f49ff24abe9443fef7b548a7cc
7
- data.tar.gz: ef44ccd22089e3e408f7453ce978c51102acc43edf968d6edfe3721c02729a926fd8d37ac08fd6961d726d3800cd27b8f8d01b7d066d327b520926d86d09f7b3
6
+ metadata.gz: 4580b708e976c77128454ff540cdf4751bb9634dbcd9813b31fccdd1e757805aef1592fd2b8804827c0e540de70f0e9715fb1bed6870db7f3ad4e4c156529d9f
7
+ data.tar.gz: 3137da3783c02fcfeb770dc95bc2000f0bc4b947aa96c9c0f115c684d7b56a050d4479c67129ba834a8eb350beceec1089f715bf9f4a04eefa111c1243f70b22
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ufo (0.0.2)
4
+ ufo (0.1.0)
5
5
  aws-sdk
6
6
  byebug
7
7
  colorize
@@ -22,12 +22,14 @@ GEM
22
22
  multi_json (~> 1.3)
23
23
  thread_safe (~> 0.1)
24
24
  tzinfo (~> 0.3.37)
25
- aws-sdk (2.6.9)
26
- aws-sdk-resources (= 2.6.9)
27
- aws-sdk-core (2.6.9)
25
+ aws-sdk (2.6.29)
26
+ aws-sdk-resources (= 2.6.29)
27
+ aws-sdk-core (2.6.29)
28
+ aws-sigv4 (~> 1.0)
28
29
  jmespath (~> 1.0)
29
- aws-sdk-resources (2.6.9)
30
- aws-sdk-core (= 2.6.9)
30
+ aws-sdk-resources (2.6.29)
31
+ aws-sdk-core (= 2.6.29)
32
+ aws-sigv4 (1.0.0)
31
33
  builder (3.1.4)
32
34
  byebug (9.0.6)
33
35
  codeclimate-test-reporter (0.6.0)
@@ -110,7 +112,7 @@ GEM
110
112
  i18n
111
113
  thor (0.19.1)
112
114
  thread_safe (0.3.5)
113
- tzinfo (0.3.51)
115
+ tzinfo (0.3.52)
114
116
 
115
117
  PLATFORMS
116
118
  ruby
@@ -125,4 +127,4 @@ DEPENDENCIES
125
127
  ufo!
126
128
 
127
129
  BUNDLED WITH
128
- 1.13.2
130
+ 1.13.6
data/README.md CHANGED
@@ -1,98 +1,71 @@
1
- # Ufo
1
+ # Ufo - Build Docker Containers and Ship Them to AWS ECS
2
2
 
3
- This script handles a common application deployment pattern to AWS ECS. Most rails apps have web, worker, and clock processes. These processes use the same codebase (same docker image) but have slightly different run time settings. For example, the docker run command for a web process could be `puma` and the command for a worker process could be `sidekiq`. Environment variables are sometimes different also.
3
+ ## Quick Introduction
4
4
 
5
- This script builds the same docker image to be used for all of these processes but allows you to different generated AWS ECS Task Definitions for each of the processes. The task defintions for each process is created via a template generator which you fully can control.
5
+ Ufo is a simple tool that makes building and shipping Docker containers to [AWS ECS](https://aws.amazon.com/ecs/) super easy.
6
6
 
7
7
  A summary of steps `ufo ship` takes:
8
8
 
9
- 1. builds a docker image - optional and can be skipped
10
- 2. generates the ecs template definition - optional and can be skipped
11
- 3. ships it to possible multiple services depending on the settings
9
+ 1. builds a docker image
10
+ 2. generates and registers the ECS template definition
11
+ 3. deploys the ECS template definition to the specified service.
12
+
13
+ Ufo deploys a task definition that is created via a template generator which is fully controllable.
14
+
12
15
 
13
16
  ## Installation
14
17
 
15
18
  $ gem install ufo
16
19
 
17
- You will need a working version of docker installed if you want ufo to also build the docker image. If you do not want ufo to build the docker image, then you do not need docker installed.
20
+ You will need a working version of docker installed as ufo calls the docker command.
18
21
 
19
22
  ## Usage
20
23
 
21
- If the cluster or the services do not exist then they get created. If you are relying on this tool to create the cluster, you still need to associate ECS Container Instances to the cluster yourself.
24
+ When using ufo if the ECS service does not yet exist, it will automatically be created for you. If you are relying on this tool to create the cluster, you still need to associate ECS Container Instances to the cluster yourself.
22
25
 
23
26
  First initialize ufo files within your project. Let's say you have an `hi` app.
24
27
 
25
28
  ```
29
+ $ git clone https://github.com/tongueroo/hi
26
30
  $ cd hi
27
- $ ufo init --cluster default --image tongueroo/hi
28
- Generated starter ufo structure:
29
- hi/ufo/task_definitions.rb
30
- hi/ufo/templates/web.json.erb
31
- hi/ufo/settings.yml # default cluster is saved here
31
+ $ ufo init --app hi --cluster stag --image tongueroo/hi
32
+ Setting up ufo project...
33
+ created: ./bin/deploy
34
+ exists: ./Dockerfile
35
+ created: ./ufo/settings.yml
36
+ created: ./ufo/task_definitions.rb
37
+ created: ./ufo/templates/main.json.erb
38
+ created: ./.env
39
+ Starter ufo files created.
40
+ $
32
41
  ```
33
42
 
34
- It is now a good time to take a look at the generated files at this point.
35
-
36
- ### ufo/settings.yml
37
-
38
- `ufo/settings.yml` holds some default configuration settings so you don't have to type out these options every single time.
43
+ Take a look at the `ufo/settings.yml` file to see that it holds some default configuration settings so you don't have to type out these options every single time.
39
44
 
40
45
  ```yaml
41
- service_cluster:
42
- default: my-default-cluster
43
- hi-web-prod: hi-cluster
44
46
  image: tongueroo/hi
47
+ service_cluster:
48
+ default: stag # default cluster
49
+ hi-web: stag
50
+ hi-clock: stag
51
+ hi-worker: stag
45
52
  ```
46
53
 
47
- You should adjust the image name if it not already adjusted.
54
+ The `image` value is the name that ufo will use for the Docker image name.
48
55
 
49
56
  The `service_cluster` mapping provides a way to set default service to cluster mappings so that you do not have to specify the `--cluster` repeatedly. Example:
50
57
 
51
58
  ```
52
- ufo ship hi-web-prod --cluster hi-cluster
53
- ufo ship hi-web-prod # same as above because it is configured in ufo/settings.yml
54
- ufo ship hi-web-prod --cluster special-cluster # overrides any setting default fallback.
59
+ ufo ship hi-web --cluster hi-cluster
60
+ ufo ship hi-web # same as above because it is configured in ufo/settings.yml
61
+ ufo ship hi-web --cluster special-cluster # overrides any setting default fallback.
55
62
  ```
56
63
 
57
- ### ufo/task_definitions.rb
64
+ ## Task Definition ERB Template and DSL Generator
58
65
 
59
- `ufo/task_definitions.rb` holds the task definitions to be generated. They correspond to each service you want deployed. It is written in a DSL. We'll go over a simplifed example:
66
+ Ufo task definitions are is written in a template generator DSL to provide full control of the task definition that gets uploaded for each service. We'll go over a simple example. Here is the ERB template for `ufo/templates/main.json.erb`:
60
67
 
61
- ```ruby
62
- task_definition "hi-web-prod" do
63
- source "web" # this corresponds to the file in "ufo/templates/web.json.erb"
64
- # if source is not set, it will use a default task definition template:
65
- # https://github.com/tongueroo/ufo/tree/master/lib/ufo/templates/default.json.erb
66
- variables(
67
- family: "hi-web-prod",
68
- name: "web",
69
- container_port: helper.dockerfile_port,
70
- command: ["bin/web"]
71
- image:helper.full_image_name,
72
- cpu: 2,
73
- memory_reservation: 128,
74
- container_port: helper.dockerfile_port,
75
- command: helper.dockerfile_command,
76
- environment: [
77
- {name: "DATABASE_URL", value: "mysql2://user:pass@domani.com:3306/myapp"},
78
- {name: "PORT", value: helper.dockerfile_port.to_s},
79
- {name: "SECRET", value: "supersecret"},
80
- ]
81
- )
82
- end
83
-
84
- ```
85
-
86
- You'll notice a `helper` variable being used. `helper` is a variable that holds some special variables that is available within the ufo DSL. They are optional to use. Here is a list of them:
87
-
88
- * helper.full_image_name - Docker image name to be used when a the docker image is build. This is defined in ufo/settings.yml.
89
- * helper.dockerfile_port - Expose port in the Dockerfile. Only supports one exposed port, the first one that is encountered.
90
-
91
- The variables defined within the task_definition block of code are available as instance variables in the corresponding template. Here is the template with the use of the instance variables:
92
-
93
- ### ufo/templates/web.json.erb
94
-
95
- ```html
68
+ ```json
96
69
  {
97
70
  "family": "<%= @family %>",
98
71
  "containerDefinitions": [
@@ -118,12 +91,48 @@ The variables defined within the task_definition block of code are available as
118
91
  <% if @environment %>
119
92
  "environment": <%= @environment.to_json %>,
120
93
  <% end %>
94
+ <% if @awslogs_group %>
95
+ "logConfiguration": {
96
+ "logDriver": "awslogs",
97
+ "options": {
98
+ "awslogs-group": "<%= @awslogs_group %>",
99
+ "awslogs-region": "<%= @awslogs_region || 'us-east-1' %>",
100
+ "awslogs-stream-prefix": "<%= @awslogs_stream_prefix %>"
101
+ }
102
+ },
103
+ <% end %>
121
104
  "essential": true
122
105
  }
123
106
  ]
124
107
  }
125
108
  ```
126
109
 
110
+ The instance variable values are specified in `ufo/task_definitions.rb`. Here's the
111
+
112
+
113
+ ```ruby
114
+ task_definition "hi-web" do
115
+ source "main" # will use ufo/templates/main.json.erb
116
+ variables(
117
+ family: task_definition_name,
118
+ # image: tongueroo/hi:ufo-[timestamp]=[sha]
119
+ image: helper.full_image_name,
120
+ environment: env_file('.env.prod')
121
+ name: "web",
122
+ container_port: helper.dockerfile_port,
123
+ command: ["bin/web"]
124
+ )
125
+ end
126
+ ```
127
+
128
+ As you can see above, the task\_definitions.rb file has some special variables and helper methods available. These helper methods provide useful contextual information about the project. For example, one of the variable provides the exposed port in the Dockerfile of the project. Here is a list of the important ones:
129
+
130
+ * **helper.full\_image\_name** — The full docker image name that ufo builds. The “base” portion of the docker image name is defined in ufo/settings.yml. For example, the base portion is "tongueroo/hi" and the full image name is tongueroo/hi:ufo-[timestamp]-[sha]. So the base does not include the Docker tag and the full image name does include the tag.
131
+ * **helper.dockerfile\_port** — Exposed port extracted from the Dockerfile of the project. 
132
+ * **env_file** — This method takes an .env file which contains a simple key value list of environment variables and converts the list to the proper task definition json format.
133
+
134
+ The 2 classes which provide these special helper methods are in [ufo/dsl.rb](https://github.com/tongueroo/ufo/blob/master/lib/ufo/dsl.rb) and [ufo/dsl/helper.rb](https://github.com/tongueroo/ufo/blob/master/lib/ufo/dsl/helper.rb). Refer to these classes for the full list of the special variables and methods.
135
+
127
136
  ### Customizing Templates
128
137
 
129
138
  If you want to change the template then you can follow the example in the generated ufo files. For example, if you want to create a template for the worker service.
@@ -132,46 +141,68 @@ If you want to change the template then you can follow the example in the genera
132
141
  2. Change the source in the `task_definition` using "worker" as the source.
133
142
  3. Add variables.
134
143
 
135
- ### Ship
144
+ ### ufo ship
136
145
 
137
146
  Ufo uses the aforementioned files to build task definitions and then ship to them to AWS ECS. To execute the ship process run:
138
147
 
139
148
  ```bash
140
- ufo ship hi-web-prod
149
+ ufo ship hi-web --cluster stag
141
150
  ```
142
151
 
143
- When you run `ufo ship hi-web-prod`:
152
+ Note, if you have configured `ufo/settings.yml` to map hi-web to the stag cluster using the service_cluster option the command becomes simply:
144
153
 
145
- 1. It builds the docker image
146
- 2. Generates a task definition and registers it
154
+ ```bash
155
+ ufo ship hi-web
156
+ ```
157
+
158
+ When you run `ufo ship hi-web`:
159
+
160
+ 1. It builds the docker image.
161
+ 2. Generates a task definition and registers it.
147
162
  3. Updates the ECS service to use it.
148
163
 
149
- If the ECS service hi-web-prod does not yet exist, ufo will create the service for you.
164
+ If the ECS service hi-web does not yet exist, ufo will create the service for you.
150
165
 
151
166
  If the service has a container name web, you'll get prompted to create an ELB and specify a target group arn. The ELB and target group must already exist.
152
167
 
153
- You can bypass the prompt and specify the target group arn as part of the command. The elb target group can only be associated when the service gets created for the first time. If the service already exists then the `--target-group` parameter just gets ignored and the ECS task simply gets updated.
168
+ You can bypass the prompt and specify the target group arn as part of the command. The elb target group can only be associated when the service gets created for the first time. If the service already exists then the `--target-group` parameter just gets ignored and the ECS task simply gets updated. Example:
169
+
170
+
171
+ ```bash
172
+ ufo ship hi-web --target-group=arn:aws:elasticloadbalancing:us-east-1:12345689:targetgroup/hi-web/jdisljflsdkjl
173
+ ```
174
+
175
+ ### Shipping Multiple Services with bin/deploy
154
176
 
177
+ A common pattern is to have 3 processes: web, worker, and clock. This is very common in rails applcations. The web process handles web traffic, the worker process handles background job processing that would be too slow and potentially block web requests, and a clock process is typically used to schedule recurring jobs. These processes use the same codebase, or same docker image, but have slightly different run time settings. For example, the docker run command for a web process could be [puma](http://puma.io/) and the command for a worker process could be [sidekiq](http://sidekiq.org/). Environment variables are sometimes different also. The important key is that the same docker image is used for all 3 services but the task definition for each service is different.
178
+
179
+ This is easily accomplished with the `bin/deploy` wrapper script that the `ufo init` command initially generates. The starter script example shows you how you can use ufo to generate one docker image and use the same image to deploy to all 3 services. Here is an example `bin/deploy` script:
155
180
 
156
181
  ```bash
157
- ufo ship hi-web-prod --target-group=arn:aws:elasticloadbalancing:us-east-1:12345689:targetgroup/hi-web-prod/jdisljflsdkjl
182
+ #!/bin/bash -xe
183
+
184
+ ufo ship hi-worker --cluster stag --no-wait
185
+ ufo ship hi-clock --cluster stag --no-wait --no-docker
186
+ ufo ship hi-web --cluster stag --no-docker
158
187
  ```
159
188
 
189
+ The first `ufo ship hi-worker` command build and ships docker image to ECS, but the following two `ufo ship` commands use the `--no-docker` flag to skip the `docker build` step. `ufo ship` will use the last built docker image as the image to be shipped. For those curious, this is stored in `ufo/docker_image_name_ufo.txt`.
190
+
160
191
  ### Service and Task Names Convention
161
192
 
162
193
  Ufo assumes a convention that service\_name and the task\_name are the same. If you would like to override this convention then you can specify the task name.
163
194
 
164
195
  ```
165
- ufo ship hi-web-prod-1 --task hi-web-prod
196
+ ufo ship hi-web --task my-task
166
197
  ```
167
198
 
168
- This means that in the task_definitionintion.rb you will also defined it without the `-1`. For example:
199
+ This means that in the task_definition.rb you will also defined it with `my-task`. For example:
169
200
 
170
201
  ```ruby
171
- task_definition "hi-web-prod" do
202
+ task_definition "my-task" do
172
203
  source "web" # this corresponds to the file in "ufo/templates/web.json.erb"
173
204
  variables(
174
- family: "hi-web-prod",
205
+ family: "my-task",
175
206
  ....
176
207
  )
177
208
  end
@@ -180,7 +211,7 @@ end
180
211
 
181
212
  ### Running Tasks in Pieces
182
213
 
183
- The `ufo ship` command goes few a few stages: building the docker image, registering the task defiintions and updating the ECS service. The CLI exposes each of the steps as separate commands. Here is now you would be able to run each of the steps in pieces.
214
+ The `ufo ship` command goes through a few stages: building the docker image, registering the task defiintions and updating the ECS service. The CLI exposes each of the steps as separate commands. Here is now you would be able to run each of the steps in pieces.
184
215
 
185
216
  Build the docker image first.
186
217
 
@@ -199,21 +230,35 @@ ufo tasks register # will register all genreated task definitinos in the ufo/out
199
230
  Skips all the build docker phases of a deploy sequence and only update the service with the task definitions.
200
231
 
201
232
  ```bash
202
- ufo ship hi-web-prod --no-docker
233
+ ufo ship hi-web --no-docker
203
234
  ```
204
- Note you use the `--no-docker` option you should make sure you have push a docker image with the previous committed sha code to your docker register. Or else the task will not be able to spin up because the docker image does not exist. You can work around this but just running `--no-docker` with a dirty working tree.
235
+ Note if you use the `--no-docker` option you should ensure that you have already push a docker image to your docker register. Or else the task will not be able to spin up because the docker image does not exist. I recommend that you normally use `ufo ship` most of the time.
236
+
205
237
 
238
+ ## Automated Docker Images Clean Up
206
239
 
207
- ## Automatically Creates the Service
240
+ Ufo can be configured to automatically clean old images from the ECR registry after the deploy completes. I normally set `~/.ufo/settings.yml` like so:
208
241
 
209
- When running `ufo ship` if the ECS service does not yet exist, it will automatically be created for you.
242
+ ```yaml
243
+ ecr_keep: 3
244
+ ```
245
+
246
+ Automated Docker images clean up only works if you are using ECR registry.
210
247
 
211
248
  ## Scale
212
249
 
213
- There is a convenience wrapper that simple executes `aws ecs update-service --service [SERVICE] ----desired-count [COUNT]`
250
+ There is a convenience wrapper that simple executes `aws ecs update-service --service [SERVICE] --desired-count [COUNT]`
214
251
 
215
252
  ```
216
- ufo scale hi-web-prod 1
253
+ ufo scale hi-web 1
254
+ ```
255
+
256
+ ## Destroy
257
+
258
+ To scale down the service and destroy it:
259
+
260
+ ```
261
+ ufo destroy hi-web
217
262
  ```
218
263
 
219
264
  ### More Help
@@ -223,5 +268,4 @@ ufo help
223
268
  ```
224
269
  ## Contributing
225
270
 
226
- Bug reports and pull requests are welcome on GitHub at [https://github.com/tongueroo/ufo/issues](https://github.com/tongueroo/ufo/issues).
227
-
271
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/tongueroo/ufo/issues](https://github.com/tongueroo/ufo/issues).
File without changes
@@ -9,4 +9,4 @@ ufo ship <%= @app %>-clock --cluster <%= @cluster %> --no-wait
9
9
  ufo ship <%= @app %>-worker --cluster <%= @cluster %> --no-wait --no-docker
10
10
  # The final service will wait for the deploy to finish. Please specify an
11
11
  # Application Load Balancer if creating the service for the first time.
12
- ufo ship <%= @app %>-web --cluster <%= @cluster %> --no-docker --target-group ''
12
+ ufo ship <%= @app %>-web --cluster <%= @cluster %> --no-docker
@@ -12,7 +12,7 @@ common = {
12
12
  image: helper.full_image_name, # includes the git sha tongueroo/hi:ufo-[sha].
13
13
  cpu: 128,
14
14
  memory_reservation: 256,
15
- environment: env_file(".env.prod")
15
+ environment: env_file(".env")
16
16
  }
17
17
 
18
18
  task_definition "<%= @app %>-web" do
@@ -50,7 +50,7 @@ module Ufo
50
50
  end
51
51
  end
52
52
 
53
- # methods available in task_definitionintions
53
+ # methods available in task_definitions
54
54
  def task_definition(name, &block)
55
55
  @task_definitions << TaskDefinition.new(self, name, @options, &block)
56
56
  end
@@ -10,7 +10,7 @@ module Ufo
10
10
  def build
11
11
  puts "Building Task Definitions...".green unless @options[:mute]
12
12
  check_templates_definitions_path
13
- dsl = DSL.new(template_definitions_path, @options.merge(quiet: true, mute: true))
13
+ dsl = DSL.new(template_definitions_path, @options.merge(quiet: false, mute: true))
14
14
  dsl.run
15
15
  puts "Task Definitions built in ufo/output." unless @options[:mute]
16
16
  end
@@ -1,3 +1,3 @@
1
1
  module Ufo
2
- VERSION = "0.0.6"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Ufo::VERSION
9
9
  spec.authors = ["Tung Nguyen"]
10
10
  spec.email = ["tongueroo@gmail.com"]
11
- spec.description = %q{Build docker containers and ship them to AWS ECS}
12
- spec.summary = %q{Build docker containers and ship them to AWS ECS}
11
+ spec.description = %q{Build Docker Containers and Ship Them to AWS ECS}
12
+ spec.summary = %q{Build Docker Containers and Ship Them to AWS ECS}
13
13
  spec.homepage = "https://github.com/tongueroo/ufo"
14
14
  spec.license = "MIT"
15
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ufo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-30 00:00:00.000000000 Z
11
+ date: 2016-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -178,7 +178,7 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- description: Build docker containers and ship them to AWS ECS
181
+ description: Build Docker Containers and Ship Them to AWS ECS
182
182
  email:
183
183
  - tongueroo@gmail.com
184
184
  executables:
@@ -196,7 +196,7 @@ files:
196
196
  - README.md
197
197
  - Rakefile
198
198
  - bin/ufo
199
- - lib/starter_project/.env.prod
199
+ - lib/starter_project/.env
200
200
  - lib/starter_project/Dockerfile
201
201
  - lib/starter_project/bin/deploy
202
202
  - lib/starter_project/ufo/settings.yml
@@ -257,7 +257,7 @@ rubyforge_project:
257
257
  rubygems_version: 2.5.2
258
258
  signing_key:
259
259
  specification_version: 4
260
- summary: Build docker containers and ship them to AWS ECS
260
+ summary: Build Docker Containers and Ship Them to AWS ECS
261
261
  test_files:
262
262
  - spec/fixtures/home_existing/.docker/config.json
263
263
  - spec/lib/cli_spec.rb