From c3b059d61c08c3a9c85ae6519c9df9c08d8f5266 Mon Sep 17 00:00:00 2001 From: Stefan Horning Date: Fri, 23 Nov 2018 13:35:25 +0100 Subject: [PATCH] Ecs service module health check settings (#47217) * Added feature health_check_grace_period_seconds to ecs_service, this time with a botocore version check and some initial testing * Only set health_check_grace_period_seconds when loadbalancers are defined * Removed leftover commas and fix in test * Removed blank line * Minor improvements for ecs_service module * Removed default (30) for health_check_grace_period_seconds param * Changed botocore version allowed to 1.8.20 for health check param. * Fix empty healthcheck failure --- .../modules/cloud/amazon/ecs_service.py | 35 ++++++++++++++----- .../roles/ecs_cluster/defaults/main.yml | 1 + .../roles/ecs_cluster/tasks/main.yml | 3 ++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/ansible/modules/cloud/amazon/ecs_service.py b/lib/ansible/modules/cloud/amazon/ecs_service.py index cad2cfff33..7fb0ea808a 100644 --- a/lib/ansible/modules/cloud/amazon/ecs_service.py +++ b/lib/ansible/modules/cloud/amazon/ecs_service.py @@ -121,6 +121,11 @@ options: required: false version_added: 2.7 choices: ["EC2", "FARGATE"] + health_check_grace_period_seconds: + description: + - Seconds to wait before health checking the freshly added/updated services. This option requires botocore >= 1.8.20. + required: false + version_added: 2.8 extends_documentation_fragment: - aws - ec2 @@ -384,7 +389,7 @@ class EcsServiceManager: def create_service(self, service_name, cluster_name, task_definition, load_balancers, desired_count, client_token, role, deployment_configuration, placement_constraints, placement_strategy, network_configuration, - launch_type): + launch_type, health_check_grace_period_seconds): params = dict( cluster=cluster_name, serviceName=service_name, @@ -401,19 +406,24 @@ class EcsServiceManager: params['networkConfiguration'] = network_configuration if launch_type: params['launchType'] = launch_type + if self.health_check_setable(params) and health_check_grace_period_seconds is not None: + params['healthCheckGracePeriodSeconds'] = health_check_grace_period_seconds 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): + desired_count, deployment_configuration, network_configuration, health_check_grace_period_seconds): params = dict( cluster=cluster_name, service=service_name, taskDefinition=task_definition, desiredCount=desired_count, - deploymentConfiguration=deployment_configuration) + deploymentConfiguration=deployment_configuration + ) if network_configuration: params['networkConfiguration'] = network_configuration + if self.health_check_setable(params): + params['healthCheckGracePeriodSeconds'] = health_check_grace_period_seconds response = self.ecs.update_service(**params) return self.jsonize(response['service']) @@ -438,11 +448,15 @@ class EcsServiceManager: return self.ecs.delete_service(cluster=cluster, service=service) def ecs_api_handles_network_configuration(self): - from distutils.version import LooseVersion # There doesn't seem to be a nice way to inspect botocore to look # for attributes (and networkConfiguration is not an explicit argument # to e.g. ecs.run_task, it's just passed as a keyword argument) - return LooseVersion(botocore.__version__) >= LooseVersion('1.7.44') + return self.module.botocore_at_least('1.7.44') + + def health_check_setable(self, params): + load_balancers = params.get('loadBalancers', []) + # check if botocore (and thus boto3) is new enough for using the healthCheckGracePeriodSeconds parameter + return len(load_balancers) > 0 and self.module.botocore_at_least('1.8.20') def main(): @@ -466,7 +480,8 @@ def main(): security_groups=dict(type='list'), assign_public_ip=dict(type='bool'), )), - launch_type=dict(required=False, choices=['EC2', 'FARGATE']) + launch_type=dict(required=False, choices=['EC2', 'FARGATE']), + health_check_grace_period_seconds=dict(required=False, type='int') )) module = AnsibleAWSModule(argument_spec=argument_spec, @@ -536,7 +551,9 @@ def main(): module.params['task_definition'], module.params['desired_count'], deploymentConfiguration, - network_configuration) + network_configuration, + module.params['health_check_grace_period_seconds'] + ) else: try: response = service_mgr.create_service(module.params['name'], @@ -550,7 +567,9 @@ def main(): module.params['placement_constraints'], module.params['placement_strategy'], network_configuration, - module.params['launch_type']) + module.params['launch_type'], + module.params['health_check_grace_period_seconds'] + ) except botocore.exceptions.ClientError as e: module.fail_json_aws(e, msg="Couldn't create service") diff --git a/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/defaults/main.yml b/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/defaults/main.yml index 288f531f95..20e010e366 100644 --- a/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/defaults/main.yml +++ b/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/defaults/main.yml @@ -27,6 +27,7 @@ ecs_service_placement_strategy: ecs_task_container_port: 8080 ecs_target_group_name: "{{ resource_prefix[:28] }}-tg" ecs_load_balancer_name: "{{ resource_prefix[:29] }}-lb" +ecs_service_health_check_grace_period: 60 ecs_fargate_task_containers: - name: "{{ ecs_task_name }}" image: "{{ ecs_task_image_path }}" diff --git a/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/tasks/main.yml b/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/tasks/main.yml index 342253db25..78358b88d7 100644 --- a/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/tasks/main.yml +++ b/test/integration/targets/ecs_cluster/playbooks/roles/ecs_cluster/tasks/main.yml @@ -232,6 +232,7 @@ desired_count: 1 deployment_configuration: "{{ ecs_service_deployment_configuration }}" placement_strategy: "{{ ecs_service_placement_strategy }}" + health_check_grace_period_seconds: "{{ ecs_service_health_check_grace_period }}" load_balancers: - targetGroupArn: "{{ elb_target_group_instance.target_group_arn }}" containerName: "{{ ecs_task_name }}" @@ -254,6 +255,7 @@ desired_count: 1 deployment_configuration: "{{ ecs_service_deployment_configuration }}" placement_strategy: "{{ ecs_service_placement_strategy }}" + health_check_grace_period_seconds: "{{ ecs_service_health_check_grace_period }}" load_balancers: - targetGroupArn: "{{ elb_target_group_instance.target_group_arn }}" containerName: "{{ ecs_task_name }}" @@ -279,6 +281,7 @@ desired_count: 1 deployment_configuration: "{{ ecs_service_deployment_configuration }}" placement_strategy: "{{ ecs_service_placement_strategy }}" + health_check_grace_period_seconds: "{{ ecs_service_health_check_grace_period }}" load_balancers: - targetGroupArn: "{{ elb_target_group_instance.target_group_arn }}" containerName: "{{ ecs_task_name }}"