diff --git a/changelogs/fragments/migrate_sts_assume_role.yml b/changelogs/fragments/migrate_sts_assume_role.yml new file mode 100644 index 00000000000..49bb113ab2d --- /dev/null +++ b/changelogs/fragments/migrate_sts_assume_role.yml @@ -0,0 +1,4 @@ +breaking_changes: +- sts_assume_role - The module has been migrated from the ``community.aws`` collection. + Playbooks using the Fully Qualified Collection Name for this module should be updated + to use ``amazon.aws.sts_assume_role``. diff --git a/meta/runtime.yml b/meta/runtime.yml index 2a4ba354800..5d05436df14 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -203,7 +203,6 @@ action_groups: - stepfunctions_state_machine - stepfunctions_state_machine_execution - storagegateway_info - - sts_assume_role - sts_session_token - waf_condition - waf_info @@ -518,6 +517,8 @@ plugin_routing: redirect: amazon.aws.route53_zone s3_bucket_info: redirect: amazon.aws.s3_bucket_info + sts_assume_role: + redirect: amazon.aws.sts_assume_role module_utils: route53: redirect: amazon.aws.route53 \ No newline at end of file diff --git a/plugins/modules/sts_assume_role.py b/plugins/modules/sts_assume_role.py deleted file mode 100644 index 4d934c2d5cd..00000000000 --- a/plugins/modules/sts_assume_role.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -DOCUMENTATION = r""" ---- -module: sts_assume_role -version_added: 1.0.0 -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. -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 I(access_key), - I(secret_key) and I(session_token) parameters to modules that should use the assumed credentials. -extends_documentation_fragment: - - amazon.aws.common.modules - - amazon.aws.region.modules - - amazon.aws.boto3 -""" - -RETURN = r""" -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 = r""" -# Assume an existing role (more details: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) -- community.aws.sts_assume_role: - access_key: AKIA1EXAMPLE1EXAMPLE - secret_key: 123456789abcdefghijklmnopqrstuvwxyzABCDE - 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 -- amazon.aws.ec2_tag: - access_key: "{{ assumed_role.sts_creds.access_key }}" - secret_key: "{{ assumed_role.sts_creds.secret_key }}" - session_token: "{{ assumed_role.sts_creds.session_token }}" - resource: i-xyzxyz01 - state: present - tags: - MyNewTag: value - -""" - -try: - from botocore.exceptions import ClientError - from botocore.exceptions import ParamValidationError -except ImportError: - pass # caught by AnsibleAWSModule - -from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict - -from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as 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, no_log=True), - ) - - module = AnsibleAWSModule(argument_spec=argument_spec) - - connection = module.client("sts") - - assume_role_policy(connection, module) - - -if __name__ == "__main__": - main() diff --git a/tests/integration/targets/sts_assume_role/aliases b/tests/integration/targets/sts_assume_role/aliases deleted file mode 100644 index 4ef4b2067d0..00000000000 --- a/tests/integration/targets/sts_assume_role/aliases +++ /dev/null @@ -1 +0,0 @@ -cloud/aws diff --git a/tests/integration/targets/sts_assume_role/defaults/main.yml b/tests/integration/targets/sts_assume_role/defaults/main.yml deleted file mode 100644 index 17072d6a4fd..00000000000 --- a/tests/integration/targets/sts_assume_role/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -iam_role_name: "ansible-test-{{ tiny_prefix }}" diff --git a/tests/integration/targets/sts_assume_role/meta/main.yml b/tests/integration/targets/sts_assume_role/meta/main.yml deleted file mode 100644 index 32cf5dda7ed..00000000000 --- a/tests/integration/targets/sts_assume_role/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] diff --git a/tests/integration/targets/sts_assume_role/tasks/main.yml b/tests/integration/targets/sts_assume_role/tasks/main.yml deleted file mode 100644 index 23e0dba7843..00000000000 --- a/tests/integration/targets/sts_assume_role/tasks/main.yml +++ /dev/null @@ -1,305 +0,0 @@ ---- -# tasks file for sts_assume_role - -- module_defaults: - group/aws: - region: "{{ aws_region }}" - access_key: "{{ aws_access_key }}" - secret_key: "{{ aws_secret_key }}" - session_token: "{{ security_token | default(omit) }}" - collections: - - amazon.aws - block: - # Get some information about who we are before starting our tests - # we'll need this as soon as we start working on the policies - - name: get ARN of calling user - aws_caller_info: - register: aws_caller_info - - - name: register account id - set_fact: - aws_account: "{{ aws_caller_info.account }}" - - # ============================================================ - - name: create test iam role - iam_role: - name: "{{ iam_role_name }}" - assume_role_policy_document: "{{ lookup('template','policy.json.j2') }}" - create_instance_profile: False - managed_policy: - - arn:aws:iam::aws:policy/IAMReadOnlyAccess - state: present - register: test_role - - # ============================================================ - - name: pause to ensure role exists before using - pause: - seconds: 30 - - # ============================================================ - - name: test with no parameters - sts_assume_role: - access_key: '{{ omit }}' - secret_key: '{{ omit }}' - session_token: '{{ omit }}' - register: result - ignore_errors: true - - - name: assert with no parameters - assert: - that: - - 'result.failed' - - "'missing required arguments:' in result.msg" - - # ============================================================ - - name: test with only 'role_arn' parameter - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - register: result - ignore_errors: true - - - name: assert with only 'role_arn' parameter - assert: - that: - - 'result.failed' - - "'missing required arguments: role_session_name' in result.msg" - - # ============================================================ - - name: test with only 'role_session_name' parameter - sts_assume_role: - role_session_name: "AnsibleTest" - register: result - ignore_errors: true - - - name: assert with only 'role_session_name' parameter - assert: - that: - - 'result.failed' - - "'missing required arguments: role_arn' in result.msg" - - # ============================================================ - - name: test assume role with invalid policy - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - role_session_name: "AnsibleTest" - policy: "invalid policy" - register: result - ignore_errors: true - - - name: assert assume role with invalid policy - assert: - that: - - 'result.failed' - - "'The policy is not in the valid JSON format.' in result.msg" - when: result.module_stderr is not defined - - - name: assert assume role with invalid policy - assert: - that: - - 'result.failed' - - "'The policy is not in the valid JSON format.' in result.module_stderr" - when: result.module_stderr is defined - - # ============================================================ - - name: test assume role with invalid duration seconds - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - role_session_name: AnsibleTest - duration_seconds: invalid duration - register: result - ignore_errors: true - - - name: assert assume role with invalid duration seconds - assert: - that: - - result is failed - - "'duration_seconds' in result.msg" - - "'cannot be converted to an int' in result.msg" - - # ============================================================ - - name: test assume role with invalid external id - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - role_session_name: AnsibleTest - external_id: invalid external id - register: result - ignore_errors: true - - - name: assert assume role with invalid external id - assert: - that: - - 'result.failed' - - "'Member must satisfy regular expression pattern:' in result.msg" - when: result.module_stderr is not defined - - - name: assert assume role with invalid external id - assert: - that: - - 'result.failed' - - "'Member must satisfy regular expression pattern:' in result.module_stderr" - when: result.module_stderr is defined - - # ============================================================ - - name: test assume role with invalid mfa serial number - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - role_session_name: AnsibleTest - mfa_serial_number: invalid serial number - register: result - ignore_errors: true - - - name: assert assume role with invalid mfa serial number - assert: - that: - - 'result.failed' - - "'Member must satisfy regular expression pattern:' in result.msg" - when: result.module_stderr is not defined - - - name: assert assume role with invalid mfa serial number - assert: - that: - - 'result.failed' - - "'Member must satisfy regular expression pattern:' in result.module_stderr" - when: result.module_stderr is defined - - # ============================================================ - - name: test assume role with invalid mfa token code - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - role_session_name: AnsibleTest - mfa_token: invalid token code - register: result - ignore_errors: true - - - name: assert assume role with invalid mfa token code - assert: - that: - - 'result.failed' - - "'Member must satisfy regular expression pattern:' in result.msg" - when: result.module_stderr is not defined - - - name: assert assume role with invalid mfa token code - assert: - that: - - 'result.failed' - - "'Member must satisfy regular expression pattern:' in result.module_stderr" - when: result.module_stderr is defined - - # ============================================================ - - name: test assume role with invalid role_arn - sts_assume_role: - role_arn: invalid role arn - role_session_name: AnsibleTest - register: result - ignore_errors: true - - - name: assert assume role with invalid role_arn - assert: - that: - - result.failed - - "'Invalid length for parameter RoleArn' in result.msg" - when: result.module_stderr is not defined - - - name: assert assume role with invalid role_arn - assert: - that: - - 'result.failed' - - "'Member must have length greater than or equal to 20' in result.module_stderr" - when: result.module_stderr is defined - - # ============================================================ - - name: test assume not existing sts role - sts_assume_role: - role_arn: "arn:aws:iam::123456789:role/non-existing-role" - role_session_name: "AnsibleTest" - register: result - ignore_errors: true - - - name: assert assume not existing sts role - assert: - that: - - 'result.failed' - - "'is not authorized to perform: sts:AssumeRole' in result.msg" - when: result.module_stderr is not defined - - - name: assert assume not existing sts role - assert: - that: - - 'result.failed' - - "'is not authorized to perform: sts:AssumeRole' in result.msg" - when: result.module_stderr is defined - - # ============================================================ - - name: test assume role - sts_assume_role: - role_arn: "{{ test_role.iam_role.arn }}" - role_session_name: AnsibleTest - register: assumed_role - - - name: assert assume role - assert: - that: - - 'not assumed_role.failed' - - "'sts_creds' in assumed_role" - - "'access_key' in assumed_role.sts_creds" - - "'secret_key' in assumed_role.sts_creds" - - "'session_token' in assumed_role.sts_creds" - - # ============================================================ - - name: test that assumed credentials have IAM read-only access - iam_role: - access_key: "{{ assumed_role.sts_creds.access_key }}" - secret_key: "{{ assumed_role.sts_creds.secret_key }}" - session_token: "{{ assumed_role.sts_creds.session_token }}" - name: "{{ iam_role_name }}" - assume_role_policy_document: "{{ lookup('template','policy.json.j2') }}" - create_instance_profile: False - state: present - register: result - - - name: assert assumed role with privileged action (expect changed=false) - assert: - that: - - 'not result.failed' - - 'not result.changed' - - "'iam_role' in result" - - # ============================================================ - - name: test assumed role with unprivileged action - iam_role: - access_key: "{{ assumed_role.sts_creds.access_key }}" - secret_key: "{{ assumed_role.sts_creds.secret_key }}" - session_token: "{{ assumed_role.sts_creds.session_token }}" - name: "{{ iam_role_name }}-new" - assume_role_policy_document: "{{ lookup('template','policy.json.j2') }}" - state: present - register: result - ignore_errors: true - - - name: assert assumed role with unprivileged action (expect changed=false) - assert: - that: - - 'result.failed' - - "'is not authorized to perform: iam:CreateRole' in result.msg" - # runs on Python2 - when: result.module_stderr is not defined - - - name: assert assumed role with unprivileged action (expect changed=false) - assert: - that: - - 'result.failed' - - "'is not authorized to perform: iam:CreateRole' in result.module_stderr" - # runs on Python3 - when: result.module_stderr is defined - - # ============================================================ - always: - - - name: delete test iam role - iam_role: - name: "{{ iam_role_name }}" - assume_role_policy_document: "{{ lookup('template','policy.json.j2') }}" - delete_instance_profile: True - managed_policy: - - arn:aws:iam::aws:policy/IAMReadOnlyAccess - state: absent diff --git a/tests/integration/targets/sts_assume_role/templates/policy.json.j2 b/tests/integration/targets/sts_assume_role/templates/policy.json.j2 deleted file mode 100644 index 559562fd91d..00000000000 --- a/tests/integration/targets/sts_assume_role/templates/policy.json.j2 +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "AWS": "arn:aws:iam::{{ aws_account }}:root" - }, - "Action": "sts:AssumeRole" - } - ] -} \ No newline at end of file