diff --git a/lib/ansible/module_utils/aws/waiters.py b/lib/ansible/module_utils/aws/waiters.py new file mode 100644 index 00000000000..c8f9157dbc2 --- /dev/null +++ b/lib/ansible/module_utils/aws/waiters.py @@ -0,0 +1,52 @@ +# Copyright: (c) 2018, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +try: + import botocore.waiter as core_waiter +except ImportError: + pass # caught by HAS_BOTO3 + + +ec2_data = { + "version": 2, + "waiters": { + "RouteTableExists": { + "delay": 5, + "maxAttempts": 40, + "operation": "DescribeRouteTables", + "acceptors": [ + { + "matcher": "path", + "expected": True, + "argument": "length(RouteTables[]) > `0`", + "state": "success" + }, + { + "matcher": "error", + "expected": "InvalidRouteTableID.NotFound", + "state": "retry" + } + ] + } + } +} + + +def model_for(name): + ec2_models = core_waiter.WaiterModel(waiter_config=ec2_data) + return ec2_models.get_waiter(name) + + +waiters_by_name = { + ('EC2', 'route_table_exists'): lambda ec2: core_waiter.Waiter( + 'route_table_exists', + model_for('RouteTableExists'), + ec2.describe_route_tables) +} + + +def get_waiter(client, waiter_name): + try: + return waiters_by_name[(client.__class__.__name__, waiter_name)](client) + except KeyError: + raise NotImplementedError("Waiter {0} could not be found for client {1}. Available waiters: {2}".format( + waiter_name, type(client), ', '.join(repr(k) for k in waiters_by_name.keys()))) diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py index 0222dd579ee..29c33c7fc17 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py +++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py @@ -226,6 +226,7 @@ route_table: import re from time import sleep from ansible.module_utils.aws.core import AnsibleAWSModule +from ansible.module_utils.aws.waiters import get_waiter from ansible.module_utils.ec2 import ec2_argument_spec, boto3_conn, get_aws_connection_info from ansible.module_utils.ec2 import ansible_dict_to_boto3_filter_list from ansible.module_utils.ec2 import camel_dict_to_snake_dict, snake_dict_to_camel_dict @@ -649,11 +650,11 @@ def ensure_route_table_present(connection, module): try: route_table = connection.create_route_table(VpcId=vpc_id)['RouteTable'] # try to wait for route table to be present before moving on - for attempt in range(5): - if not get_route_table_by_id(connection, module, route_table['RouteTableId']): - sleep(2) - else: - break + get_waiter( + connection, 'route_table_exists' + ).wait( + RouteTableIds=[route_table['RouteTableId']], + ) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Error creating route table") else: