ufo 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +128 -0
- data/Guardfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +227 -0
- data/Rakefile +6 -0
- data/bin/ufo +10 -0
- data/lib/starter_project/.env.prod +3 -0
- data/lib/starter_project/Dockerfile +20 -0
- data/lib/starter_project/bin/deploy +12 -0
- data/lib/starter_project/ufo/settings.yml +7 -0
- data/lib/starter_project/ufo/task_definitions.rb +44 -0
- data/lib/starter_project/ufo/templates/main.json.erb +39 -0
- data/lib/ufo.rb +26 -0
- data/lib/ufo/aws_services.rb +21 -0
- data/lib/ufo/cli.rb +136 -0
- data/lib/ufo/cli/help.rb +164 -0
- data/lib/ufo/defaults.rb +46 -0
- data/lib/ufo/destroy.rb +60 -0
- data/lib/ufo/docker_builder.rb +120 -0
- data/lib/ufo/docker_cleaner.rb +52 -0
- data/lib/ufo/dockerfile_updater.rb +42 -0
- data/lib/ufo/dsl.rb +93 -0
- data/lib/ufo/dsl/helper.rb +47 -0
- data/lib/ufo/dsl/outputter.rb +40 -0
- data/lib/ufo/dsl/task_definition.rb +65 -0
- data/lib/ufo/ecr_auth.rb +35 -0
- data/lib/ufo/ecr_cleaner.rb +66 -0
- data/lib/ufo/execute.rb +19 -0
- data/lib/ufo/init.rb +83 -0
- data/lib/ufo/pretty_time.rb +14 -0
- data/lib/ufo/scale.rb +34 -0
- data/lib/ufo/settings.rb +33 -0
- data/lib/ufo/ship.rb +436 -0
- data/lib/ufo/tasks_builder.rb +30 -0
- data/lib/ufo/tasks_register.rb +51 -0
- data/lib/ufo/templates/default.json.erb +39 -0
- data/lib/ufo/version.rb +3 -0
- data/spec/fixtures/home_existing/.docker/config.json +10 -0
- data/spec/lib/cli_spec.rb +50 -0
- data/spec/lib/ecr_auth_spec.rb +39 -0
- data/spec/lib/ecr_cleaner_spec.rb +32 -0
- data/spec/lib/ship_spec.rb +77 -0
- data/spec/spec_helper.rb +28 -0
- data/ufo.gemspec +34 -0
- metadata +267 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
FROM ruby:2.3.3
|
2
|
+
MAINTAINER Tung Nguyen <tongueroo@gmail.com>
|
3
|
+
|
4
|
+
# This is just a sample Dockerfile. This is meant to be overriden.
|
5
|
+
|
6
|
+
# Install bundle of gems first in a layer
|
7
|
+
# so if the Gemfile doesnt chagne it wont have to install gems again
|
8
|
+
WORKDIR /tmp
|
9
|
+
COPY Gemfile* /tmp/
|
10
|
+
RUN bundle install && rm -rf /root/.bundle/cache
|
11
|
+
|
12
|
+
# Add the Rails app
|
13
|
+
ENV HOME /root
|
14
|
+
WORKDIR /app
|
15
|
+
COPY . /app
|
16
|
+
RUN bundle install
|
17
|
+
RUN mkdir -p tmp/cache tmp/pids
|
18
|
+
|
19
|
+
EXPOSE 5001
|
20
|
+
CMD ["bin/web"]
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/bin/bash -xe
|
2
|
+
|
3
|
+
# Generated started bin/deploy script. Meant to be example only and should probably
|
4
|
+
# be overridden.
|
5
|
+
|
6
|
+
# Only build docker image on with the first command.
|
7
|
+
ufo ship <%= @app %>-clock --cluster <%= @cluster %> --no-wait
|
8
|
+
# Skipping the docker build phase for the rest of the ship commands
|
9
|
+
ufo ship <%= @app %>-worker --cluster <%= @cluster %> --no-wait --no-docker
|
10
|
+
# The final service will wait for the deploy to finish. Please specify an
|
11
|
+
# Application Load Balancer if creating the service for the first time.
|
12
|
+
ufo ship <%= @app %>-web --cluster <%= @cluster %> --no-docker --target-group ''
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# There will be some special variables that are automatically available in this file.
|
2
|
+
#
|
3
|
+
# Some of variables are from the Dockerfile and some are from other places.
|
4
|
+
#
|
5
|
+
# * helper.full_image_name - Docker image name with the tag when docker image is built by ufo. This is defined in ufo/settings.yml. The helper.full_image_name includes the git sha tongueroo/hi:ufo-[sha].
|
6
|
+
# * helper.dockerfile_port - Expose port in the Dockerfile. Only supports one exposed port, the first one that is encountered.
|
7
|
+
#
|
8
|
+
# env_vars - is a helper method that generates the proper environment Array of Hashes
|
9
|
+
|
10
|
+
# common variables
|
11
|
+
common = {
|
12
|
+
image: helper.full_image_name, # includes the git sha tongueroo/hi:ufo-[sha].
|
13
|
+
cpu: 128,
|
14
|
+
memory_reservation: 256,
|
15
|
+
environment: env_file(".env.prod")
|
16
|
+
}
|
17
|
+
|
18
|
+
task_definition "<%= @app %>-web" do
|
19
|
+
source "main" # will use ufo/templates/main.json.erb
|
20
|
+
variables(common.dup.deep_merge(
|
21
|
+
family: task_definition_name,
|
22
|
+
name: "web",
|
23
|
+
container_port: helper.dockerfile_port,
|
24
|
+
command: ["bin/web"]
|
25
|
+
))
|
26
|
+
end
|
27
|
+
|
28
|
+
task_definition "<%= @app %>-worker" do
|
29
|
+
source "main" # will use ufo/templates/main.json.erb
|
30
|
+
variables(common.dup.deep_merge(
|
31
|
+
family: task_definition_name,
|
32
|
+
name: "worker",
|
33
|
+
command: ["bin/worker"]
|
34
|
+
))
|
35
|
+
end
|
36
|
+
|
37
|
+
task_definition "<%= @app %>-clock" do
|
38
|
+
source "main" # will use ufo/templates/main.json.erb
|
39
|
+
variables(common.dup.deep_merge(
|
40
|
+
family: task_definition_name,
|
41
|
+
name: "clock",
|
42
|
+
command: ["bin/clock"]
|
43
|
+
))
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"family": "<%= @family %>",
|
3
|
+
"containerDefinitions": [
|
4
|
+
{
|
5
|
+
"name": "<%= @name %>",
|
6
|
+
"image": "<%= @image %>",
|
7
|
+
"cpu": <%= @cpu %>,
|
8
|
+
<% if @memory %>
|
9
|
+
"memory": <%= @memory %>,
|
10
|
+
<% end %>
|
11
|
+
<% if @memory_reservation %>
|
12
|
+
"memoryReservation": <%= @memory_reservation %>,
|
13
|
+
<% end %>
|
14
|
+
<% if @container_port %>
|
15
|
+
"portMappings": [
|
16
|
+
{
|
17
|
+
"containerPort": "<%= @container_port %>",
|
18
|
+
"protocol": "tcp"
|
19
|
+
}
|
20
|
+
],
|
21
|
+
<% end %>
|
22
|
+
"command": <%= @command.to_json %>,
|
23
|
+
<% if @environment %>
|
24
|
+
"environment": <%= @environment.to_json %>,
|
25
|
+
<% end %>
|
26
|
+
<% if @awslogs_group %>
|
27
|
+
"logConfiguration": {
|
28
|
+
"logDriver": "awslogs",
|
29
|
+
"options": {
|
30
|
+
"awslogs-group": "<%= @awslogs_group %>",
|
31
|
+
"awslogs-region": "<%= @awslogs_region || 'us-east-1' %>",
|
32
|
+
"awslogs-stream-prefix": "<%= @awslogs_stream_prefix %>"
|
33
|
+
}
|
34
|
+
},
|
35
|
+
<% end %>
|
36
|
+
"essential": true
|
37
|
+
}
|
38
|
+
]
|
39
|
+
}
|
data/lib/ufo.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift(File.expand_path("../", __FILE__))
|
2
|
+
require "ufo/version"
|
3
|
+
require "pp"
|
4
|
+
require 'deep_merge'
|
5
|
+
require "colorize"
|
6
|
+
|
7
|
+
module Ufo
|
8
|
+
autoload :Settings, 'ufo/settings'
|
9
|
+
autoload :PrettyTime, 'ufo/pretty_time'
|
10
|
+
autoload :Execute, 'ufo/execute'
|
11
|
+
autoload :Init, 'ufo/init'
|
12
|
+
autoload :EcrAuth, 'ufo/ecr_auth'
|
13
|
+
autoload :CLI, 'ufo/cli'
|
14
|
+
autoload :DockerBuilder, 'ufo/docker_builder'
|
15
|
+
autoload :DockerfileUpdater, 'ufo/dockerfile_updater'
|
16
|
+
autoload :DockerCleaner, 'ufo/docker_cleaner'
|
17
|
+
autoload :TasksBuilder, 'ufo/tasks_builder'
|
18
|
+
autoload :TasksRegister, 'ufo/tasks_register'
|
19
|
+
autoload :Ship, 'ufo/ship'
|
20
|
+
autoload :EcrCleaner, 'ufo/ecr_cleaner'
|
21
|
+
autoload :Destroy, 'ufo/destroy'
|
22
|
+
autoload :Scale, 'ufo/scale'
|
23
|
+
# modules
|
24
|
+
autoload :Defaults, 'ufo/defaults'
|
25
|
+
autoload :AwsServices, 'ufo/aws_services'
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module Ufo
|
4
|
+
module AwsServices
|
5
|
+
def ecs
|
6
|
+
@ecs ||= Aws::ECS::Client.new(region: region)
|
7
|
+
end
|
8
|
+
|
9
|
+
def elb
|
10
|
+
@elb ||= Aws::ElasticLoadBalancingV2::Client.new(region: region)
|
11
|
+
end
|
12
|
+
|
13
|
+
def ecr
|
14
|
+
@ecr ||= Aws::ECR::Client.new(region: region)
|
15
|
+
end
|
16
|
+
|
17
|
+
def region
|
18
|
+
ENV['REGION'] || 'us-east-1'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ufo/cli.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'ufo/cli/help'
|
3
|
+
|
4
|
+
module Ufo
|
5
|
+
class Docker < Thor
|
6
|
+
desc "build", "builds docker image"
|
7
|
+
long_desc CLI::Help.docker_build
|
8
|
+
option :push, type: :boolean, default: false
|
9
|
+
def build
|
10
|
+
builder = DockerBuilder.new(options)
|
11
|
+
builder.build
|
12
|
+
builder.push if options[:push]
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "base", "builds docker image from Dockerfile.base"
|
16
|
+
long_desc CLI::Help.docker_base
|
17
|
+
option :push, type: :boolean, default: true
|
18
|
+
def base
|
19
|
+
builder = DockerBuilder.new(options.dup.merge(
|
20
|
+
image_namespace: "base",
|
21
|
+
dockerfile: "Dockerfile.base"
|
22
|
+
))
|
23
|
+
builder.build
|
24
|
+
builder.push if options[:push]
|
25
|
+
builder.update_dockerfile
|
26
|
+
DockerCleaner.new(builder.image_name, options.merge(tag_prefix: "base")).cleanup
|
27
|
+
EcrCleaner.new(builder.image_name, options.merge(tag_prefix: "base")).cleanup
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "full_image_name", "displays the full docker image with tag that will be generated"
|
31
|
+
long_desc CLI::Help.docker_full_image_name
|
32
|
+
def full_image_name
|
33
|
+
full_image_name = DockerBuilder.new(options).full_image_name
|
34
|
+
puts "Docker image name that will be used: #{full_image_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "cleanup IMAGE_NAME", "Cleans up old images. Keeps a specified amount."
|
38
|
+
option :keep, type: :numeric, default: 3
|
39
|
+
option :tag_prefix, default: "ufo"
|
40
|
+
long_desc CLI::Help.docker_cleanup
|
41
|
+
def cleanup(image_name)
|
42
|
+
DockerCleaner.new(image_name, options).cleanup
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Tasks < Thor
|
47
|
+
desc "build", "builds task definitions"
|
48
|
+
long_desc CLI::Help.tasks_build
|
49
|
+
option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
|
50
|
+
def build
|
51
|
+
TasksBuilder.new(options).build
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "register", "register all built task definitions in ufo/output"
|
55
|
+
long_desc CLI::Help.tasks_register
|
56
|
+
def register
|
57
|
+
TasksRegister.register_all(options)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class CLI < Thor
|
62
|
+
class_option :verbose, type: :boolean
|
63
|
+
class_option :mute, type: :boolean
|
64
|
+
class_option :noop, type: :boolean
|
65
|
+
class_option :project_root, type: :string, default: '.'
|
66
|
+
class_option :cluster, desc: "Cluster. Overrides ufo/settings.yml."
|
67
|
+
|
68
|
+
desc "docker ACTION", "docker related tasks"
|
69
|
+
long_desc Help.docker
|
70
|
+
subcommand "docker", Docker
|
71
|
+
|
72
|
+
desc "tasks ACTION", "task definition related tasks"
|
73
|
+
long_desc Help.tasks
|
74
|
+
subcommand "tasks", Tasks
|
75
|
+
|
76
|
+
desc "init", "setup initial ufo files"
|
77
|
+
option :cluster, type: :string, required: true, desc: "ECS cluster name. Example: default"
|
78
|
+
option :image, type: :string, required: true, desc: "Docker image name without the tag. Example: tongueroo/hi"
|
79
|
+
option :app, type: :string, required: true, desc: "App name. Preferably one word. Used in the generated ufo/task_definitions.rb."
|
80
|
+
long_desc Help.init
|
81
|
+
def init
|
82
|
+
Init.new(options).setup
|
83
|
+
end
|
84
|
+
|
85
|
+
desc "ship [SERVICE]", "ships container to the ECS service"
|
86
|
+
option :task, desc: "ECS task name, to override the task name convention."
|
87
|
+
option :target_group, desc: "ELB Target Group ARN."
|
88
|
+
option :elb, desc: "ELB Name associated with the target_group. Assumes first "
|
89
|
+
option :elb_prompt, type: :boolean, desc: "Enable ELB prompt", default: true
|
90
|
+
option :docker, type: :boolean, desc: "Enable docker build and push", default: true
|
91
|
+
option :wait, type: :boolean, desc: "Wait for deployment to complete", default: true
|
92
|
+
option :pretty, type: :boolean, default: true, desc: "Pretty format the json for the task definitions"
|
93
|
+
option :stop_old_tasks, type: :boolean, default: false, desc: "Stop old tasks after waiting for deploying to complete"
|
94
|
+
option :ecr_keep, type: :numeric, desc: "ECR specific cleanup of old images. Specifies how many images to keep. Only runs if the images are ECR images. Defaults to keeping all the images."
|
95
|
+
long_desc Help.ship
|
96
|
+
def ship(service)
|
97
|
+
builder = DockerBuilder.new(options) # outside if because it need docker.full_image_name
|
98
|
+
if options[:docker]
|
99
|
+
builder.build
|
100
|
+
builder.push
|
101
|
+
end
|
102
|
+
|
103
|
+
# task definition and deploy logic are coupled in the Ship class.
|
104
|
+
# Example: We need to know if the task defintion is a web service to see if we need to
|
105
|
+
# add the elb target group. The web service information is in the TasksBuilder
|
106
|
+
# and the elb target group gets set in the Ship class.
|
107
|
+
# So we always call these together.
|
108
|
+
TasksBuilder.new(options).build
|
109
|
+
TasksRegister.register(service, options)
|
110
|
+
task_definition = options[:task] || service # convention
|
111
|
+
ship = Ship.new(service, task_definition, options)
|
112
|
+
|
113
|
+
return if ENV['TEST'] # to allow me to quickly test most of the ship CLI portion only
|
114
|
+
ship.deploy
|
115
|
+
if options[:docker]
|
116
|
+
DockerCleaner.new(builder.image_name, options).cleanup
|
117
|
+
EcrCleaner.new(builder.image_name, options).cleanup
|
118
|
+
end
|
119
|
+
puts "Docker image shipped: #{builder.full_image_name.green}"
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "destroy [SERVICE]", "destroys the ECS service"
|
123
|
+
long_desc Help.destroy
|
124
|
+
option :force, type: :boolean, desc: "By pass are you sure prompt."
|
125
|
+
def destroy(service)
|
126
|
+
task_definition = options[:task] || service # convention
|
127
|
+
Destroy.new(service, options).bye
|
128
|
+
end
|
129
|
+
|
130
|
+
desc "scale [SERVICE] [COUNT]", "scale the ECS service"
|
131
|
+
long_desc Help.scale
|
132
|
+
def scale(service, count)
|
133
|
+
Scale.new(service, count, options).update
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/lib/ufo/cli/help.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
module Ufo
|
2
|
+
class CLI < Thor
|
3
|
+
class Help
|
4
|
+
class << self
|
5
|
+
def init
|
6
|
+
<<-EOL
|
7
|
+
Examples:
|
8
|
+
|
9
|
+
$ ufo init --cluster prod --image tongueroo/hi --app hi
|
10
|
+
|
11
|
+
The image should not include the tag since the tag is generated upon a `ufo ship`.
|
12
|
+
EOL
|
13
|
+
end
|
14
|
+
|
15
|
+
def docker
|
16
|
+
<<-EOL
|
17
|
+
Examples:
|
18
|
+
|
19
|
+
$ ufo docker build
|
20
|
+
|
21
|
+
$ ufo docker tag
|
22
|
+
EOL
|
23
|
+
end
|
24
|
+
|
25
|
+
def docker_base
|
26
|
+
<<-EOL
|
27
|
+
|
28
|
+
The docker cache task builds a docker image using the Dockerfile.base file and
|
29
|
+
updates the FROM Dockerfile image with the generated image from Dockerfile.base.
|
30
|
+
|
31
|
+
Examples:
|
32
|
+
|
33
|
+
$ ufo docker base
|
34
|
+
|
35
|
+
$ ufo docker base --no-push # do not push the image to the registry
|
36
|
+
|
37
|
+
Docker image tongueroo/hi:base-2016-10-21T15-50-57-88071f5 built.
|
38
|
+
EOL
|
39
|
+
end
|
40
|
+
|
41
|
+
def docker_build
|
42
|
+
<<-EOL
|
43
|
+
Examples:
|
44
|
+
|
45
|
+
$ ufo docker build
|
46
|
+
|
47
|
+
$ ufo docker build --push # also pushes the image to the docker registry
|
48
|
+
|
49
|
+
Docker image tongueroo/hi:ufo-2016-10-21T15-50-57-88071f5 built.
|
50
|
+
EOL
|
51
|
+
end
|
52
|
+
|
53
|
+
def docker_full_image_name
|
54
|
+
<<-EOL
|
55
|
+
Examples:
|
56
|
+
|
57
|
+
$ ufo docker full_image_name
|
58
|
+
|
59
|
+
Docker image name that will be used: tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
|
60
|
+
EOL
|
61
|
+
end
|
62
|
+
|
63
|
+
def docker_cleanup
|
64
|
+
<<-EOL
|
65
|
+
Examples:
|
66
|
+
|
67
|
+
Say you currently have these images:
|
68
|
+
|
69
|
+
* tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
|
70
|
+
|
71
|
+
* tongueroo/hi:ufo-2016-10-16T19-29-06-88071f5
|
72
|
+
|
73
|
+
* tongueroo/hi:ufo-2016-10-17T19-29-06-88071f5
|
74
|
+
|
75
|
+
* tongueroo/hi:ufo-2016-10-18T19-29-06-88071f5
|
76
|
+
|
77
|
+
To clean them up and keep the 3 more recent:
|
78
|
+
|
79
|
+
$ ufo docker cleanup tongueroo/hi
|
80
|
+
|
81
|
+
This will remove tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5.
|
82
|
+
EOL
|
83
|
+
end
|
84
|
+
|
85
|
+
def tasks
|
86
|
+
<<-EOL
|
87
|
+
Examples:
|
88
|
+
|
89
|
+
$ ufo tasks build
|
90
|
+
|
91
|
+
Builds all the task defintiions.
|
92
|
+
|
93
|
+
Note all the existing ufo/output generated task defintions are wiped out.
|
94
|
+
EOL
|
95
|
+
end
|
96
|
+
|
97
|
+
def tasks_build
|
98
|
+
<<-EOL
|
99
|
+
Examples:
|
100
|
+
|
101
|
+
$ ufo tasks build
|
102
|
+
|
103
|
+
Builds all the task defintiions.
|
104
|
+
|
105
|
+
Note all the existing ufo/output generated task defintions are wiped out.
|
106
|
+
EOL
|
107
|
+
end
|
108
|
+
|
109
|
+
def tasks_register
|
110
|
+
<<-EOL
|
111
|
+
Examples:
|
112
|
+
|
113
|
+
$ ufo tasks register
|
114
|
+
All the task defintiions in ufo/output registered.
|
115
|
+
EOL
|
116
|
+
end
|
117
|
+
|
118
|
+
def ship
|
119
|
+
<<-EOL
|
120
|
+
Examples:
|
121
|
+
|
122
|
+
To build the docker image, generate the task definition and ship it, run:
|
123
|
+
|
124
|
+
$ ufo ship hi-web-prod
|
125
|
+
|
126
|
+
By convention the task and service names match. If you need override to this convention then you can specific the task. For example if you want to ship to the `hi-web-prod-1` service and use the `hi-web-prod` task, run:
|
127
|
+
|
128
|
+
$ ufo ship hi-web-prod-1 --task hi-web-prod
|
129
|
+
|
130
|
+
The deploy will also created the ECS service if the service does not yet exist on the cluster. The deploy will prompt you for the ELB `--target-group` if you are shipping a web container that does not yet exist. If it is not a web container the `--target-group` option gets ignored.
|
131
|
+
|
132
|
+
The prommpt can be bypassed by specifying a valid `--target-group` option or specifying the `---no-elb-prompt` option.
|
133
|
+
|
134
|
+
$ ufo ship hi-web-prod --target-group arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/hi-web-prod/jsdlfjsdkd
|
135
|
+
|
136
|
+
$ ufo ship hi-web-prod --no-elb-prompt
|
137
|
+
EOL
|
138
|
+
end
|
139
|
+
|
140
|
+
def destroy
|
141
|
+
<<-EOL
|
142
|
+
Examples:
|
143
|
+
|
144
|
+
Destroys the service. It will automatcally set the desired task size to 0 and stop all task so the destory happens in one command.
|
145
|
+
|
146
|
+
$ ufo destroy hi-web-prod
|
147
|
+
|
148
|
+
EOL
|
149
|
+
end
|
150
|
+
|
151
|
+
def scale
|
152
|
+
<<-EOL
|
153
|
+
Examples:
|
154
|
+
|
155
|
+
Scales the service. Simple wrapper for `aws ecs update-service --service xxx ----desired-count xxx`
|
156
|
+
|
157
|
+
$ ufo scale hi-web-prod 5
|
158
|
+
|
159
|
+
EOL
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|