lib/hako/schedulers/ecs.rb in hako-2.12.0 vs lib/hako/schedulers/ecs.rb in hako-2.13.0

- old
+ new

@@ -72,10 +72,19 @@ @execution_role_arn = options.fetch('execution_role_arn', nil) @cpu = options.fetch('cpu', nil) @memory = options.fetch('memory', nil) @requires_compatibilities = options.fetch('requires_compatibilities', nil) @launch_type = options.fetch('launch_type', nil) + if options.key?('capacity_provider_strategy') + @capacity_provider_strategy = options.fetch('capacity_provider_strategy').map do |strategy| + { + capacity_provider: strategy.fetch('capacity_provider'), + weight: strategy.fetch('weight', nil), + base: strategy.fetch('base', nil), + } + end + end @platform_version = options.fetch('platform_version', nil) if options.key?('network_configuration') network_configuration = options.fetch('network_configuration') if network_configuration.key?('awsvpc_configuration') awsvpc_configuration = network_configuration.fetch('awsvpc_configuration') @@ -668,10 +677,11 @@ overrides: overrides_option(commands, env, overrides), count: 1, placement_constraints: @placement_constraints, started_by: 'hako oneshot', launch_type: @launch_type, + capacity_provider_strategy: @capacity_provider_strategy, platform_version: @platform_version, network_configuration: @network_configuration, ) result.failures.each do |failure| Hako.logger.error("#{failure.arn} #{failure.reason}") @@ -862,18 +872,33 @@ cluster: @cluster, service: @app_id, desired_count: @desired_count, task_definition: task_definition_arn, deployment_configuration: @deployment_configuration, + capacity_provider_strategy: @capacity_provider_strategy, platform_version: @platform_version, network_configuration: @network_configuration, health_check_grace_period_seconds: @health_check_grace_period_seconds, } if @autoscaling # Keep current desired_count if autoscaling is enabled params[:desired_count] = current_service.desired_count end + # Copy the current capacity provider strategy in order to avoid a + # perpetual diff when the service is created with no strategy to use the + # cluster's default capacity provider strategy, which results in the + # strategy being set to the default strategy at that moment. + # It is not allowed to update the service to use the cluster's default + # capacity provider strategy when it is using a non-default capacity + # provider strategy. + params[:capacity_provider_strategy] ||= current_service.capacity_provider_strategy&.map(&:to_h) + if different_capacity_provider_strategy?(params[:capacity_provider_strategy], current_service.capacity_provider_strategy) + # Switching from launch type to capacity provider strategy or making + # a change to a capacity provider strategy requires to force a new + # deployment. + params[:force_new_deployment] = true + end warn_placement_policy_change(current_service) warn_service_registries_change(current_service) if service_changed?(current_service, params) ecs_client.update_service(params).service else @@ -893,10 +918,11 @@ deployment_configuration: @deployment_configuration, placement_constraints: @placement_constraints, placement_strategy: @placement_strategy, scheduling_strategy: @scheduling_strategy, launch_type: @launch_type, + capacity_provider_strategy: @capacity_provider_strategy, platform_version: @platform_version, network_configuration: @network_configuration, health_check_grace_period_seconds: @health_check_grace_period_seconds, } if @scheduling_strategy != 'DAEMON' @@ -1344,9 +1370,18 @@ unless invalid_parameter_names.empty? raise Error.new("Invalid parameters for secrets: #{invalid_parameter_names}") end nil + end + + # @param [Hash, nil] expected_strategy + # @param [Aws::ECS::Types::CapacityProviderStrategyItem, nil] actual_strategy + # @return [Boolean] + def different_capacity_provider_strategy?(expected_strategy, actual_strategy) + expected = (expected_strategy || []).map { |s| [s[:capacity_provider], s[:weight] || 0, s[:base] || 0] }.sort + actual = (actual_strategy || []).map { |s| [s.capacity_provider, s.weight, s.base] }.sort + expected != actual end # @param [Aws::ECS::Types::Service] service # @return [nil] def warn_placement_policy_change(service)