Skip to content

Commit

Permalink
ecs_* - add waiters (#1209)
Browse files Browse the repository at this point in the history
SUMMARY

    Add wait parameter to utilize boto3 waiters in ecs_service and ecs_task (ServicesInactive, TasksStopped, TasksRunning).
    There's an additional waiter for ServicesStable but idempotence checked never failed locally so it seems redundant when creating a service.

ISSUE TYPE

    Feature Pull Request

COMPONENT NAME

    ecs_service
    ecs_task

ADDITIONAL INFORMATION

When testing the waiter for TasksRunning, tests failed on waiter error due to the container instance not being able to be created, not because of the waiter, so I commented out those tests for now.

In the ECS console:

Stopped reason CannotPullContainerError: inspect image has been retried 5 time(s): failed to resolve ref "docker.io/library/nginx:latest": failed to do request: Head https://registry-1.docker.io/v2/library/nginx/manifests/latest: dial tcp 34.237.244.67:443: i/o timeout

* add waiters and fix some bugs
* add changelog
* move bugfixes to different PR for backporting purposes
* update wait description
* catch WaiterError
* Bump version_added

(cherry picked from commit cff148f)
  • Loading branch information
jatorcasso authored and patchback[bot] committed Jun 29, 2022
1 parent 7460c66 commit fed1332
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 38 deletions.
3 changes: 3 additions & 0 deletions changelogs/fragments/1209-ecs_service-add-waiters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
minor_changes:
- ecs_service - add ``wait`` parameter and waiter for deleting services (https://github.com/ansible-collections/community.aws/pull/1209).
- ecs_task - add ``wait`` parameter and waiter for running and stopping tasks (https://github.com/ansible-collections/community.aws/pull/1209).
24 changes: 24 additions & 0 deletions plugins/modules/ecs_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,13 @@
required: false
choices: ["DAEMON", "REPLICA"]
type: str
wait:
description:
- Whether or not to wait for the service to be inactive.
- Waits only when I(state) is C(absent).
type: bool
default: false
version_added: 4.1.0
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
Expand Down Expand Up @@ -780,6 +787,7 @@ def main():
force_new_deployment=dict(required=False, default=False, type='bool'),
force_deletion=dict(required=False, default=False, type='bool'),
deployment_configuration=dict(required=False, default={}, type='dict'),
wait=dict(required=False, default=False, type='bool'),
placement_constraints=dict(
required=False,
default=[],
Expand Down Expand Up @@ -964,8 +972,24 @@ def main():
module.params['cluster'],
module.params['force_deletion'],
)

# Wait for service to be INACTIVE prior to exiting
if module.params['wait']:
waiter = service_mgr.ecs.get_waiter('services_inactive')
try:
waiter.wait(
services=[module.params['name']],
cluster=module.params['cluster'],
WaiterConfig={
'Delay': module.params['delay'],
'MaxAttempts': module.params['repeat']
}
)
except botocore.exceptions.WaiterError as e:
module.fail_json_aws(e, 'Timeout waiting for service removal')
except botocore.exceptions.ClientError as e:
module.fail_json_aws(e, msg="Couldn't delete service")

results['changed'] = True

elif module.params['state'] == 'deleting':
Expand Down
42 changes: 40 additions & 2 deletions plugins/modules/ecs_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@
- Tags that will be added to ecs tasks on start and run
required: false
aliases: ['resource_tags']
wait:
description:
- Whether or not to wait for the desired state.
type: bool
default: false
version_added: 4.1.0
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
Expand Down Expand Up @@ -353,7 +359,8 @@ def main():
started_by=dict(required=False, type='str'), # R S
network_configuration=dict(required=False, type='dict'),
launch_type=dict(required=False, choices=['EC2', 'FARGATE']),
tags=dict(required=False, type='dict', aliases=['resource_tags'])
tags=dict(required=False, type='dict', aliases=['resource_tags']),
wait=dict(required=False, default=False, type='bool'),
)

module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True,
Expand Down Expand Up @@ -395,7 +402,9 @@ def main():
results['task'] = existing
else:
if not module.check_mode:
results['task'] = service_mgr.run_task(

# run_task returns a list of tasks created
tasks = service_mgr.run_task(
module.params['cluster'],
module.params['task_definition'],
module.params['overrides'],
Expand All @@ -404,6 +413,21 @@ def main():
module.params['launch_type'],
module.params['tags'],
)

# Wait for task(s) to be running prior to exiting
if module.params['wait']:

waiter = service_mgr.ecs.get_waiter('tasks_running')
try:
waiter.wait(
tasks=[task['taskArn'] for task in tasks],
cluster=module.params['cluster'],
)
except botocore.exceptions.WaiterError as e:
module.fail_json_aws(e, 'Timeout waiting for tasks to run')

results['task'] = tasks

results['changed'] = True

elif module.params['operation'] == 'start':
Expand All @@ -420,6 +444,7 @@ def main():
module.params['started_by'],
module.params['tags'],
)

results['changed'] = True

elif module.params['operation'] == 'stop':
Expand All @@ -433,6 +458,19 @@ def main():
module.params['cluster'],
module.params['task']
)

# Wait for task to be stopped prior to exiting
if module.params['wait']:

waiter = service_mgr.ecs.get_waiter('tasks_stopped')
try:
waiter.wait(
tasks=[module.params['task']],
cluster=module.params['cluster'],
)
except botocore.exceptions.WaiterError as e:
module.fail_json_aws(e, 'Timeout waiting for task to stop')

results['changed'] = True

module.exit_json(**results)
Expand Down
Loading

0 comments on commit fed1332

Please sign in to comment.