ecs_deploy 1.0.3 → 1.0.5

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
  SHA256:
3
- metadata.gz: f4d2cb1f5439702efac5ec26e9cd0c47c6225e0106c05b6f73b7860098098488
4
- data.tar.gz: 29007dc6fdeb7b64b82a0113ac78ad00025ec9693bca1b238ccca3c507065c01
3
+ metadata.gz: a9b02fc9a3cfda6288d7e00f339487fd2050b441e973d5fc7a822f9c261ea272
4
+ data.tar.gz: 9c002ab5e543435304d8d56eb88d19fceac56b4d70916f1b740176b6c3070dfc
5
5
  SHA512:
6
- metadata.gz: 42481f7631cebe62057fbd9e2c0fc6ba61ff0ee198e5d537958934df8a001c76ef5ddb6f8965c2f7db57d0098aac3b79cb43a677cdbaa95609107d29826892b8
7
- data.tar.gz: 28a2d8072e7f94a84301e0f0607fc02c469561d1f39da439cf87d3f7b64c12e301bb77a13bb96e0823870b43af36f5f35ee3e4984567ac57ebe5ae759342d61c
6
+ metadata.gz: c88b02664cb84e45ae1b14b4bbd97907d984a46d3ff6eb817f48d0ffb626f7b8c88311f1b6c5a31c8f8b27a2eaeee8ed9a06c61c93551e4b3dd1c3099d382628
7
+ data.tar.gz: 144449c85ed16c1f4dbfe8340cb6a11b1b4aee8ac55de07e2322dda654932c3bbfb12a125b39776aad3294841487b0047098dd9e65e46f2d44aec125c933b9e4
@@ -0,0 +1,23 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ ruby-version: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2']
14
+
15
+ steps:
16
+ - uses: actions/checkout@v3
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby-version }}
21
+ bundler-cache: true
22
+ - name: Run tests
23
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # v1.0
2
2
 
3
+ ## Release v1.0.5 - 2023/03/15
4
+
5
+ ### Enhancement
6
+
7
+ - Add variable of capistrano `ecs_client_retry_params` to override parameter of ECS::Client#initialize https://github.com/reproio/ecs_deploy/pull/88
8
+
9
+ ## Release v1.0.4 - 2023/02/10
10
+
11
+ ### Bug fixes
12
+
13
+ - Fix Aws::AutoScaling::Errors::ValidationError https://github.com/reproio/ecs_deploy/pull/85
14
+
15
+ - Fix Timeout::Error that occurs in trigger_capacity_update https://github.com/reproio/ecs_deploy/pull/80
16
+
17
+ - use force a new deployment, when switching from launch type to capacity provider strategy on an existing service https://github.com/reproio/ecs_deploy/pull/75
18
+
19
+ ### Enhancement
20
+
21
+ - Run test with Ruby 3.2 https://github.com/reproio/ecs_deploy/pull/83
22
+
23
+ - Merge `propagate_tags` to service_options when updating service https://github.com/reproio/ecs_deploy/pull/82
24
+
25
+ - Show service event logs while waiting for services https://github.com/reproio/ecs_deploy/pull/81
26
+
27
+ - Stop supporting ruby 2.4 https://github.com/reproio/ecs_deploy/pull/79
28
+
29
+ - Display warning that desired count has reached max value https://github.com/reproio/ecs_deploy/pull/78
30
+
31
+ - Make draining feature opt-outable https://github.com/reproio/ecs_deploy/pull/77
32
+
33
+ - Add capacity_provider_strategy options to Service https://github.com/reproio/ecs_deploy/pull/74
34
+
3
35
  ## Release v1.0.3 - 2021/11/17
4
36
 
5
37
  ### Bug fixes
data/README.md CHANGED
@@ -33,6 +33,7 @@ set :ecs_service_role, "customEcsServiceRole" # default: ecsServiceRole
33
33
  set :ecs_deploy_wait_timeout, 600 # default: 300
34
34
  set :ecs_wait_until_services_stable_max_attempts, 40 # optional
35
35
  set :ecs_wait_until_services_stable_delay, 15 # optional
36
+ set :ecs_client_params, { retry_mode: "standard", max_attempts: 10 } # default: {}
36
37
 
37
38
  set :ecs_tasks, [
38
39
  {
@@ -215,6 +216,7 @@ auto_scaling_groups:
215
216
  # autoscaler will set the capacity to (buffer + desired_tasks * required_capacity).
216
217
  # Adjust this value if it takes much time to prepare ECS instances and launch new tasks.
217
218
  buffer: 1
219
+ disable_draining: false # cf. spot_instance_intrp_warns_queue_urls
218
220
  services:
219
221
  - name: repro-api-production
220
222
  step: 1
@@ -242,6 +244,7 @@ spot_fleet_requests:
242
244
  region: ap-northeast-1
243
245
  cluster: ecs-cluster-for-worker
244
246
  buffer: 1
247
+ disable_draining: false # cf. spot_instance_intrp_warns_queue_urls
245
248
  services:
246
249
  - name: repro-worker-production
247
250
  step: 1
@@ -261,11 +264,15 @@ spot_fleet_requests:
261
264
  state: ALARM
262
265
  prioritized_over_upscale_triggers: true
263
266
 
264
- # If you specify `spot_instance_intrp_warns_queue_urls` as SQS queue for spot instance interruption warnings,
265
- # autoscaler will polls them and set the state of instances to be intrrupted to "DRAINING".
266
- # autoscaler will also waits for the capacity of active instances in the cluster being decreased
267
- # when the capacity of spot fleet request is decreased,
268
- # so you should specify URLs or set the state of the instances to "DRAINING" manually.
267
+ # When you use spot instances, instances that receive interruption warnings should be drained.
268
+ # If you set URLs of SQS queues for spot instance interruption warnings to `spot_instance_intrp_warns_queue_urls`,
269
+ # autoscaler drains instances to interrupt and detaches the instances from the auto scaling groups with
270
+ # should_decrement_desired_capacity false.
271
+ # If you set ECS_ENABLE_SPOT_INSTANCE_DRAINING to true, we recommend that you opt out of the draining feature
272
+ # by setting disable_draining to true in the configurations of auto scaling groups and spot fleet requests.
273
+ # Otherwise, instances don't seem to be drained on rare occasions.
274
+ # Even if you opt out of the feature, you still have the advantage of setting `spot_instance_intrp_warns_queue_urls`
275
+ # because instances to interrupt are replaced with new instances as soon as possible.
269
276
  spot_instance_intrp_warns_queue_urls:
270
277
  - https://sqs.ap-northeast-1.amazonaws.com/<account-id>/spot-instance-intrp-warns
271
278
  ```
data/ecs_deploy.gemspec CHANGED
@@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "bundler", ">= 1.11", "< 3"
31
31
  spec.add_development_dependency "rake", ">= 10.0"
32
32
  spec.add_development_dependency "rspec", "~> 3.0"
33
+ spec.add_development_dependency "rexml" # For aws-sdk-*
33
34
  end
@@ -7,7 +7,7 @@ require "ecs_deploy/auto_scaler/cluster_resource_manager"
7
7
 
8
8
  module EcsDeploy
9
9
  module AutoScaler
10
- AutoScalingGroupConfig = Struct.new(:name, :region, :cluster, :buffer, :service_configs) do
10
+ AutoScalingGroupConfig = Struct.new(:name, :region, :cluster, :buffer, :service_configs, :disable_draining) do
11
11
  include ConfigBase
12
12
 
13
13
  MAX_DETACHABLE_INSTANCE_COUNT = 20
@@ -82,7 +82,7 @@ module EcsDeploy
82
82
  def decrease_desired_capacity(count)
83
83
  container_instance_arns_in_service = cluster_resource_manager.fetch_container_instance_arns_in_service
84
84
  container_instances_in_cluster = cluster_resource_manager.fetch_container_instances_in_cluster
85
- auto_scaling_group_instances = instances(reload: true)
85
+ auto_scaling_group_instances = describe_detachable_instances
86
86
  deregisterable_instances = container_instances_in_cluster.select do |i|
87
87
  i.pending_tasks_count == 0 &&
88
88
  !running_essential_task?(i, container_instance_arns_in_service) &&
@@ -144,15 +144,8 @@ module EcsDeploy
144
144
 
145
145
  def detach_and_terminate_orphan_instances
146
146
  container_instance_ids = cluster_resource_manager.fetch_container_instances_in_cluster.map(&:ec2_instance_id)
147
- orphans = instances(reload: true).reject do |i|
147
+ orphans = describe_detachable_instances.reject do |i|
148
148
  next true if container_instance_ids.include?(i.instance_id)
149
-
150
- # The lifecycle state of terminated instances becomes "Terminating", "Terminating:Wait", or "Terminating:Proceed",
151
- # and we can't detach instances in such a state.
152
- if i.lifecycle_state.start_with?("Terminating")
153
- AutoScaler.error_logger.warn("#{log_prefix} The lifesycle state of #{i.instance_id} is \"#{i.lifecycle_state}\", so ignore it")
154
- next true
155
- end
156
149
  end.map(&:instance_id)
157
150
 
158
151
  return if orphans.empty?
@@ -184,14 +177,11 @@ module EcsDeploy
184
177
  )
185
178
  end
186
179
 
187
- def instances(reload: false)
188
- if reload || @instances.nil?
189
- resp = client.describe_auto_scaling_groups({
190
- auto_scaling_group_names: [name],
191
- })
192
- @instances = resp.auto_scaling_groups[0].instances
193
- else
194
- @instances
180
+ def describe_detachable_instances
181
+ client.describe_auto_scaling_groups({ auto_scaling_group_names: [name] }).auto_scaling_groups[0].instances.reject do |i|
182
+ # The lifecycle state of terminated instances becomes "Detaching", "Terminating", "Terminating:Wait", or "Terminating:Proceed",
183
+ # and we can't detach instances in such a state.
184
+ i.lifecycle_state.start_with?("Terminating") || i.lifecycle_state == "Detaching"
195
185
  end
196
186
  end
197
187
 
@@ -74,39 +74,42 @@ module EcsDeploy
74
74
  end
75
75
 
76
76
  def trigger_capacity_update(old_desired_capacity, new_desired_capacity, interval: 5, wait_until_capacity_updated: false)
77
+ return if new_desired_capacity == old_desired_capacity
78
+
77
79
  th = Thread.new do
78
80
  @logger&.info "#{log_prefix} Start updating capacity: #{old_desired_capacity} -> #{new_desired_capacity}"
79
81
  Timeout.timeout(180) do
80
- until @capacity == new_desired_capacity || (new_desired_capacity >= old_desired_capacity && @capacity > new_desired_capacity)
82
+ until @capacity == new_desired_capacity ||
83
+ (new_desired_capacity > old_desired_capacity && @capacity > new_desired_capacity) ||
84
+ (new_desired_capacity < old_desired_capacity && @capacity < new_desired_capacity)
81
85
  @mutex.synchronize do
82
- begin
83
- @capacity = calculate_active_instance_capacity
84
- @resource.broadcast
85
- rescue => e
86
- AutoScaler.error_logger.warn("#{log_prefix} `#{__method__}': #{e} (#{e.class})")
87
- end
86
+ @capacity = calculate_active_instance_capacity
87
+ @resource.broadcast
88
+ rescue => e
89
+ AutoScaler.error_logger.warn("#{log_prefix} `#{__method__}': #{e} (#{e.class})")
88
90
  end
89
91
 
90
92
  sleep interval
91
93
  end
92
94
  @logger&.info "#{log_prefix} capacity is updated to #{@capacity}"
93
95
  end
96
+ rescue Timeout::Error => e
97
+ msg = "#{log_prefix} `#{__method__}': #{e} (#{e.class})"
98
+ if @capacity_based_on == "vCPUs"
99
+ # Timeout::Error sometimes occur.
100
+ # For example, the following case never meats the condition of until
101
+ # * old_desired_capaacity is 102
102
+ # * new_desired_capaacity is 101
103
+ # * all instances have 2 vCPUs
104
+ AutoScaler.error_logger.warn(msg)
105
+ else
106
+ AutoScaler.error_logger.error(msg)
107
+ end
94
108
  end
95
109
 
96
110
  if wait_until_capacity_updated
97
111
  @logger&.info "#{log_prefix} Wait for the capacity of active instances to become #{new_desired_capacity} from #{old_desired_capacity}"
98
- begin
99
- th.join
100
- rescue Timeout::Error => e
101
- msg = "#{log_prefix} `#{__method__}': #{e} (#{e.class})"
102
- if @capacity_based_on == "vCPUs"
103
- # Timeout::Error sometimes occur.
104
- # For example, @capacity won't be new_desired_capacity if new_desired_capacity is odd and all instances have 2 vCPUs
105
- AutoScaler.error_logger.warn(msg)
106
- else
107
- AutoScaler.error_logger.error(msg)
108
- end
109
- end
112
+ th.join
110
113
  end
111
114
  end
112
115
 
@@ -78,6 +78,11 @@ module EcsDeploy
78
78
  def set_instance_state_to_draining(config_to_instance_ids, region)
79
79
  cl = ecs_client(region)
80
80
  config_to_instance_ids.each do |config, instance_ids|
81
+ if config.disable_draining == true || config.disable_draining == "true"
82
+ @logger.info "Skip draining instances: region: #{region}, cluster: #{config.cluster}, instance_ids: #{instance_ids.inspect}"
83
+ next
84
+ end
85
+
81
86
  arns = cl.list_container_instances(
82
87
  cluster: config.cluster,
83
88
  filter: "ec2InstanceId in [#{instance_ids.join(",")}]",
@@ -135,6 +135,9 @@ module EcsDeploy
135
135
  now = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
136
136
  @reach_max_at ||= now
137
137
  @logger.info "#{log_prefix} Service waits cooldown elapsed #{(now - @reach_max_at).to_i}sec"
138
+ if next_desired_count > max_task_count[current_level] && current_level == max_task_count.size - 1
139
+ @logger.warn "#{log_prefix} Desired count has reached the maximum value and couldn't be increased"
140
+ end
138
141
  elsif current_level == next_level && next_desired_count < max_task_count[current_level]
139
142
  level = current_level
140
143
  @reach_max_at = nil
@@ -8,7 +8,7 @@ require "ecs_deploy/auto_scaler/cluster_resource_manager"
8
8
 
9
9
  module EcsDeploy
10
10
  module AutoScaler
11
- SpotFleetRequestConfig = Struct.new(:id, :region, :cluster, :buffer, :service_configs) do
11
+ SpotFleetRequestConfig = Struct.new(:id, :region, :cluster, :buffer, :service_configs, :disable_draining) do
12
12
  include ConfigBase
13
13
 
14
14
  def initialize(attributes = {}, logger)
@@ -10,6 +10,7 @@ namespace :ecs do
10
10
  c.default_region = Array(fetch(:ecs_region))[0] if fetch(:ecs_region)
11
11
  c.ecs_wait_until_services_stable_max_attempts = fetch(:ecs_wait_until_services_stable_max_attempts) if fetch(:ecs_wait_until_services_stable_max_attempts)
12
12
  c.ecs_wait_until_services_stable_delay = fetch(:ecs_wait_until_services_stable_delay) if fetch(:ecs_wait_until_services_stable_delay)
13
+ c.ecs_client_params = fetch(:ecs_client_params) if fetch(:ecs_client_params)
13
14
  end
14
15
 
15
16
  if ENV["TARGET_CLUSTER"]
@@ -113,6 +114,7 @@ namespace :ecs do
113
114
  service_options[:deployment_configuration] = service[:deployment_configuration] if service[:deployment_configuration]
114
115
  service_options[:placement_constraints] = service[:placement_constraints] if service[:placement_constraints]
115
116
  service_options[:placement_strategy] = service[:placement_strategy] if service[:placement_strategy]
117
+ service_options[:capacity_provider_strategy] = service[:capacity_provider_strategy] if service[:capacity_provider_strategy]
116
118
  service_options[:scheduling_strategy] = service[:scheduling_strategy] if service[:scheduling_strategy]
117
119
  s = EcsDeploy::Service.new(**service_options)
118
120
  s.deploy
@@ -179,6 +181,7 @@ namespace :ecs do
179
181
  service_options[:deployment_configuration] = service[:deployment_configuration] if service[:deployment_configuration]
180
182
  service_options[:placement_constraints] = service[:placement_constraints] if service[:placement_constraints]
181
183
  service_options[:placement_strategy] = service[:placement_strategy] if service[:placement_strategy]
184
+ service_options[:capacity_provider_strategy] = service[:capacity_provider_strategy] if service[:capacity_provider_strategy]
182
185
  s = EcsDeploy::Service.new(**service_options)
183
186
  s.deploy
184
187
  EcsDeploy::TaskDefinition.deregister(current_task_definition_arn, region: r)
@@ -8,7 +8,8 @@ module EcsDeploy
8
8
  :deploy_wait_timeout,
9
9
  :ecs_service_role,
10
10
  :ecs_wait_until_services_stable_max_attempts,
11
- :ecs_wait_until_services_stable_delay
11
+ :ecs_wait_until_services_stable_delay,
12
+ :ecs_client_params
12
13
 
13
14
  def initialize
14
15
  @log_level = :info
@@ -16,6 +17,7 @@ module EcsDeploy
16
17
  # The following values are the default values of Aws::ECS::Waiters::ServicesStable
17
18
  @ecs_wait_until_services_stable_max_attempts = 40
18
19
  @ecs_wait_until_services_stable_delay = 15
20
+ @ecs_client_params = {}
19
21
  end
20
22
  end
21
23
  end
@@ -113,7 +113,7 @@ module EcsDeploy
113
113
  end
114
114
 
115
115
  def ecs_client
116
- @ecs_client ||= Aws::ECS::Client.new(aws_params)
116
+ @ecs_client ||= Aws::ECS::Client.new(aws_params.merge(EcsDeploy.config.ecs_client_params))
117
117
  end
118
118
 
119
119
  def fetch_auto_scaling_group
@@ -27,9 +27,10 @@ module EcsDeploy
27
27
  @platform_version = platform_version
28
28
  @group = group
29
29
  region ||= EcsDeploy.config.default_region
30
+ params ||= EcsDeploy.config.ecs_client_params
30
31
  @container_overrides = container_overrides
31
32
 
32
- @client = region ? Aws::ECS::Client.new(region: region) : Aws::ECS::Client.new
33
+ @client = region ? Aws::ECS::Client.new(params.merge(region: region)) : Aws::ECS::Client.new(params)
33
34
  @region = @client.config.region
34
35
  @cloud_watch_events = Aws::CloudWatchEvents::Client.new(region: @region)
35
36
  end
@@ -7,7 +7,7 @@ module EcsDeploy
7
7
 
8
8
  class TooManyAttemptsError < StandardError; end
9
9
 
10
- attr_reader :cluster, :region, :service_name, :delete
10
+ attr_reader :cluster, :region, :service_name, :delete, :deploy_started_at
11
11
 
12
12
  def initialize(
13
13
  cluster:, service_name:, task_definition_name: nil, revision: nil,
@@ -16,6 +16,7 @@ module EcsDeploy
16
16
  launch_type: nil,
17
17
  placement_constraints: [],
18
18
  placement_strategy: [],
19
+ capacity_provider_strategy: nil,
19
20
  network_configuration: nil,
20
21
  health_check_grace_period_seconds: nil,
21
22
  scheduling_strategy: 'REPLICA',
@@ -35,6 +36,7 @@ module EcsDeploy
35
36
  @launch_type = launch_type
36
37
  @placement_constraints = placement_constraints
37
38
  @placement_strategy = placement_strategy
39
+ @capacity_provider_strategy = capacity_provider_strategy
38
40
  @network_configuration = network_configuration
39
41
  @health_check_grace_period_seconds = health_check_grace_period_seconds
40
42
  @scheduling_strategy = scheduling_strategy
@@ -47,7 +49,8 @@ module EcsDeploy
47
49
  @response = nil
48
50
 
49
51
  region ||= EcsDeploy.config.default_region
50
- @client = region ? Aws::ECS::Client.new(region: region) : Aws::ECS::Client.new
52
+ params ||= EcsDeploy.config.ecs_client_params
53
+ @client = region ? Aws::ECS::Client.new(params.merge(region: region)) : Aws::ECS::Client.new(params)
51
54
  @region = @client.config.region
52
55
 
53
56
  @delete = delete
@@ -59,6 +62,7 @@ module EcsDeploy
59
62
  end
60
63
 
61
64
  def deploy
65
+ @deploy_started_at = Time.now
62
66
  res = @client.describe_services(cluster: @cluster, services: [@service_name])
63
67
  service_options = {
64
68
  cluster: @cluster,
@@ -66,8 +70,25 @@ module EcsDeploy
66
70
  deployment_configuration: @deployment_configuration,
67
71
  network_configuration: @network_configuration,
68
72
  health_check_grace_period_seconds: @health_check_grace_period_seconds,
73
+ capacity_provider_strategy: @capacity_provider_strategy,
69
74
  enable_execute_command: @enable_execute_command,
75
+ enable_ecs_managed_tags: @enable_ecs_managed_tags,
76
+ placement_constraints: @placement_constraints,
77
+ placement_strategy: @placement_strategy,
70
78
  }
79
+
80
+ if @load_balancers && EcsDeploy.config.ecs_service_role
81
+ service_options.merge!({
82
+ role: EcsDeploy.config.ecs_service_role,
83
+ })
84
+ end
85
+
86
+ if @load_balancers
87
+ service_options.merge!({
88
+ load_balancers: @load_balancers,
89
+ })
90
+ end
91
+
71
92
  if res.services.select{ |s| s.status == 'ACTIVE' }.empty?
72
93
  return if @delete
73
94
 
@@ -75,25 +96,10 @@ module EcsDeploy
75
96
  service_name: @service_name,
76
97
  desired_count: @desired_count.to_i,
77
98
  launch_type: @launch_type,
78
- placement_constraints: @placement_constraints,
79
- placement_strategy: @placement_strategy,
80
- enable_ecs_managed_tags: @enable_ecs_managed_tags,
81
99
  tags: @tags,
82
100
  propagate_tags: @propagate_tags,
83
101
  })
84
102
 
85
- if @load_balancers && EcsDeploy.config.ecs_service_role
86
- service_options.merge!({
87
- role: EcsDeploy.config.ecs_service_role,
88
- })
89
- end
90
-
91
- if @load_balancers
92
- service_options.merge!({
93
- load_balancers: @load_balancers,
94
- })
95
- end
96
-
97
103
  if @scheduling_strategy == 'DAEMON'
98
104
  service_options[:scheduling_strategy] = @scheduling_strategy
99
105
  service_options.delete(:desired_count)
@@ -105,12 +111,34 @@ module EcsDeploy
105
111
 
106
112
  service_options.merge!({service: @service_name})
107
113
  service_options.merge!({desired_count: @desired_count}) if @desired_count
114
+ service_options.merge!({propagate_tags: @propagate_tags}) if @propagate_tags
115
+
116
+ current_service = res.services[0]
117
+ service_options.merge!({force_new_deployment: true}) if need_force_new_deployment?(current_service)
118
+
108
119
  update_tags(@service_name, @tags)
109
120
  @response = @client.update_service(service_options)
110
121
  EcsDeploy.logger.info "update service [#{@service_name}] [#{@cluster}] [#{@region}] [#{Paint['OK', :green]}]"
111
122
  end
112
123
  end
113
124
 
125
+ private def need_force_new_deployment?(service)
126
+ return false unless @capacity_provider_strategy
127
+ return true unless service.capacity_provider_strategy
128
+
129
+ return true if @capacity_provider_strategy.size != service.capacity_provider_strategy.size
130
+
131
+ match_array = @capacity_provider_strategy.all? do |strategy|
132
+ service.capacity_provider_strategy.find do |current_strategy|
133
+ strategy[:capacity_provider] == current_strategy.capacity_provider &&
134
+ strategy[:weight] == current_strategy.weight &&
135
+ strategy[:base] == current_strategy.base
136
+ end
137
+ end
138
+
139
+ !match_array
140
+ end
141
+
114
142
  def delete_service
115
143
  if @scheduling_strategy != 'DAEMON'
116
144
  @client.update_service(cluster: @cluster, service: @service_name, desired_count: 0)
@@ -142,9 +170,20 @@ module EcsDeploy
142
170
  end
143
171
  end
144
172
 
173
+ def log_events(ecs_service)
174
+ ecs_service.events.sort_by(&:created_at).each do |e|
175
+ next if e.created_at <= deploy_started_at
176
+ next if @last_event && e.created_at <= @last_event.created_at
177
+
178
+ EcsDeploy.logger.info e.message
179
+ @last_event = e
180
+ end
181
+ end
182
+
145
183
  def self.wait_all_running(services)
146
184
  services.group_by { |s| [s.cluster, s.region] }.flat_map do |(cl, region), ss|
147
- client = Aws::ECS::Client.new(region: region)
185
+ params ||= EcsDeploy.config.ecs_client_params
186
+ client = Aws::ECS::Client.new(params.merge(region: region))
148
187
  ss.reject(&:delete).map(&:service_name).each_slice(MAX_DESCRIBE_SERVICES).map do |chunked_service_names|
149
188
  Thread.new do
150
189
  EcsDeploy.config.ecs_wait_until_services_stable_max_attempts.times do
@@ -155,6 +194,8 @@ module EcsDeploy
155
194
  if s.deployments.size == 1 && s.running_count == s.desired_count
156
195
  chunked_service_names.delete(s.service_name)
157
196
  end
197
+ service = ss.detect {|sc| sc.service_name == s.service_name }
198
+ service.log_events(s)
158
199
  end
159
200
  break if chunked_service_names.empty?
160
201
  sleep EcsDeploy.config.ecs_wait_until_services_stable_delay
@@ -1,15 +1,9 @@
1
1
  module EcsDeploy
2
2
  class TaskDefinition
3
- RETRY_BACKOFF = lambda do |c|
4
- sleep(1)
5
- end
6
-
7
- RETRY_LIMIT = 10
8
-
9
3
  def self.deregister(arn, region: nil)
10
4
  region ||= EcsDeploy.config.default_region
11
- param = {retry_backoff: RETRY_BACKOFF, retry_limit: RETRY_LIMIT}
12
- client = region ? Aws::ECS::Client.new(param.merge(region: region)) : Aws::ECS::Client.new(param)
5
+ params ||= EcsDeploy.config.ecs_client_params
6
+ client = region ? Aws::ECS::Client.new(params.merge(region: region)) : Aws::ECS::Client.new(params)
13
7
  client.deregister_task_definition({
14
8
  task_definition: arn,
15
9
  })
@@ -29,6 +23,7 @@ module EcsDeploy
29
23
  @task_role_arn = task_role_arn
30
24
  @execution_role_arn = execution_role_arn
31
25
  region ||= EcsDeploy.config.default_region
26
+ params ||= EcsDeploy.config.ecs_client_params
32
27
 
33
28
  @container_definitions = container_definitions.map do |cd|
34
29
  if cd[:docker_labels]
@@ -46,8 +41,7 @@ module EcsDeploy
46
41
  @cpu = cpu&.to_s
47
42
  @memory = memory&.to_s
48
43
  @tags = tags
49
- param = {retry_backoff: RETRY_BACKOFF, retry_limit: RETRY_LIMIT}
50
- @client = region ? Aws::ECS::Client.new(param.merge(region: region)) : Aws::ECS::Client.new(param)
44
+ @client = region ? Aws::ECS::Client.new(params.merge(region: region)) : Aws::ECS::Client.new(params)
51
45
  @region = @client.config.region
52
46
  end
53
47
 
@@ -1,3 +1,3 @@
1
1
  module EcsDeploy
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecs_deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - joker1007
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-17 00:00:00.000000000 Z
11
+ date: 2023-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-autoscaling
@@ -170,6 +170,20 @@ dependencies:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
172
  version: '3.0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: rexml
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
173
187
  description: AWS ECS deploy helper
174
188
  email:
175
189
  - kakyoin.hierophant@gmail.com
@@ -178,8 +192,8 @@ executables:
178
192
  extensions: []
179
193
  extra_rdoc_files: []
180
194
  files:
195
+ - ".github/workflows/test.yml"
181
196
  - ".gitignore"
182
- - ".travis.yml"
183
197
  - CHANGELOG.md
184
198
  - Gemfile
185
199
  - README.md
@@ -222,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
236
  - !ruby/object:Gem::Version
223
237
  version: '0'
224
238
  requirements: []
225
- rubygems_version: 3.2.15
239
+ rubygems_version: 3.4.2
226
240
  signing_key:
227
241
  specification_version: 4
228
242
  summary: AWS ECS deploy helper
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - ruby-2.4.9
4
- - ruby-2.5.7
5
- - ruby-2.6.5