ecs_deployer 2.0.0 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/README.md +20 -47
- data/config.local.yml +6 -0
- data/config.yml +6 -0
- data/ecs_deployer.gemspec +4 -6
- data/example/register_task.rb +11 -0
- data/example/update_scheduled_task.rb +17 -0
- data/example/update_service.rb +13 -0
- data/lib/ecs_deployer.rb +8 -2
- data/lib/ecs_deployer/cli.rb +16 -17
- data/lib/ecs_deployer/client.rb +12 -244
- data/lib/ecs_deployer/scheduled_task/client.rb +55 -0
- data/lib/ecs_deployer/scheduled_task/target.rb +64 -0
- data/lib/ecs_deployer/service/client.rb +155 -0
- data/lib/ecs_deployer/task/client.rb +99 -0
- data/lib/ecs_deployer/util/cipher.rb +44 -0
- data/lib/ecs_deployer/version.rb +1 -1
- metadata +44 -35
- data/example/sample.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53c73ee2931e45cc8f3db8a292cef5f467d08895
|
4
|
+
data.tar.gz: e5e00d7575c48223a3f6952ba03338b2ed504c7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f664e88c2e5dbe349f72cf2cbbb683496f9facba1a8b7592944c5c93cf9d0954ee6ea71ac2c540233f959783a16dd56c17e5bd1cfccfe2c85c8cc360d66b3dc0
|
7
|
+
data.tar.gz: ba609ad07fb2f6f4a1319fc6ba6592e3d6f18a5a4de0af96ad01216c3f987e322b31d3d28730b8d64280a097edf5e0bb1e23dbbeb9ac094da924d3bb34a0728b
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
-
#
|
1
|
+
# ECS Deployer
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/ecs_deployer)
|
4
4
|
[](https://codeclimate.com/github/naomichi-y/ecs_deployer/coverage)
|
5
5
|
[](https://codeclimate.com/github/naomichi-y/ecs_deployer)
|
6
6
|
[](https://circleci.com/gh/naomichi-y/ecs_deployer/tree/master)
|
7
7
|
|
8
|
-
* [Description](#description)
|
9
|
-
* [Installation](#installation)
|
10
|
-
* [Task definition](#task-definition)
|
11
|
-
* [Encrypt of environment variables](#encrypt-of-environment-variables)
|
12
|
-
* [Usage](#usage)
|
13
|
-
* [API](#api)
|
14
|
-
* [CLI](#cli)
|
15
|
-
* [Register new task](#register-new-task)
|
16
|
-
* [Encrypt environment value](#encrypt-environment-value)
|
17
|
-
* [Decrypt environment value](#decrypt-environment-value)
|
18
|
-
* [Update service](#update-service)
|
19
|
-
|
20
8
|
## Description
|
21
9
|
|
22
|
-
Deploy Docker container on AWS ECS
|
10
|
+
Deploy Docker container on AWS ECS.
|
11
|
+
|
12
|
+
* Task
|
13
|
+
* Create
|
14
|
+
* Service
|
15
|
+
* Update
|
16
|
+
* scheduled task
|
17
|
+
* Create
|
18
|
+
* Update
|
23
19
|
|
24
20
|
## Installation
|
25
21
|
|
@@ -47,26 +43,15 @@ Write task definition in YAML format.
|
|
47
43
|
For available parameters see [Task Definition Parameters](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html).
|
48
44
|
|
49
45
|
```yaml
|
46
|
+
family: nginx
|
50
47
|
container_definitions:
|
51
|
-
- name:
|
52
|
-
|
53
|
-
- mysql
|
54
|
-
image: wordpress
|
48
|
+
- name: web
|
49
|
+
image: nginx:{{tag}}
|
55
50
|
essential: true
|
56
51
|
port_mappings:
|
57
52
|
- container_port: 80
|
58
|
-
|
59
|
-
memory:
|
60
|
-
cpu: 10
|
61
|
-
- environment:
|
62
|
-
- name: MYSQL_ROOT_PASSWORD
|
63
|
-
value: password
|
64
|
-
name: mysql
|
65
|
-
image: mysql
|
66
|
-
cpu: 10
|
67
|
-
memory: 512
|
68
|
-
essential: true
|
69
|
-
family: hello_world
|
53
|
+
host_port: 80
|
54
|
+
memory: 256
|
70
55
|
```
|
71
56
|
|
72
57
|
### Encrypt of environment variables
|
@@ -86,21 +71,7 @@ Values are decrypted when task is created.
|
|
86
71
|
|
87
72
|
### API
|
88
73
|
|
89
|
-
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
deployer = EcsDeployer::Client.new
|
93
|
-
deployer.register_task('development.yml')
|
94
|
-
deployer.update_service('cluster', 'development')
|
95
|
-
```
|
96
|
-
|
97
|
-
`{{xxx}}` parameter is construed variable.
|
98
|
-
|
99
|
-
```yaml
|
100
|
-
container_definitions:
|
101
|
-
- name: wordpress
|
102
|
-
image: wordpress:{{tag}}
|
103
|
-
```
|
74
|
+
Refer to [sample code](https://github.com/naomichi-y/ecs_deployer/tree/master/example).
|
104
75
|
|
105
76
|
```ruby
|
106
77
|
deployer.register_task('development.yml', tag: 'latest')
|
@@ -108,11 +79,13 @@ deployer.register_task('development.yml', tag: 'latest')
|
|
108
79
|
|
109
80
|
### CLI
|
110
81
|
|
82
|
+
Please create `.env` from `.env.default` file, before running.
|
83
|
+
|
111
84
|
#### Register new task
|
112
85
|
|
113
86
|
```bash
|
114
87
|
$ bundle exec ecs_deployer task-register --path=spec/fixtures/task.yml --replace-variables=tag:latest
|
115
|
-
Registered task: arn:aws:ecs:ap-northeast-1:xxx:task-definition/
|
88
|
+
Registered task: arn:aws:ecs:ap-northeast-1:xxx:task-definition/nginx:latest
|
116
89
|
```
|
117
90
|
|
118
91
|
#### Encrypt environment value
|
@@ -132,7 +105,7 @@ Decrypted value: xxx
|
|
132
105
|
#### Update service
|
133
106
|
|
134
107
|
```bash
|
135
|
-
$ bundle exec ecs_deployer update-service --cluster=xxx --service=xxx --wait --timeout=600
|
108
|
+
$ bundle exec ecs_deployer update-service --cluster=xxx --service=xxx --wait --wait-timeout=600
|
136
109
|
Start deploying...
|
137
110
|
Deploying... [0/1] (20 seconds elapsed)
|
138
111
|
New task: arn:aws:ecs:ap-northeast-1:xxxx:task-definition/sandbox-development:68
|
data/config.local.yml
ADDED
data/config.yml
ADDED
data/ecs_deployer.gemspec
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
1
|
lib = File.expand_path('../lib', __FILE__)
|
4
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
3
|
require 'ecs_deployer/version'
|
@@ -31,15 +29,15 @@ Gem::Specification.new do |spec|
|
|
31
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
30
|
spec.require_paths = ['lib']
|
33
31
|
|
32
|
+
spec.add_dependency 'aws-sdk', '>= 2.9.0'
|
33
|
+
spec.add_dependency 'aws_config', '~> 0.1'
|
34
34
|
spec.add_dependency 'oj', '~> 3.0'
|
35
35
|
spec.add_dependency 'thor', '~> 0.19'
|
36
|
-
spec.add_dependency 'aws-sdk', '~> 2.9'
|
37
|
-
spec.add_dependency 'aws_config', '~> 0.1'
|
38
36
|
spec.add_development_dependency 'bundler', '~> 1.13'
|
37
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
38
|
+
spec.add_development_dependency 'config', '~> 1.5.1'
|
39
39
|
spec.add_development_dependency 'rake', '~> 10.0'
|
40
40
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
41
|
-
spec.add_development_dependency 'json_spec', '~> 1.1'
|
42
41
|
spec.add_development_dependency 'rubocop', '~> 0.48'
|
43
42
|
spec.add_development_dependency 'simplecov', '~> 0.14'
|
44
|
-
spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
45
43
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'ecs_deployer'
|
3
|
+
require 'config'
|
4
|
+
|
5
|
+
Config.load_and_set_settings('config.yml', 'config.local.yml')
|
6
|
+
|
7
|
+
task_path = File.expand_path(Settings.task_path)
|
8
|
+
deployer = EcsDeployer::Client.new(Settings.cluster)
|
9
|
+
task_definition = deployer.task.register(task_path, tag: 'latest')
|
10
|
+
|
11
|
+
puts task_definition.task_definition_arn
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'ecs_deployer'
|
3
|
+
require 'config'
|
4
|
+
|
5
|
+
Config.load_and_set_settings('config.yml', 'config.local.yml')
|
6
|
+
task_path = File.expand_path(Settings.scheduled_task_path)
|
7
|
+
|
8
|
+
deployer = EcsDeployer::Client.new(Settings.cluster)
|
9
|
+
task_definition = deployer.task.register(task_path, tag: 'latest')
|
10
|
+
|
11
|
+
scheduled_task = deployer.scheduled_task
|
12
|
+
target_builder = scheduled_task.target_builder(Settings.scheduled_task_target_id)
|
13
|
+
target_builder.task_definition_arn = task_definition.task_definition_arn
|
14
|
+
target_builder.override_container('rails', ['curl', 'http://153.122.13.159/'])
|
15
|
+
|
16
|
+
task_definition = scheduled_task.update(Settings.scheduled_task_rule, 'cron(* * * * ? *)', [target_builder.to_hash])
|
17
|
+
puts task_definition.rule_arn
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'ecs_deployer'
|
3
|
+
require 'config'
|
4
|
+
|
5
|
+
Config.load_and_set_settings('config.yml', 'config.local.yml')
|
6
|
+
|
7
|
+
task_path = File.expand_path(Settings.task_path)
|
8
|
+
|
9
|
+
deployer = EcsDeployer::Client.new(Settings.cluster)
|
10
|
+
task_definition = deployer.task.register(task_path, tag: 'latest')
|
11
|
+
service = deployer.service.update(Settings.service, task_definition)
|
12
|
+
|
13
|
+
puts service.service_arn
|
data/lib/ecs_deployer.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
require 'ecs_deployer/version'
|
2
1
|
require 'ecs_deployer/client'
|
3
|
-
require 'ecs_deployer/error'
|
4
2
|
require 'ecs_deployer/cli'
|
3
|
+
require 'ecs_deployer/error'
|
4
|
+
require 'ecs_deployer/service/client'
|
5
|
+
require 'ecs_deployer/task/client'
|
6
|
+
require 'ecs_deployer/scheduled_task/client'
|
7
|
+
require 'ecs_deployer/scheduled_task/target'
|
8
|
+
require 'ecs_deployer/util/cipher'
|
9
|
+
require 'ecs_deployer/version'
|
5
10
|
|
6
11
|
module EcsDeployer
|
12
|
+
class ClusterNotFoundError < EcsDeployer::Error; end
|
7
13
|
class ServiceNotFoundError < EcsDeployer::Error; end
|
8
14
|
class TaskRunningError < EcsDeployer::Error; end
|
9
15
|
class TaskDefinitionValidateError < EcsDeployer::Error; end
|
data/lib/ecs_deployer/cli.rb
CHANGED
@@ -7,11 +7,9 @@ module EcsDeployer
|
|
7
7
|
|
8
8
|
no_commands do
|
9
9
|
def prepare
|
10
|
-
aws_options = {}
|
11
|
-
aws_options[:profile] = options[:profile] if options[:profile]
|
12
|
-
aws_options[:region] = options[:region] if options[:region]
|
13
|
-
|
14
|
-
@deployer = EcsDeployer::Client.new(aws_options)
|
10
|
+
@aws_options = {}
|
11
|
+
@aws_options[:profile] = options[:profile] if options[:profile]
|
12
|
+
@aws_options[:region] = options[:region] if options[:region]
|
15
13
|
|
16
14
|
nil
|
17
15
|
end
|
@@ -27,38 +25,39 @@ module EcsDeployer
|
|
27
25
|
option :replace_variables, type: :hash, default: {}
|
28
26
|
def task_register
|
29
27
|
path = File.expand_path(options[:path], Dir.pwd)
|
30
|
-
|
28
|
+
task_client = EcsDeployer::Task::Client.new(@aws_options)
|
29
|
+
result = task_client.register(path, options[:replace_variables])
|
31
30
|
|
32
|
-
puts "Registered task: #{result}"
|
31
|
+
puts "Registered task: #{result.task_definition_arn}"
|
33
32
|
end
|
34
33
|
|
35
34
|
desc 'update-service', 'Update service difinition.'
|
36
35
|
option :cluster, required: true
|
37
36
|
option :service, required: true
|
38
37
|
option :wait, type: :boolean, default: true
|
39
|
-
option :
|
38
|
+
option :wait_timeout, type: :numeric, default: 600
|
40
39
|
def update_service
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
options[:wait]
|
46
|
-
)
|
40
|
+
deploy_client = EcsDeployer::Client.new(options[:cluster], nil, @aws_options)
|
41
|
+
service_client = deploy_client.service
|
42
|
+
service_client.wait_timeout = options[:wait_timeout]
|
43
|
+
result = service_client.update(options[:service], nil, options[:wait])
|
47
44
|
|
48
|
-
puts "Update service: #{result}"
|
45
|
+
puts "Update service: #{result.service_arn}"
|
49
46
|
end
|
50
47
|
|
51
48
|
desc 'encrypt', 'Encrypt value of argument with KMS.'
|
52
49
|
option :master_key, required: true
|
53
50
|
option :value, required: true
|
54
51
|
def encrypt
|
55
|
-
|
52
|
+
cipher = EcsDeployer::Util::Cipher.new(@aws_options)
|
53
|
+
puts "Encrypted value: #{cipher.encrypt(options[:master_key], options[:value])}"
|
56
54
|
end
|
57
55
|
|
58
56
|
desc 'decrypt', 'Decrypt value of argument with KMS.'
|
59
57
|
option :value, required: true
|
60
58
|
def decrypt
|
61
|
-
|
59
|
+
cipher = EcsDeployer::Util::Cipher.new(@aws_options)
|
60
|
+
puts "Decrypted value: #{cipher.decrypt(options[:value])}"
|
62
61
|
end
|
63
62
|
end
|
64
63
|
end
|
data/lib/ecs_deployer/client.rb
CHANGED
@@ -1,262 +1,30 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'oj'
|
3
|
-
require 'aws-sdk'
|
4
|
-
require 'base64'
|
5
1
|
require 'logger'
|
6
2
|
|
7
3
|
module EcsDeployer
|
8
4
|
class Client
|
9
|
-
LOG_SEPARATOR = '-' * 96
|
10
|
-
ENCRYPT_PATTERN = /^\${(.+)}$/
|
11
|
-
|
12
|
-
attr_reader :ecs
|
13
|
-
attr_accessor :wait_timeout, :pauling_interval
|
14
|
-
|
15
5
|
# @param [String] cluster
|
16
6
|
# @param [Logger] logger
|
7
|
+
# @param [Hash] aws_options
|
17
8
|
# @return [EcsDeployer::Client]
|
18
9
|
def initialize(cluster, logger = nil, aws_options = {})
|
19
10
|
@cluster = cluster
|
20
|
-
@logger = logger.nil? ? Logger.new(
|
21
|
-
@
|
22
|
-
@kms = Aws::KMS::Client.new(aws_options)
|
23
|
-
@wait_timeout = 900
|
24
|
-
@pauling_interval = 20
|
25
|
-
end
|
26
|
-
|
27
|
-
# @param [String] mater_key
|
28
|
-
# @param [String] value
|
29
|
-
# @return [String]
|
30
|
-
def encrypt(master_key, value)
|
31
|
-
encode = @kms.encrypt(key_id: "alias/#{master_key}", plaintext: value)
|
32
|
-
"${#{Base64.strict_encode64(encode.ciphertext_blob)}}"
|
33
|
-
rescue => e
|
34
|
-
raise KmsEncryptError, e.to_s
|
35
|
-
end
|
36
|
-
|
37
|
-
# @param [String] value
|
38
|
-
# @return [String]
|
39
|
-
def decrypt(value)
|
40
|
-
match = value.match(ENCRYPT_PATTERN)
|
41
|
-
raise KmsDecryptError, 'Encrypted string is invalid.' unless match
|
42
|
-
|
43
|
-
begin
|
44
|
-
@kms.decrypt(ciphertext_blob: Base64.strict_decode64(match[1])).plaintext
|
45
|
-
rescue => e
|
46
|
-
raise KmsDecryptError, e.to_s
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# @param [String] path
|
51
|
-
# @param [Hash] replace_variables
|
52
|
-
# @return [String]
|
53
|
-
def register_task(path, replace_variables = {})
|
54
|
-
raise IOError, "File does not exist. [#{path}]" unless File.exist?(path)
|
55
|
-
|
56
|
-
register_task_hash(YAML.load(File.read(path)), replace_variables)
|
57
|
-
end
|
58
|
-
|
59
|
-
# @param [Hash] task_definition
|
60
|
-
# @param [Hash] replace_variables
|
61
|
-
# @return [Aws::ECS::Types::TaskDefinition]
|
62
|
-
def register_task_hash(task_definition, replace_variables = {})
|
63
|
-
task_definition = Oj.load(Oj.dump(task_definition), symbol_keys: true)
|
64
|
-
|
65
|
-
replace_parameter_variables!(task_definition, replace_variables)
|
66
|
-
decrypt_environment_variables!(task_definition)
|
67
|
-
|
68
|
-
result = @ecs.register_task_definition(
|
69
|
-
container_definitions: task_definition[:container_definitions],
|
70
|
-
family: task_definition[:family],
|
71
|
-
task_role_arn: task_definition[:task_role_arn],
|
72
|
-
volumes: task_definition[:volumes]
|
73
|
-
)
|
74
|
-
|
75
|
-
result[:task_definition]
|
11
|
+
@logger = logger.nil? ? Logger.new(nil) : logger
|
12
|
+
@aws_options = aws_options
|
76
13
|
end
|
77
14
|
|
78
|
-
# @
|
79
|
-
|
80
|
-
|
81
|
-
result = @ecs.describe_services(
|
82
|
-
cluster: @cluster,
|
83
|
-
services: [service]
|
84
|
-
)
|
85
|
-
|
86
|
-
result[:services].each do |svc|
|
87
|
-
next unless svc[:service_name] == service
|
88
|
-
|
89
|
-
result = @ecs.describe_task_definition(
|
90
|
-
task_definition: svc[:task_definition]
|
91
|
-
)
|
92
|
-
|
93
|
-
return register_task_hash(result[:task_definition].to_hash)
|
94
|
-
end
|
95
|
-
|
96
|
-
raise ServiceNotFoundError, "'#{service}' service is not found."
|
15
|
+
# @return [EcsDeployer::Task::Client]
|
16
|
+
def task
|
17
|
+
EcsDeployer::Task::Client.new(@aws_options)
|
97
18
|
end
|
98
19
|
|
99
|
-
# @
|
100
|
-
|
101
|
-
|
102
|
-
def update_service(service, task_definition = nil, wait = true)
|
103
|
-
task_definition = register_clone_task(service) if task_definition.nil?
|
104
|
-
result = @ecs.update_service(
|
105
|
-
cluster: @cluster,
|
106
|
-
service: service,
|
107
|
-
task_definition: task_definition[:family] + ':' + task_definition[:revision].to_s
|
108
|
-
)
|
109
|
-
|
110
|
-
wait_for_deploy(service, result.service.task_definition) if wait
|
111
|
-
result.service.service_arn
|
112
|
-
end
|
113
|
-
|
114
|
-
private
|
115
|
-
|
116
|
-
# @param [Array, Hash] variables
|
117
|
-
# @param [Hash] replace_variables
|
118
|
-
def replace_parameter_variables!(variables, replace_variables = {})
|
119
|
-
for variable in variables do
|
120
|
-
if variable.class == Array || variable.class == Hash
|
121
|
-
replace_parameter_variables!(variable, replace_variables)
|
122
|
-
elsif variable.class == String
|
123
|
-
replace_variables.each do |replace_key, replace_value|
|
124
|
-
variable.gsub!("{{#{replace_key}}}", replace_value)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# @param [Hash] task_definition
|
131
|
-
def decrypt_environment_variables!(task_definition)
|
132
|
-
raise TaskDefinitionValidateError, '\'container_definition\' is undefined.' unless task_definition.key?(:container_definitions)
|
133
|
-
task_definition[:container_definitions].each do |container_definition|
|
134
|
-
next unless container_definition.key?(:environment)
|
135
|
-
|
136
|
-
container_definition[:environment].each do |environment|
|
137
|
-
if environment[:value].class == String
|
138
|
-
match = environment[:value].match(ENCRYPT_PATTERN)
|
139
|
-
environment[:value] = decrypt(match[0]) if match
|
140
|
-
else
|
141
|
-
# https://github.com/naomichi-y/ecs_deployer/issues/6
|
142
|
-
environment[:value] = environment[:value].to_s
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
20
|
+
# @return [EcsDeployer::ScheduledTask::Client]
|
21
|
+
def scheduled_task
|
22
|
+
EcsDeployer::ScheduledTask::Client.new(@cluster, @aws_options)
|
146
23
|
end
|
147
24
|
|
148
|
-
# @
|
149
|
-
|
150
|
-
|
151
|
-
status = nil
|
152
|
-
result = @ecs.describe_services(
|
153
|
-
cluster: @cluster,
|
154
|
-
services: [service]
|
155
|
-
)
|
156
|
-
result[:services].each do |svc|
|
157
|
-
next unless svc[:service_name] == service
|
158
|
-
status = svc
|
159
|
-
break
|
160
|
-
end
|
161
|
-
|
162
|
-
raise ServiceNotFoundError, "'#{service}' service is not found." if status.nil?
|
163
|
-
|
164
|
-
status
|
165
|
-
end
|
166
|
-
|
167
|
-
# @param [String] service
|
168
|
-
# @param [String] task_definition_arn
|
169
|
-
def detect_stopped_task(service, task_definition_arn)
|
170
|
-
stopped_tasks = @ecs.list_tasks(
|
171
|
-
cluster: @cluster,
|
172
|
-
service_name: service,
|
173
|
-
desired_status: 'STOPPED'
|
174
|
-
).task_arns
|
175
|
-
|
176
|
-
return if stopped_tasks.size.zero?
|
177
|
-
|
178
|
-
description_tasks = @ecs.describe_tasks(
|
179
|
-
cluster: @cluster,
|
180
|
-
tasks: stopped_tasks
|
181
|
-
).tasks
|
182
|
-
|
183
|
-
description_tasks.each do |task|
|
184
|
-
raise TaskStoppedError, task.stopped_reason if task.task_definition_arn == task_definition_arn
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
# @param [String] service
|
189
|
-
# @param [String] task_definition_arn
|
190
|
-
# @return [Hash]
|
191
|
-
def deploy_status(service, task_definition_arn)
|
192
|
-
detect_stopped_task(service, task_definition_arn)
|
193
|
-
|
194
|
-
# Get current tasks
|
195
|
-
result = @ecs.list_tasks(
|
196
|
-
cluster: @cluster,
|
197
|
-
service_name: service,
|
198
|
-
desired_status: 'RUNNING'
|
199
|
-
)
|
200
|
-
|
201
|
-
raise TaskRunningError, 'Running task not found.' if result[:task_arns].size.zero?
|
202
|
-
|
203
|
-
result = @ecs.describe_tasks(
|
204
|
-
cluster: @cluster,
|
205
|
-
tasks: result[:task_arns]
|
206
|
-
)
|
207
|
-
|
208
|
-
new_running_count = 0
|
209
|
-
task_status_logs = []
|
210
|
-
|
211
|
-
result[:tasks].each do |task|
|
212
|
-
new_running_count += 1 if task_definition_arn == task[:task_definition_arn] && task[:last_status] == 'RUNNING'
|
213
|
-
task_status_logs << " #{task[:task_definition_arn]} [#{task[:last_status]}]"
|
214
|
-
end
|
215
|
-
|
216
|
-
{
|
217
|
-
current_running_count: result[:tasks].size,
|
218
|
-
new_running_count: new_running_count,
|
219
|
-
task_status_logs: task_status_logs
|
220
|
-
}
|
221
|
-
end
|
222
|
-
|
223
|
-
# @param [String] service
|
224
|
-
# @param [String] task_definition_arn
|
225
|
-
def wait_for_deploy(service, task_definition_arn)
|
226
|
-
service_status = service_status(service)
|
227
|
-
|
228
|
-
wait_time = 0
|
229
|
-
@logger.info 'Start deploying...'
|
230
|
-
|
231
|
-
loop do
|
232
|
-
sleep(@pauling_interval)
|
233
|
-
wait_time += @pauling_interval
|
234
|
-
result = deploy_status(service, task_definition_arn)
|
235
|
-
|
236
|
-
@logger.info "Deploying... [#{result[:new_running_count]}/#{result[:current_running_count]}] (#{wait_time} seconds elapsed)"
|
237
|
-
@logger.info "New task: #{task_definition_arn}"
|
238
|
-
@logger.info LOG_SEPARATOR
|
239
|
-
|
240
|
-
result[:task_status_logs].each do |log|
|
241
|
-
@logger.info log
|
242
|
-
end
|
243
|
-
|
244
|
-
@logger.info LOG_SEPARATOR
|
245
|
-
|
246
|
-
if result[:new_running_count] == result[:current_running_count]
|
247
|
-
@logger.info "Service update succeeded. [#{result[:new_running_count]}/#{result[:current_running_count]}]"
|
248
|
-
@logger.info "New task definition: #{task_definition_arn}"
|
249
|
-
|
250
|
-
break
|
251
|
-
else
|
252
|
-
@logger.info 'You can stop process with Ctrl+C. Deployment will continue.'
|
253
|
-
|
254
|
-
if wait_time > @wait_timeout
|
255
|
-
@logger.info "New task definition: #{task_definition_arn}"
|
256
|
-
raise DeployTimeoutError, 'Service is being updating, but process is timed out.'
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
25
|
+
# @return [EcsDeployer::Service::Client]
|
26
|
+
def service
|
27
|
+
EcsDeployer::Service::Client.new(@cluster, @logger, @aws_options)
|
260
28
|
end
|
261
29
|
end
|
262
30
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module EcsDeployer
|
4
|
+
module ScheduledTask
|
5
|
+
class Client
|
6
|
+
# @param [String] cluster
|
7
|
+
# @param [Hash] aws_options
|
8
|
+
# @return [EcsDeployer::ScheduledTask::Client]
|
9
|
+
def initialize(cluster, aws_options = {})
|
10
|
+
@cluster = cluster
|
11
|
+
@cloud_watch_events = Aws::CloudWatchEvents::Client.new(aws_options)
|
12
|
+
@aws_options = aws_options
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [String] rule
|
16
|
+
# @return [Bool]
|
17
|
+
def exist_rule?(rule)
|
18
|
+
@cloud_watch_events.describe_rule(name: rule)
|
19
|
+
true
|
20
|
+
rescue Aws::CloudWatchEvents::Errors::ResourceNotFoundException
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [String] id
|
25
|
+
# @param [String] role
|
26
|
+
# @return [EcsDeployer::ScheduledTask::Target]
|
27
|
+
def target_builder(id, role = 'ecsEventsRole')
|
28
|
+
EcsDeployer::ScheduledTask::Target.new(@cluster, id, role, @aws_options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [String] rule
|
32
|
+
# @param [String] schedule_expression
|
33
|
+
# @param [Array] targets
|
34
|
+
# @return [CloudWatchEvents::Types::PutRuleResponse]
|
35
|
+
def update(rule, schedule_expression, targets)
|
36
|
+
response = @cloud_watch_events.put_rule(
|
37
|
+
name: rule,
|
38
|
+
schedule_expression: schedule_expression,
|
39
|
+
state: 'ENABLED'
|
40
|
+
)
|
41
|
+
begin
|
42
|
+
@cloud_watch_events.put_targets(
|
43
|
+
rule: rule,
|
44
|
+
targets: targets
|
45
|
+
)
|
46
|
+
|
47
|
+
response
|
48
|
+
rescue => e
|
49
|
+
@cloud_watch_events.delete_rule(name: rule)
|
50
|
+
raise e
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module EcsDeployer
|
2
|
+
module ScheduledTask
|
3
|
+
class Target
|
4
|
+
attr_reader :id
|
5
|
+
attr_accessor :arn, :role_arn, :task_definition_arn, :task_count
|
6
|
+
|
7
|
+
# @param [String] cluster
|
8
|
+
# @param [String] id
|
9
|
+
# @param [String] role
|
10
|
+
# @param [Hash] aws_options
|
11
|
+
# @return EcsDeployer::ScheduledTask::Target]
|
12
|
+
def initialize(cluster, id, role = nil, aws_options = {})
|
13
|
+
ecs = Aws::ECS::Client.new(aws_options)
|
14
|
+
clusters = ecs.describe_clusters(clusters: [cluster]).clusters
|
15
|
+
raise ClusterNotFoundError, "Cluster does not eixst. [#{cluster}]" if clusters.count.zero?
|
16
|
+
|
17
|
+
@id = id
|
18
|
+
@arn = clusters[0].cluster_arn
|
19
|
+
@role_arn = Aws::IAM::Role.new(role, @aws_options).arn unless role.nil?
|
20
|
+
@task_count = 1
|
21
|
+
@container_overrides = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [String] name
|
25
|
+
# @param [Array] command
|
26
|
+
# @param [Hash] environments
|
27
|
+
def override_container(name, command = nil, environments = {})
|
28
|
+
override_environments = []
|
29
|
+
environments.each do |environment|
|
30
|
+
environment.each do |env_name, env_value|
|
31
|
+
override_environments << {
|
32
|
+
name: env_name,
|
33
|
+
value: env_value
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
container_override = {
|
39
|
+
name: name,
|
40
|
+
command: command
|
41
|
+
}
|
42
|
+
container_overrides[:environment] = override_environments if override_environments.count > 0
|
43
|
+
|
44
|
+
@container_overrides << container_override
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Hash]
|
48
|
+
def to_hash
|
49
|
+
{
|
50
|
+
id: @id,
|
51
|
+
arn: @arn,
|
52
|
+
role_arn: @role_arn,
|
53
|
+
ecs_parameters: {
|
54
|
+
task_definition_arn: @task_definition_arn,
|
55
|
+
task_count: @task_count
|
56
|
+
},
|
57
|
+
input: {
|
58
|
+
containerOverrides: @container_overrides
|
59
|
+
}.to_json.to_s
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module EcsDeployer
|
4
|
+
module Service
|
5
|
+
class Client
|
6
|
+
LOG_SEPARATOR = '-' * 96
|
7
|
+
|
8
|
+
attr_accessor :wait_timeout, :polling_interval
|
9
|
+
|
10
|
+
# @param [String] cluster
|
11
|
+
# @param [Logger] logger
|
12
|
+
# @param [Hash] aws_options
|
13
|
+
# @return [EcsDeployer::Service::Client]
|
14
|
+
def initialize(cluster, logger, aws_options = {})
|
15
|
+
@cluster = cluster
|
16
|
+
@logger = logger
|
17
|
+
|
18
|
+
@ecs = Aws::ECS::Client.new(aws_options)
|
19
|
+
@task = EcsDeployer::Task::Client.new(aws_options)
|
20
|
+
|
21
|
+
@wait_timeout = 900
|
22
|
+
@polling_interval = 20
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [String] service
|
26
|
+
# @param [Aws::ECS::Types::TaskDefinition] task_definition
|
27
|
+
# @return [Aws::ECS::Types::Service]
|
28
|
+
def update(service, task_definition = nil, wait = true)
|
29
|
+
task_definition = @task.register_clone(@cluster, service) if task_definition.nil?
|
30
|
+
result = @ecs.update_service(
|
31
|
+
cluster: @cluster,
|
32
|
+
service: service,
|
33
|
+
task_definition: task_definition[:family] + ':' + task_definition[:revision].to_s
|
34
|
+
)
|
35
|
+
|
36
|
+
wait_for_deploy(service, result.service.task_definition) if wait
|
37
|
+
result.service
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @param [String] service
|
43
|
+
# @return [Bool]
|
44
|
+
def exist?(service)
|
45
|
+
status = nil
|
46
|
+
result = @ecs.describe_services(
|
47
|
+
cluster: @cluster,
|
48
|
+
services: [service]
|
49
|
+
)
|
50
|
+
result[:services].each do |svc|
|
51
|
+
next unless svc[:service_name] == service
|
52
|
+
status = svc
|
53
|
+
break
|
54
|
+
end
|
55
|
+
|
56
|
+
status.nil? ? false : true
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param [String] service
|
60
|
+
# @param [String] task_definition_arn
|
61
|
+
def detect_stopped_task(service, task_definition_arn)
|
62
|
+
stopped_tasks = @ecs.list_tasks(
|
63
|
+
cluster: @cluster,
|
64
|
+
service_name: service,
|
65
|
+
desired_status: 'STOPPED'
|
66
|
+
).task_arns
|
67
|
+
|
68
|
+
return if stopped_tasks.size.zero?
|
69
|
+
|
70
|
+
description_tasks = @ecs.describe_tasks(
|
71
|
+
cluster: @cluster,
|
72
|
+
tasks: stopped_tasks
|
73
|
+
).tasks
|
74
|
+
|
75
|
+
description_tasks.each do |task|
|
76
|
+
raise TaskStoppedError, task.stopped_reason if task.task_definition_arn == task_definition_arn
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [String] service
|
81
|
+
# @param [String] task_definition_arn
|
82
|
+
# @return [Hash]
|
83
|
+
def deploy_status(service, task_definition_arn)
|
84
|
+
detect_stopped_task(service, task_definition_arn)
|
85
|
+
|
86
|
+
# Get current tasks
|
87
|
+
result = @ecs.list_tasks(
|
88
|
+
cluster: @cluster,
|
89
|
+
service_name: service,
|
90
|
+
desired_status: 'RUNNING'
|
91
|
+
)
|
92
|
+
|
93
|
+
raise TaskRunningError, 'Running task not found.' if result[:task_arns].size.zero?
|
94
|
+
|
95
|
+
result = @ecs.describe_tasks(
|
96
|
+
cluster: @cluster,
|
97
|
+
tasks: result[:task_arns]
|
98
|
+
)
|
99
|
+
|
100
|
+
new_running_count = 0
|
101
|
+
task_status_logs = []
|
102
|
+
|
103
|
+
result[:tasks].each do |task|
|
104
|
+
new_running_count += 1 if task_definition_arn == task[:task_definition_arn] && task[:last_status] == 'RUNNING'
|
105
|
+
task_status_logs << " #{task[:task_definition_arn]} [#{task[:last_status]}]"
|
106
|
+
end
|
107
|
+
|
108
|
+
{
|
109
|
+
current_running_count: result[:tasks].size,
|
110
|
+
new_running_count: new_running_count,
|
111
|
+
task_status_logs: task_status_logs
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
# @param [String] service
|
116
|
+
# @param [String] task_definition_arn
|
117
|
+
def wait_for_deploy(service, task_definition_arn)
|
118
|
+
raise ServiceNotFoundError, "'#{service}' service is not found." unless exist?(service)
|
119
|
+
|
120
|
+
wait_time = 0
|
121
|
+
@logger.info 'Start deploying...'
|
122
|
+
|
123
|
+
loop do
|
124
|
+
sleep(@polling_interval)
|
125
|
+
wait_time += @polling_interval
|
126
|
+
result = deploy_status(service, task_definition_arn)
|
127
|
+
|
128
|
+
@logger.info "Deploying... [#{result[:new_running_count]}/#{result[:current_running_count]}] (#{wait_time} seconds elapsed)"
|
129
|
+
@logger.info "New task: #{task_definition_arn}"
|
130
|
+
@logger.info LOG_SEPARATOR
|
131
|
+
|
132
|
+
result[:task_status_logs].each do |log|
|
133
|
+
@logger.info log
|
134
|
+
end
|
135
|
+
|
136
|
+
@logger.info LOG_SEPARATOR
|
137
|
+
|
138
|
+
if result[:new_running_count] == result[:current_running_count]
|
139
|
+
@logger.info "Service update succeeded. [#{result[:new_running_count]}/#{result[:current_running_count]}]"
|
140
|
+
@logger.info "New task definition: #{task_definition_arn}"
|
141
|
+
|
142
|
+
break
|
143
|
+
else
|
144
|
+
@logger.info 'You can stop process with Ctrl+C. Deployment will continue.'
|
145
|
+
|
146
|
+
if wait_time > @wait_timeout
|
147
|
+
@logger.info "New task definition: #{task_definition_arn}"
|
148
|
+
raise DeployTimeoutError, 'Service is being updating, but process is timed out.'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'yaml'
|
3
|
+
require 'oj'
|
4
|
+
|
5
|
+
module EcsDeployer
|
6
|
+
module Task
|
7
|
+
class Client
|
8
|
+
# @param [Hash] aws_options
|
9
|
+
# @return [EcsDeployer::Task::Client]
|
10
|
+
def initialize(aws_options = {})
|
11
|
+
@ecs = Aws::ECS::Client.new(aws_options)
|
12
|
+
@cipher = EcsDeployer::Util::Cipher.new(aws_options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [String] path
|
16
|
+
# @param [Hash] replace_variables
|
17
|
+
# @return [Aws::ECS::Types::TaskDefinition]
|
18
|
+
def register(path, replace_variables = {})
|
19
|
+
raise IOError, "File does not exist. [#{path}]" unless File.exist?(path)
|
20
|
+
|
21
|
+
register_hash(YAML.load(File.read(path)), replace_variables)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [Hash] task_definition
|
25
|
+
# @param [Hash] replace_variables
|
26
|
+
# @return [Aws::ECS::Types::TaskDefinition]
|
27
|
+
def register_hash(task_definition, replace_variables = {})
|
28
|
+
task_definition = Oj.load(Oj.dump(task_definition), symbol_keys: true)
|
29
|
+
|
30
|
+
replace_parameter_variables!(task_definition, replace_variables)
|
31
|
+
decrypt_environment_variables!(task_definition)
|
32
|
+
|
33
|
+
result = @ecs.register_task_definition(
|
34
|
+
container_definitions: task_definition[:container_definitions],
|
35
|
+
family: task_definition[:family],
|
36
|
+
task_role_arn: task_definition[:task_role_arn],
|
37
|
+
volumes: task_definition[:volumes]
|
38
|
+
)
|
39
|
+
|
40
|
+
result[:task_definition]
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param [String] cluster
|
44
|
+
# @param [String] service
|
45
|
+
# @return [String]
|
46
|
+
def register_clone(cluster, service)
|
47
|
+
result = @ecs.describe_services(
|
48
|
+
cluster: cluster,
|
49
|
+
services: [service]
|
50
|
+
)
|
51
|
+
|
52
|
+
result[:services].each do |svc|
|
53
|
+
next unless svc[:service_name] == service
|
54
|
+
|
55
|
+
result = @ecs.describe_task_definition(
|
56
|
+
task_definition: svc[:task_definition]
|
57
|
+
)
|
58
|
+
|
59
|
+
return register_hash(result[:task_definition].to_hash)
|
60
|
+
end
|
61
|
+
|
62
|
+
raise ServiceNotFoundError, "'#{service}' service is not found."
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# @param [Array, Hash] variables
|
68
|
+
# @param [Hash] replace_variables
|
69
|
+
def replace_parameter_variables!(variables, replace_variables = {})
|
70
|
+
for variable in variables do
|
71
|
+
if variable.class == Array || variable.class == Hash
|
72
|
+
replace_parameter_variables!(variable, replace_variables)
|
73
|
+
elsif variable.class == String
|
74
|
+
replace_variables.each do |replace_key, replace_value|
|
75
|
+
variable.gsub!("{{#{replace_key}}}", replace_value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @param [Hash] task_definition
|
82
|
+
def decrypt_environment_variables!(task_definition)
|
83
|
+
raise TaskDefinitionValidateError, '\'container_definition\' is undefined.' unless task_definition.key?(:container_definitions)
|
84
|
+
task_definition[:container_definitions].each do |container_definition|
|
85
|
+
next unless container_definition.key?(:environment)
|
86
|
+
|
87
|
+
container_definition[:environment].each do |environment|
|
88
|
+
if environment[:value].class == String
|
89
|
+
environment[:value] = @cipher.decrypt(environment[:value]) if @cipher.encrypt_value?(environment[:value])
|
90
|
+
else
|
91
|
+
# https://github.com/naomichi-y/ecs_deployer/issues/6
|
92
|
+
environment[:value] = environment[:value].to_s
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module EcsDeployer
|
4
|
+
module Util
|
5
|
+
class Cipher
|
6
|
+
ENCRYPT_VARIABLE_PATTERN = /^\${(.+)}$/
|
7
|
+
|
8
|
+
# @param [Hash] aws_options
|
9
|
+
# @return [EcsDeployer::Util::Cipher]
|
10
|
+
def initialize(aws_options = {})
|
11
|
+
@kms = Aws::KMS::Client.new(aws_options)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [String] mater_key
|
15
|
+
# @param [String] value
|
16
|
+
# @return [String]
|
17
|
+
def encrypt(master_key, value)
|
18
|
+
encode = @kms.encrypt(key_id: "alias/#{master_key}", plaintext: value)
|
19
|
+
"${#{Base64.strict_encode64(encode.ciphertext_blob)}}"
|
20
|
+
rescue => e
|
21
|
+
raise KmsEncryptError, e.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [String] value
|
25
|
+
# @return [String]
|
26
|
+
def decrypt(value)
|
27
|
+
match = value.match(ENCRYPT_VARIABLE_PATTERN)
|
28
|
+
raise KmsDecryptError, 'Encrypted string is invalid.' unless match
|
29
|
+
|
30
|
+
begin
|
31
|
+
@kms.decrypt(ciphertext_blob: Base64.strict_decode64(match[1])).plaintext
|
32
|
+
rescue => e
|
33
|
+
raise KmsDecryptError, e.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [String] value
|
38
|
+
# @return [Bool]
|
39
|
+
def encrypt_value?(value)
|
40
|
+
value.to_s.match(ENCRYPT_VARIABLE_PATTERN) ? true : false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/ecs_deployer/version.rb
CHANGED
metadata
CHANGED
@@ -1,71 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecs_deployer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- naomichi-y
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-10-
|
11
|
+
date: 2017-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: aws-sdk
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.9.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.9.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: aws_config
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
40
|
+
version: '0.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: oj
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '3.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '3.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: thor
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
61
|
+
version: '0.19'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0.
|
68
|
+
version: '0.19'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,89 +81,89 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.13'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: codeclimate-test-reporter
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '1.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '1.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: config
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 1.5.1
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
110
|
+
version: 1.5.1
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rake
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
117
|
+
version: '10.0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
124
|
+
version: '10.0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: rspec
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0
|
131
|
+
version: '3.0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0
|
138
|
+
version: '3.0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: rubocop
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0.
|
145
|
+
version: '0.48'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '0.
|
152
|
+
version: '0.48'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: simplecov
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - "~>"
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
159
|
+
version: '0.14'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
166
|
+
version: '0.14'
|
167
167
|
description: Deploy Docker container on AWS ECS.
|
168
168
|
email:
|
169
169
|
- n.yamakita@gmail.com
|
@@ -182,13 +182,22 @@ files:
|
|
182
182
|
- bin/console
|
183
183
|
- bin/setup
|
184
184
|
- circle.yml
|
185
|
+
- config.local.yml
|
186
|
+
- config.yml
|
185
187
|
- ecs_deployer.gemspec
|
186
|
-
- example/
|
188
|
+
- example/register_task.rb
|
189
|
+
- example/update_scheduled_task.rb
|
190
|
+
- example/update_service.rb
|
187
191
|
- exe/ecs_deployer
|
188
192
|
- lib/ecs_deployer.rb
|
189
193
|
- lib/ecs_deployer/cli.rb
|
190
194
|
- lib/ecs_deployer/client.rb
|
191
195
|
- lib/ecs_deployer/error.rb
|
196
|
+
- lib/ecs_deployer/scheduled_task/client.rb
|
197
|
+
- lib/ecs_deployer/scheduled_task/target.rb
|
198
|
+
- lib/ecs_deployer/service/client.rb
|
199
|
+
- lib/ecs_deployer/task/client.rb
|
200
|
+
- lib/ecs_deployer/util/cipher.rb
|
192
201
|
- lib/ecs_deployer/version.rb
|
193
202
|
homepage: https://github.com/naomichi-y/ecs_deployer
|
194
203
|
licenses:
|
data/example/sample.rb
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
require 'ecs_deployer'
|
3
|
-
|
4
|
-
path = File.expand_path('../spec/fixtures/task.yml', File.dirname(File.realpath(__FILE__)))
|
5
|
-
|
6
|
-
deployer = EcsDeployer::Client.new('sandbox')
|
7
|
-
task_definition = deployer.register_task(path, tag: 'latest')
|
8
|
-
deployer.update_service('production', task_definition)
|