Skip to content

Commit

Permalink
Capacity Provider Strategy for ECS Services ansible-collections#1137
Browse files Browse the repository at this point in the history
Add requested feature for capacity provider strategy.

Capacity Provider Strategy is mutually exclusive with launch_type and a given service cannot be changed from one to the other.

Possibly still needs:
Camel <=> Snake casing for the subelements of capacity_provider_strategy.

Catch if provided list has more than 6 elements and fail cleanly.
  • Loading branch information
karcadia authored and Justin McCormick committed May 30, 2022
1 parent 688c7e8 commit 097b2b3
Showing 1 changed file with 66 additions and 8 deletions.
74 changes: 66 additions & 8 deletions plugins/modules/ecs_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,25 @@
required: false
choices: ["EC2", "FARGATE"]
type: str
capacity_provider_strategy:
description:
- The capacity provider strategy to use with your service.
required: false
type: list
elements: dict
suboptions:
capacityProvider:
description:
- Name of capacity provider.
type: str
weight:
description:
- The relative percentage of the total number of launched tasks that should use the specified provider.
type: int
base:
description:
- How many tasks, at a minimum, should use the specified provider.
type: int
platform_version:
type: str
description:
Expand Down Expand Up @@ -250,6 +269,18 @@
placement_strategy:
- type: binpack
field: memory
# With capacity_provider_strategy (added in version 4.0)
- community.aws.ecs_service:
state: present
name: test-service
cluster: test-cluster
task_definition: test-task-definition
desired_count: 1
capacity_provider_strategy:
- capacityProvider: test-capacity-provider-1
weight: 1
base: 0
'''

RETURN = r'''
Expand All @@ -258,6 +289,23 @@
returned: when creating a service
type: complex
contains:
capacityProviderStrategy:
description: The capacity provider strategy to use with your service.
returned: always
type: complex
contains:
base:
description: How many tasks, at a minimum, should use the specified provider.
returned: always
type: int
capacityProvider:
description: Name of capacity provider.
returned: always
type: str
weight:
description: The relative percentage of the total number of launched tasks that should use the specified provider.
returned: always
type: int
clusterArn:
description: The Amazon Resource Name (ARN) of the of the cluster that hosts the service.
returned: always
Expand Down Expand Up @@ -575,7 +623,7 @@ def create_service(self, service_name, cluster_name, task_definition, load_balan
desired_count, client_token, role, deployment_configuration,
placement_constraints, placement_strategy, health_check_grace_period_seconds,
network_configuration, service_registries, launch_type, platform_version,
scheduling_strategy):
scheduling_strategy, capacity_provider_strategy):

params = dict(
cluster=cluster_name,
Expand Down Expand Up @@ -607,15 +655,16 @@ def create_service(self, service_name, cluster_name, task_definition, load_balan
# desired count is not required if scheduling strategy is daemon
if desired_count is not None:
params['desiredCount'] = desired_count

if capacity_provider_strategy:
params['capacityProviderStrategy'] = capacity_provider_strategy
if scheduling_strategy:
params['schedulingStrategy'] = scheduling_strategy
response = self.ecs.create_service(**params)
return self.jsonize(response['service'])

def update_service(self, service_name, cluster_name, task_definition,
desired_count, deployment_configuration, network_configuration,
health_check_grace_period_seconds, force_new_deployment):
health_check_grace_period_seconds, force_new_deployment, capacity_provider_strategy):
params = dict(
cluster=cluster_name,
service=service_name,
Expand Down Expand Up @@ -703,14 +752,16 @@ def main():
launch_type=dict(required=False, choices=['EC2', 'FARGATE']),
platform_version=dict(required=False, type='str'),
service_registries=dict(required=False, type='list', default=[], elements='dict'),
scheduling_strategy=dict(required=False, choices=['DAEMON', 'REPLICA'])
scheduling_strategy=dict(required=False, choices=['DAEMON', 'REPLICA']),
capacity_provider_strategy=dict(required=False, type='list', default=[], elements='dict')
)

module = AnsibleAWSModule(argument_spec=argument_spec,
supports_check_mode=True,
required_if=[('state', 'present', ['task_definition']),
('launch_type', 'FARGATE', ['network_configuration'])],
required_together=[['load_balancers', 'role']])
required_together=[['load_balancers', 'role']],
mutually_exclusive=[['launch_type', 'capacity_provider_strategy']])

if module.params['state'] == 'present' and module.params['scheduling_strategy'] == 'REPLICA':
if module.params['desired_count'] is None:
Expand Down Expand Up @@ -775,7 +826,12 @@ def main():
if module.params['service_registries']:
if (existing['serviceRegistries'] or []) != serviceRegistries:
module.fail_json(msg="It is not possible to update the service registries of an existing service")

if module.params['capacity_provider_strategy']:
if 'launchType' in existing.keys():
module.fail_json(msg="It is not possible to change an existing service from launch_type to capacity_provider_strategy.")
if module.params['launch_type']:
if 'capacityProviderStrategy' in existing.keys():
module.fail_json(msg="It is not possible to change an existing service from capacity_provider_strategy to launch_type.")
if (existing['loadBalancers'] or []) != loadBalancers:
module.fail_json(msg="It is not possible to update the load balancers of an existing service")

Expand All @@ -787,7 +843,8 @@ def main():
deploymentConfiguration,
network_configuration,
module.params['health_check_grace_period_seconds'],
module.params['force_new_deployment'])
module.params['force_new_deployment'],
module.params['capacity_provider_strategy'])

else:
try:
Expand All @@ -806,7 +863,8 @@ def main():
serviceRegistries,
module.params['launch_type'],
module.params['platform_version'],
module.params['scheduling_strategy']
module.params['scheduling_strategy'],
module.params['capacity_provider_strategy']
)
except botocore.exceptions.ClientError as e:
module.fail_json_aws(e, msg="Couldn't create service")
Expand Down

0 comments on commit 097b2b3

Please sign in to comment.