diff --git a/changelogs/fragments/66988-ansibleawsmodule-region.yaml b/changelogs/fragments/66988-ansibleawsmodule-region.yaml new file mode 100644 index 00000000000..272e0b59c78 --- /dev/null +++ b/changelogs/fragments/66988-ansibleawsmodule-region.yaml @@ -0,0 +1,2 @@ +minor_changes: +- 'AnsibleAWSModule - Add a helper (region) so that modules which migrate to using module.client() can still access the region information' diff --git a/lib/ansible/module_utils/aws/core.py b/lib/ansible/module_utils/aws/core.py index 0b6f05534c1..c4527b6deb4 100644 --- a/lib/ansible/module_utils/aws/core.py +++ b/lib/ansible/module_utils/aws/core.py @@ -75,7 +75,8 @@ except ImportError: from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native -from ansible.module_utils.ec2 import HAS_BOTO3, camel_dict_to_snake_dict, ec2_argument_spec, boto3_conn, get_aws_connection_info +from ansible.module_utils.ec2 import HAS_BOTO3, camel_dict_to_snake_dict, ec2_argument_spec, boto3_conn +from ansible.module_utils.ec2 import get_aws_connection_info, get_aws_region # We will also export HAS_BOTO3 so end user modules can use it. __all__ = ('AnsibleAWSModule', 'HAS_BOTO3', 'is_boto3_error_code') @@ -189,6 +190,10 @@ class AnsibleAWSModule(object): return boto3_conn(self, conn_type='resource', resource=service, region=region, endpoint=ec2_url, **aws_connect_kwargs) + @property + def region(self, boto3=True): + return get_aws_region(self, boto3) + def fail_json_aws(self, exception, msg=None): """call fail_json with processed exception diff --git a/lib/ansible/module_utils/ec2.py b/lib/ansible/module_utils/ec2.py index d461b12687a..5599ee7ea3e 100644 --- a/lib/ansible/module_utils/ec2.py +++ b/lib/ansible/module_utils/ec2.py @@ -203,6 +203,39 @@ def ec2_argument_spec(): return spec +def get_aws_region(module, boto3=False): + region = module.params.get('region') + + if region: + return region + + if 'AWS_REGION' in os.environ: + return os.environ['AWS_REGION'] + if 'AWS_DEFAULT_REGION' in os.environ: + return os.environ['AWS_DEFAULT_REGION'] + if 'EC2_REGION' in os.environ: + return os.environ['EC2_REGION'] + + if not boto3: + if not HAS_BOTO: + module.fail_json(msg=missing_required_lib('boto'), exception=BOTO_IMP_ERR) + # boto.config.get returns None if config not found + region = boto.config.get('Boto', 'aws_region') + if region: + return region + return boto.config.get('Boto', 'ec2_region') + + if not HAS_BOTO3: + module.fail_json(msg=missing_required_lib('boto3'), exception=BOTO3_IMP_ERR) + + # here we don't need to make an additional call, will default to 'us-east-1' if the below evaluates to None. + try: + profile_name = module.params.get('profile') + return botocore.session.Session(profile=profile_name).get_config_variable('region') + except botocore.exceptions.ProfileNotFound as e: + return None + + def get_aws_connection_info(module, boto3=False): # Check module args for credentials, then check environment vars @@ -212,7 +245,7 @@ def get_aws_connection_info(module, boto3=False): access_key = module.params.get('aws_access_key') secret_key = module.params.get('aws_secret_key') security_token = module.params.get('security_token') - region = module.params.get('region') + region = get_aws_region(module, boto3) profile_name = module.params.get('profile') validate_certs = module.params.get('validate_certs') config = module.params.get('aws_config') @@ -253,31 +286,6 @@ def get_aws_connection_info(module, boto3=False): # in case secret_key came in as empty string secret_key = None - if not region: - if 'AWS_REGION' in os.environ: - region = os.environ['AWS_REGION'] - elif 'AWS_DEFAULT_REGION' in os.environ: - region = os.environ['AWS_DEFAULT_REGION'] - elif 'EC2_REGION' in os.environ: - region = os.environ['EC2_REGION'] - else: - if not boto3: - if HAS_BOTO: - # boto.config.get returns None if config not found - region = boto.config.get('Boto', 'aws_region') - if not region: - region = boto.config.get('Boto', 'ec2_region') - else: - module.fail_json(msg=missing_required_lib('boto'), exception=BOTO_IMP_ERR) - elif HAS_BOTO3: - # here we don't need to make an additional call, will default to 'us-east-1' if the below evaluates to None. - try: - region = botocore.session.Session(profile=profile_name).get_config_variable('region') - except botocore.exceptions.ProfileNotFound as e: - pass - else: - module.fail_json(msg=missing_required_lib('boto3'), exception=BOTO3_IMP_ERR) - if not security_token: if os.environ.get('AWS_SECURITY_TOKEN'): security_token = os.environ['AWS_SECURITY_TOKEN'] diff --git a/lib/ansible/modules/cloud/amazon/ec2_vol_info.py b/lib/ansible/modules/cloud/amazon/ec2_vol_info.py index 47c2eb7db23..0989f9bb6ba 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_vol_info.py +++ b/lib/ansible/modules/cloud/amazon/ec2_vol_info.py @@ -67,7 +67,7 @@ except ImportError: pass # caught by AnsibleAWSModule from ansible.module_utils.aws.core import AnsibleAWSModule -from ansible.module_utils.ec2 import AWSRetry, get_aws_connection_info +from ansible.module_utils.ec2 import AWSRetry from ansible.module_utils.ec2 import boto3_tag_list_to_ansible_dict, ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict @@ -119,12 +119,9 @@ def list_ec2_volumes(connection, module): except ClientError as e: module.fail_json_aws(e, msg="Failed to describe volumes.") - # We add region to the volume info so we need it here - region = get_aws_connection_info(module, boto3=True)[0] - for volume in all_volumes["Volumes"]: volume = camel_dict_to_snake_dict(volume, ignore_list=['Tags']) - volume_dict_array.append(get_volume_info(volume, region)) + volume_dict_array.append(get_volume_info(volume, module.region)) module.exit_json(volumes=volume_dict_array)