#!/usr/bin/python # Copyright: Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], 'supported_by': 'community'} DOCUMENTATION = ''' --- module: sts_assume_role short_description: Assume a role using AWS Security Token Service and obtain temporary credentials description: - Assume a role using AWS Security Token Service and obtain temporary credentials. version_added: "2.0" author: - Boris Ekelchik (@bekelchik) - Marek Piatek (@piontas) options: role_arn: description: - The Amazon Resource Name (ARN) of the role that the caller is assuming U(https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html#Identifiers_ARNs). required: true type: str role_session_name: description: - Name of the role's session - will be used by CloudTrail. required: true type: str policy: description: - Supplemental policy to use in addition to assumed role's policies. type: str duration_seconds: description: - The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) to 43200 seconds (12 hours). - The max depends on the IAM role's sessions duration setting. - By default, the value is set to 3600 seconds. type: int external_id: description: - A unique identifier that is used by third parties to assume a role in their customers' accounts. type: str mfa_serial_number: description: - The identification number of the MFA device that is associated with the user who is making the AssumeRole call. type: str mfa_token: description: - The value provided by the MFA device, if the trust policy of the role being assumed requires MFA. type: str notes: - In order to use the assumed role in a following playbook task you must pass the access_key, access_secret and access_token. extends_documentation_fragment: - aws - ec2 requirements: - boto3 - botocore - python >= 2.6 ''' RETURN = ''' sts_creds: description: The temporary security credentials, which include an access key ID, a secret access key, and a security (or session) token returned: always type: dict sample: access_key: XXXXXXXXXXXXXXXXXXXX expiration: 2017-11-11T11:11:11+00:00 secret_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX session_token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX sts_user: description: The Amazon Resource Name (ARN) and the assumed role ID returned: always type: dict sample: assumed_role_id: arn:aws:sts::123456789012:assumed-role/demo/Bob arn: ARO123EXAMPLE123:Bob changed: description: True if obtaining the credentials succeeds type: bool returned: always ''' EXAMPLES = ''' # Note: These examples do not set authentication details, see the AWS Guide for details. # Assume an existing role (more details: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) - sts_assume_role: role_arn: "arn:aws:iam::123456789012:role/someRole" role_session_name: "someRoleSession" register: assumed_role # Use the assumed role above to tag an instance in account 123456789012 - ec2_tag: aws_access_key: "{{ assumed_role.sts_creds.access_key }}" aws_secret_key: "{{ assumed_role.sts_creds.secret_key }}" security_token: "{{ assumed_role.sts_creds.session_token }}" resource: i-xyzxyz01 state: present tags: MyNewTag: value ''' from ansible.module_utils.aws.core import AnsibleAWSModule from ansible.module_utils.ec2 import camel_dict_to_snake_dict try: from botocore.exceptions import ClientError, ParamValidationError except ImportError: pass # caught by AnsibleAWSModule def _parse_response(response): credentials = response.get('Credentials', {}) user = response.get('AssumedRoleUser', {}) sts_cred = { 'access_key': credentials.get('AccessKeyId'), 'secret_key': credentials.get('SecretAccessKey'), 'session_token': credentials.get('SessionToken'), 'expiration': credentials.get('Expiration') } sts_user = camel_dict_to_snake_dict(user) return sts_cred, sts_user def assume_role_policy(connection, module): params = { 'RoleArn': module.params.get('role_arn'), 'RoleSessionName': module.params.get('role_session_name'), 'Policy': module.params.get('policy'), 'DurationSeconds': module.params.get('duration_seconds'), 'ExternalId': module.params.get('external_id'), 'SerialNumber': module.params.get('mfa_serial_number'), 'TokenCode': module.params.get('mfa_token') } changed = False kwargs = dict((k, v) for k, v in params.items() if v is not None) try: response = connection.assume_role(**kwargs) changed = True except (ClientError, ParamValidationError) as e: module.fail_json_aws(e) sts_cred, sts_user = _parse_response(response) module.exit_json(changed=changed, sts_creds=sts_cred, sts_user=sts_user) def main(): argument_spec = dict( role_arn=dict(required=True), role_session_name=dict(required=True), duration_seconds=dict(required=False, default=None, type='int'), external_id=dict(required=False, default=None), policy=dict(required=False, default=None), mfa_serial_number=dict(required=False, default=None), mfa_token=dict(required=False, default=None) ) module = AnsibleAWSModule(argument_spec=argument_spec) connection = module.client('sts') assume_role_policy(connection, module) if __name__ == '__main__': main()