From e83ff947f6bc1fca105223a6b2d436778b01bb3c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 15:18:45 +0000 Subject: [PATCH] iam_role - add assume_role_policy_document_raw (#1692) (#1694) [PR #1692/5bf51c0d backport][stable-5] iam_role - add assume_role_policy_document_raw This is a backport of PR #1692 as merged into main (5bf51c0). SUMMARY fixes: #551 assume_role_policy_document is an IAM policy document, and as such we shouldn't be modifying it. Running camel / snake conversion against the document breaks it. Adds assume_role_policy_document_raw and deprecates the current snake_case behaviour. ISSUE TYPE Feature Pull Request COMPONENT NAME iam_role iam_role_info ADDITIONAL INFORMATION Follows up on #1054 / #1068 Reviewed-by: Mark Chappell --- .../551-iam_role-policy_documents.yml | 7 ++++ plugins/modules/iam_role.py | 38 ++++++++++++++++++- plugins/modules/iam_role_info.py | 36 ++++++++++++++++-- .../iam_role/tasks/creation_deletion.yml | 5 ++- .../targets/iam_role/tasks/main.yml | 2 + 5 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/551-iam_role-policy_documents.yml diff --git a/changelogs/fragments/551-iam_role-policy_documents.yml b/changelogs/fragments/551-iam_role-policy_documents.yml new file mode 100644 index 00000000000..50164769d27 --- /dev/null +++ b/changelogs/fragments/551-iam_role-policy_documents.yml @@ -0,0 +1,7 @@ +minor_changes: +- iam_role - added ``assume_role_policy_document_raw`` to the role return values, this doesn't convert policy document contents from CamelCase to snake_case (https://github.com/ansible-collections/community.aws/issues/551). +- iam_role_info - added ``assume_role_policy_document_raw`` to the role return values, this doesn't convert policy document contents from CamelCase to snake_case (https://github.com/ansible-collections/community.aws/issues/551). +deprecated_features: +- iam_role - All top level return values other than ``iam_role`` and ``changed`` have been deprecated and will be removed in a release after 2023-12-01. (). +- iam_role - In a release after 2023-12-01 the contents of ``assume_role_policy_document`` will no longer be converted from CamelCase to snake_case. The ``assume_role_policy_document_raw`` return value already returns the policy document in this future format. +- iam_role_info - In a release after 2023-12-01 the contents of ``assume_role_policy_document`` will no longer be converted from CamelCase to snake_case. The ``assume_role_policy_document_raw`` return value already returns the policy document in this future format. diff --git a/plugins/modules/iam_role.py b/plugins/modules/iam_role.py index 09a86a54e82..4add6a52524 100644 --- a/plugins/modules/iam_role.py +++ b/plugins/modules/iam_role.py @@ -160,8 +160,12 @@ returned: always sample: "2016-08-14T04:36:28+00:00" assume_role_policy_document: - description: the policy that grants an entity permission to assume the role - type: str + description: + - the policy that grants an entity permission to assume the role + - | + note: the case of keys in this dictionary are currently converted from CamelCase to + snake_case. In a release after 2023-12-01 this behaviour will change + type: dict returned: always sample: { 'statement': [ @@ -176,6 +180,25 @@ ], 'version': '2012-10-17' } + assume_role_policy_document_raw: + description: the policy that grants an entity permission to assume the role + type: dict + returned: always + version_added: 5.3.0 + sample: { + 'Statement': [ + { + 'Action': 'sts:AssumeRole', + 'Effect': 'Allow', + 'Principal': { + 'Service': 'ec2.amazonaws.com' + }, + 'Sid': '' + } + ], + 'Version': '2012-10-17' + } + attached_policies: description: a list of dicts containing the name and ARN of the managed IAM policies attached to the role type: list @@ -498,6 +521,7 @@ def create_or_update_role(module, client): role['tags'] = get_role_tags(module, client) camel_role = camel_dict_to_snake_dict(role, ignore_list=['tags']) + camel_role["assume_role_policy_document_raw"] = role.get("AssumeRolePolicyDocument", {}) module.exit_json(changed=changed, iam_role=camel_role, **camel_role) @@ -674,6 +698,16 @@ def main(): required_if=[('state', 'present', ['assume_role_policy_document'])], supports_check_mode=True) + module.deprecate("All return values other than iam_role and changed have been deprecated and " + "will be removed in a release after 2023-12-01.", + date="2023-12-01", collection_name="community.aws") + + module.deprecate("In a release after 2023-12-01 the contents of iam_role.assume_role_policy_document " + "will no longer be converted from CamelCase to snake_case. The " + "iam_role.assume_role_policy_document_raw return value already returns the " + "policy document in this future format.", + date="2023-12-01", collection_name="community.aws") + if module.params.get('boundary'): if module.params.get('create_instance_profile'): module.fail_json(msg="When using a boundary policy, `create_instance_profile` must be set to `false`.") diff --git a/plugins/modules/iam_role_info.py b/plugins/modules/iam_role_info.py index 84e9a31718e..d66be487a92 100644 --- a/plugins/modules/iam_role_info.py +++ b/plugins/modules/iam_role_info.py @@ -61,9 +61,18 @@ type: str sample: arn:aws:iam::123456789012:role/AnsibleTestRole assume_role_policy_document: - description: Policy Document describing what can assume the role. + description: + - The policy that grants an entity permission to assume the role + - | + Note: the case of keys in this dictionary are currently converted from CamelCase to + snake_case. In a release after 2023-12-01 this behaviour will change. returned: always - type: str + type: dict + assume_role_policy_document_raw: + description: The policy document describing what can assume the role. + returned: always + type: dict + version_added: 5.3.0 create_date: description: Date IAM role was created. returned: always @@ -227,7 +236,22 @@ def describe_iam_roles(module, client): roles = list_iam_roles_with_backoff(client, **params)['Roles'] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't list IAM roles") - return [camel_dict_to_snake_dict(describe_iam_role(module, client, role), ignore_list=['tags']) for role in roles] + return [normalize_role(describe_iam_role(module, client, role)) for role in roles] + + +def normalize_profile(profile): + new_profile = camel_dict_to_snake_dict(profile) + if profile.get("Roles"): + profile["roles"] = [normalize_role(role) for role in profile.get("Roles")] + return new_profile + + +def normalize_role(role): + new_role = camel_dict_to_snake_dict(role, ignore_list=['tags']) + new_role["assume_role_policy_document_raw"] = role.get("AssumeRolePolicyDocument") + if role.get("InstanceProfiles"): + role["instance_profiles"] = [normalize_profile(profile) for profile in role.get("InstanceProfiles")] + return new_role def main(): @@ -245,6 +269,12 @@ def main(): client = module.client('iam', retry_decorator=AWSRetry.jittered_backoff()) + module.deprecate("In a release after 2023-12-01 the contents of assume_role_policy_document " + "will no longer be converted from CamelCase to snake_case. The " + ".assume_role_policy_document_raw return value already returns the " + "policy document in this future format.", + date="2023-12-01", collection_name="community.aws") + module.exit_json(changed=False, iam_roles=describe_iam_roles(module, client)) diff --git a/tests/integration/targets/iam_role/tasks/creation_deletion.yml b/tests/integration/targets/iam_role/tasks/creation_deletion.yml index 27c48309bce..0579a6d3430 100644 --- a/tests/integration/targets/iam_role/tasks/creation_deletion.yml +++ b/tests/integration/targets/iam_role/tasks/creation_deletion.yml @@ -105,8 +105,9 @@ - iam_role.iam_role.role_name == test_role - 'iam_role.iam_role.arn.startswith("arn")' - 'iam_role.iam_role.arn.endswith("role/" + test_role )' - # Would be nice to test the contents... - '"assume_role_policy_document" in iam_role.iam_role' + - '"assume_role_policy_document_raw" in iam_role.iam_role' + - iam_role.iam_role.assume_role_policy_document_raw == assume_deny_policy - iam_role.iam_role.attached_policies | length == 0 - iam_role.iam_role.max_session_duration == 3600 - iam_role.iam_role.path == '/' @@ -148,8 +149,10 @@ - 'role_info.iam_roles[0].arn.startswith("arn")' - 'role_info.iam_roles[0].arn.endswith("role/" + test_role )' - '"assume_role_policy_document" in role_info.iam_roles[0]' + - '"assume_role_policy_document_raw" in role_info.iam_roles[0]' - '"create_date" in role_info.iam_roles[0]' - '"description" not in role_info.iam_roles[0]' + - role_info.iam_roles[0].assume_role_policy_document_raw == assume_deny_policy - role_info.iam_roles[0].inline_policies | length == 0 - role_info.iam_roles[0].instance_profiles | length == 0 - role_info.iam_roles[0].managed_policies | length == 0 diff --git a/tests/integration/targets/iam_role/tasks/main.yml b/tests/integration/targets/iam_role/tasks/main.yml index b2db8e59c13..ae47ada1ad5 100644 --- a/tests/integration/targets/iam_role/tasks/main.yml +++ b/tests/integration/targets/iam_role/tasks/main.yml @@ -33,6 +33,8 @@ - amazon.aws - community.general block: + - set_fact: + assume_deny_policy: '{{ lookup("file", "deny-assume.json") | from_json }}' # =================================================================== # Parameter Checks - include_tasks: parameter_checks.yml