ansible/test/integration/targets/iam_role/tasks/main.yml
Mark Chappell 40660e7f6e iam_role : support managing max session duration and deleting the instance profile it creates (#62014)
* iam_role: Add support for managing MaxSessionDuration

* iam_role: Add support for deleting the IAM Instance Profiles we created

* iam_role: migrate all boto failures to fail_json_aws for consistency

* iam_role: test validity of path so we can throw a more understandable error

* iam_role: (integration tests) Split iam_role integration tests from sts_assume_role tests

- Make the iam_role tests more comprehensive
- Add tests for iam_role_info

* iam_role: (integration tests) Make some of our pauses optional

If the tests appear to be flakey we may need to enable standard_pauses
2019-09-20 13:26:29 -07:00

1218 lines
42 KiB
YAML

---
# Tests for iam_role and iam_role_info
#
# Tests:
# - Minimal Role creation
# - Role deletion
# - Fetching a specific role
# - Creating roles w/ and w/o instance profiles
# - Creating roles w/ a path
# - Updating Max Session Duration
# - Updating Description
# - Managing list of managed policies
# - Managing list of inline policies (for testing _info)
# - Managing boundary policy
#
# Notes:
# - Only tests *documented* return values ( RESULT.iam_role )
# - There are some known timing issues with boto3 returning before actions
# complete in the case of problems with "changed" status it's worth enabling
# the standard_pauses and paranoid_pauses options as a first step in debugging
#
# Possible Bugs:
# - Fails to delete role if inline policies not removed first
- name: 'Setup AWS connection info'
module_defaults:
group/aws:
aws_access_key: '{{ aws_access_key }}'
aws_secret_key: '{{ aws_secret_key }}'
security_token: '{{ security_token | default(omit) }}'
region: '{{ aws_region }}'
iam_role:
assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}'
block:
# ===================================================================
# Parameter Checks
- name: 'Friendly message when creating an instance profile and adding a boundary profile'
iam_role:
name: '{{ test_role }}'
boundary: '{{ boundary_policy }}'
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- '"boundary policy" in iam_role.msg'
- '"create_instance_profile" in iam_role.msg'
- '"false" in iam_role.msg'
- name: 'Friendly message when boundary profile is not an ARN'
iam_role:
name: '{{ test_role }}'
boundary: 'AWSDenyAll'
create_instance_profile: no
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- '"Boundary policy" in iam_role.msg'
- '"ARN" in iam_role.msg'
- name: 'Friendly message when "present" without assume_role_policy_document'
module_defaults: { iam_role: {} }
iam_role:
name: '{{ test_role }}'
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- 'iam_role.msg.startswith("state is present but all of the following are missing")'
- '"assume_role_policy_document" in iam_role.msg'
- name: 'Maximum Session Duration needs to be between 1 and 12 hours'
iam_role:
name: '{{ test_role }}'
max_session_duration: 3599
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- '"max_session_duration must be between" in iam_role.msg'
- name: 'Maximum Session Duration needs to be between 1 and 12 hours'
iam_role:
name: '{{ test_role }}'
max_session_duration: 43201
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- '"max_session_duration must be between" in iam_role.msg'
- name: 'Role Paths must start with /'
iam_role:
name: '{{ test_role }}'
path: 'test/'
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- '"path must begin and end with /" in iam_role.msg'
- name: 'Role Paths must end with /'
iam_role:
name: '{{ test_role }}'
path: '/test'
register: iam_role
ignore_errors: yes
- assert:
that:
- iam_role is failed
- '"path must begin and end with /" in iam_role.msg'
# ===================================================================
# Supplemental resource pre-creation
- name: 'Create Safe IAM Managed Policy'
iam_managed_policy:
state: present
policy_name: '{{ custom_policy_name }}'
policy_description: "A safe (deny-all) managed policy"
policy: "{{ lookup('file', 'deny-all.json') }}"
register: create_managed_policy
- assert:
that:
- create_managed_policy is succeeded
# ===================================================================
# Rapid Role Creation and deletion
- name: Try running some rapid fire create/delete tests
# We've previously seen issues with iam_role returning before creation's
# actually complete, if we think the issue's gone, let's try creating and
# deleting things in quick succession
when: not (standard_pauses | bool)
block:
- name: 'Minimal IAM Role without instance profile (rapid)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
register: iam_role
- name: 'Minimal IAM Role without instance profile (rapid)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
register: iam_role_again
- assert:
that:
- iam_role is changed
- iam_role_again is not changed
- name: 'Remove IAM Role (rapid)'
iam_role:
state: absent
name: '{{ test_role }}'
register: iam_role
- name: 'Remove IAM Role (rapid)'
iam_role:
state: absent
name: '{{ test_role }}'
register: iam_role_again
- assert:
that:
- iam_role is changed
- iam_role_again is not changed
- name: 'Minimal IAM Role without instance profile (rapid)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
register: iam_role
- name: 'Remove IAM Role (rapid)'
iam_role:
state: absent
name: '{{ test_role }}'
register: iam_role_again
- assert:
that:
- iam_role is changed
- iam_role_again is changed
# ===================================================================
# Role Creation
# (without Instance profile)
- name: 'iam_role_info before Role creation (no args)'
iam_role_info:
register: role_info
- assert:
that:
- role_info is succeeded
- name: 'iam_role_info before Role creation (search for test role)'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 0
- name: 'Minimal IAM Role (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
# Pause this first time, just in case we actually created something...
- name: Short pause for role creation to finish
pause:
seconds: 10
when: standard_pauses | bool
- name: 'iam_role_info after Role creation in check_mode'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 0
- name: 'Minimal IAM Role without instance profile'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
register: iam_role
- assert:
that:
- iam_role is changed
- 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'
- iam_role.iam_role.attached_policies | length == 0
- iam_role.iam_role.max_session_duration == 3600
- iam_role.iam_role.path == '/'
- iam_role.iam_role.role_name == test_role
- '"create_date" in iam_role.iam_role'
- '"role_id" in iam_role.iam_role'
- name: Short pause for role creation to finish
pause:
seconds: 10
when: standard_pauses | bool
- name: 'Minimal IAM Role without instance profile (no change)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after Role creation'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- '"description" not in role_info.iam_roles[0]'
- 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
- role_info.iam_roles[0].max_session_duration == 3600
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
- name: 'Remove IAM Role'
iam_role:
state: absent
name: '{{ test_role }}'
delete_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: Short pause for role removal to finish
pause:
seconds: 10
when: paranoid_pauses | bool
- name: 'iam_role_info after Role deletion'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 0
# (with path)
- name: 'Minimal IAM Role with path (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
path: '{{ test_path }}'
register: iam_role
check_mode: yes
- assert:
that:
- iam_role is changed
- name: 'Minimal IAM Role with path'
iam_role:
name: '{{ test_role }}'
path: '{{ test_path }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- 'iam_role.iam_role.arn.startswith("arn")'
- 'iam_role.iam_role.arn.endswith("role" + test_path + test_role )'
# Would be nice to test the contents...
- '"assume_role_policy_document" in iam_role.iam_role'
- iam_role.iam_role.attached_policies | length == 0
- iam_role.iam_role.max_session_duration == 3600
- iam_role.iam_role.path == '{{ test_path }}'
- iam_role.iam_role.role_name == test_role
- '"create_date" in iam_role.iam_role'
- '"role_id" in iam_role.iam_role'
- name: Short pause for role creation to finish
pause:
seconds: 10
when: standard_pauses | bool
- name: 'Minimal IAM Role with path (no change)'
iam_role:
name: '{{ test_role }}'
path: '{{ test_path }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after Role creation'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- 'role_info.iam_roles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].arn.endswith("role" + test_path + test_role )'
- '"assume_role_policy_document" 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].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile" + test_path + test_role)'
- role_info.iam_roles[0].managed_policies | length == 0
- role_info.iam_roles[0].max_session_duration == 3600
- role_info.iam_roles[0].path == '{{ test_path }}'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
- name: 'iam_role_info after Role creation (searching a path)'
iam_role_info:
path_prefix: '{{ test_path }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- 'role_info.iam_roles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].arn.endswith("role" + test_path + test_role )'
- '"assume_role_policy_document" 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].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile" + test_path + test_role)'
- role_info.iam_roles[0].managed_policies | length == 0
- role_info.iam_roles[0].max_session_duration == 3600
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].path == '{{ test_path }}'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
- name: 'Remove IAM Role'
iam_role:
state: absent
name: '{{ test_role }}'
path: '{{ test_path }}'
# If we don't delete the existing profile it'll be reused (with the path)
# by the test below.
delete_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: Short pause for role removal to finish
pause:
seconds: 10
when: paranoid_pauses | bool
- name: 'iam_role_info after Role deletion'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 0
# (with Instance profile)
- name: 'Minimal IAM Role with instance profile'
iam_role:
name: '{{ test_role }}'
create_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is changed
- 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'
- iam_role.iam_role.attached_policies | length == 0
- iam_role.iam_role.max_session_duration == 3600
- iam_role.iam_role.path == '/'
- iam_role.iam_role.role_name == test_role
- '"create_date" in iam_role.iam_role'
- '"role_id" in iam_role.iam_role'
- name: Short pause for role creation to finish
pause:
seconds: 10
when: standard_pauses | bool
- name: 'Minimal IAM Role wth instance profile (no change)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after Role creation'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- '"description" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 0
- role_info.iam_roles[0].max_session_duration == 3600
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
# ===================================================================
# Max Session Duration Manipulation
- name: 'Update Max Session Duration (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
max_session_duration: 43200
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Update Max Session Duration'
iam_role:
name: '{{ test_role }}'
max_session_duration: 43200
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- iam_role.iam_role.max_session_duration == 43200
- name: 'Update Max Session Duration (no change)'
iam_role:
name: '{{ test_role }}'
max_session_duration: 43200
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after updating Max Session Duration'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- '"description" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 0
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
# ===================================================================
# Description Manipulation
- name: 'Add Description (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
description: 'Ansible Test Role {{ resource_prefix }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Add Description'
iam_role:
name: '{{ test_role }}'
description: 'Ansible Test Role {{ resource_prefix }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- iam_role.iam_role.description == 'Ansible Test Role {{ resource_prefix }}'
- name: 'Add Description (no change)'
iam_role:
name: '{{ test_role }}'
description: 'Ansible Test Role {{ resource_prefix }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- iam_role.iam_role.description == 'Ansible Test Role {{ resource_prefix }}'
- name: 'iam_role_info after adding Description'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role {{ resource_prefix }}"'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 0
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
- name: 'Update Description (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
description: 'Ansible Test Role (updated) {{ resource_prefix }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Update Description'
iam_role:
name: '{{ test_role }}'
description: 'Ansible Test Role (updated) {{ resource_prefix }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- iam_role.iam_role.description == 'Ansible Test Role (updated) {{ resource_prefix }}'
- name: 'Update Description (no change)'
iam_role:
name: '{{ test_role }}'
description: 'Ansible Test Role (updated) {{ resource_prefix }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- iam_role.iam_role.description == 'Ansible Test Role (updated) {{ resource_prefix }}'
- name: 'iam_role_info after updating Description'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role (updated) {{ resource_prefix }}"'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 0
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
# ===================================================================
# Policy Manipulation
- name: 'Add Managed Policy (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
purge_policies: no
managed_policy:
- '{{ safe_managed_policy }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Add Managed Policy'
iam_role:
name: '{{ test_role }}'
purge_policies: no
managed_policy:
- '{{ safe_managed_policy }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- name: 'Add Managed Policy (no change)'
iam_role:
name: '{{ test_role }}'
purge_policies: no
managed_policy:
- '{{ safe_managed_policy }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after adding Managed Policy'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role (updated) {{ resource_prefix }}"'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 1
- safe_managed_policy in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- custom_policy_name not in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
- name: 'Update Managed Policy without purge (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
purge_policies: no
managed_policy:
- '{{ custom_policy_name }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Update Managed Policy without purge'
iam_role:
name: '{{ test_role }}'
purge_policies: no
managed_policy:
- '{{ custom_policy_name }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- name: 'Update Managed Policy without purge (no change)'
iam_role:
name: '{{ test_role }}'
purge_policies: no
managed_policy:
- '{{ custom_policy_name }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after updating Managed Policy without purge'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role (updated) {{ resource_prefix }}"'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 2
- safe_managed_policy in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- custom_policy_name in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
# Managed Policies are purged by default
- name: 'Update Managed Policy with purge (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
managed_policy:
- '{{ custom_policy_name }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Update Managed Policy with purge'
iam_role:
name: '{{ test_role }}'
managed_policy:
- '{{ custom_policy_name }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- name: 'Update Managed Policy with purge (no change)'
iam_role:
name: '{{ test_role }}'
managed_policy:
- '{{ custom_policy_name }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after updating Managed Policy with purge'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role (updated) {{ resource_prefix }}"'
- role_info.iam_roles[0].inline_policies | length == 0
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 1
- safe_managed_policy not in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- custom_policy_name in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
# ===================================================================
# Inline Policy (test _info behaviour)
# XXX Not sure if it's a bug in Ansible or a "quirk" of AWS, but these two
# policies need to have at least different Sids or the second doesn't show
# up...
- name: 'Attach inline policy a'
iam_policy:
state: present
iam_type: 'role'
iam_name: '{{ test_role }}'
policy_name: 'inline-policy-a'
policy_json: '{{ lookup("file", "deny-all-a.json") }}'
- name: 'Attach inline policy b'
iam_policy:
state: present
iam_type: 'role'
iam_name: '{{ test_role }}'
policy_name: 'inline-policy-b'
policy_json: '{{ lookup("file", "deny-all-b.json") }}'
- name: 'iam_role_info after attaching inline policies (using iam_policy)'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role (updated) {{ resource_prefix }}"'
- role_info.iam_roles[0].inline_policies | length == 2
- '"inline-policy-a" in role_info.iam_roles[0].inline_policies'
- '"inline-policy-b" in role_info.iam_roles[0].inline_policies'
- role_info.iam_roles[0].instance_profiles | length == 1
- role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role
- 'role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile/" + test_role)'
- role_info.iam_roles[0].managed_policies | length == 1
- safe_managed_policy not in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- custom_policy_name in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == '/'
- '"permissions_boundary" not in role_info.iam_roles[0]'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
# XXX iam_role fails to remove inline policies before deleting the role
- name: 'Detach inline policy a'
iam_policy:
state: absent
iam_type: 'role'
iam_name: '{{ test_role }}'
policy_name: 'inline-policy-a'
- name: 'Detach inline policy b'
iam_policy:
state: absent
iam_type: 'role'
iam_name: '{{ test_role }}'
policy_name: 'inline-policy-b'
# ===================================================================
# Role Removal
- name: 'Remove IAM Role (CHECK MODE)'
iam_role:
state: absent
name: '{{ test_role }}'
delete_instance_profile: yes
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Short pause for role removal to finish'
pause:
seconds: 10
when: paranoid_pauses | bool
- name: 'iam_role_info after deleting role in check mode'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- name: 'Remove IAM Role'
iam_role:
state: absent
name: '{{ test_role }}'
delete_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Short pause for role removal to finish'
pause:
seconds: 10
when: paranoid_pauses | bool
- name: 'iam_role_info after deleting role'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 0
- name: 'Remove IAM Role (should be gone already)'
iam_role:
state: absent
name: '{{ test_role }}'
delete_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is not changed
- name: 'Short pause for role removal to finish'
pause:
seconds: 10
when: paranoid_pauses | bool
# ===================================================================
# Boundary Policy (requires create_instance_profile: no)
- name: 'Create minimal role with no boundary policy'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- name: 'Configure Boundary Policy (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
boundary: '{{ boundary_policy }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: 'Configure Boundary Policy'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
boundary: '{{ boundary_policy }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- name: 'Configure Boundary Policy (no change)'
iam_role:
name: '{{ test_role }}'
create_instance_profile: no
boundary: '{{ boundary_policy }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after adding boundary policy'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- '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]'
- '"create_date" in role_info.iam_roles[0]'
- '"description" not in role_info.iam_roles[0]'
- 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
- role_info.iam_roles[0].max_session_duration == 3600
- role_info.iam_roles[0].path == '/'
- role_info.iam_roles[0].permissions_boundary.permissions_boundary_arn == boundary_policy
- role_info.iam_roles[0].permissions_boundary.permissions_boundary_type == 'Policy'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
- name: 'Remove IAM Role'
iam_role:
state: absent
name: '{{ test_role }}'
delete_instance_profile: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: Short pause for role removal to finish
pause:
seconds: 10
when: paranoid_pauses | bool
# ===================================================================
# Complex role Creation
- name: 'Complex IAM Role (CHECK MODE)'
iam_role:
name: '{{ test_role }}'
assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}'
boundary: '{{ boundary_policy }}'
create_instance_profile: no
description: 'Ansible Test Role {{ resource_prefix }}'
managed_policy:
- '{{ safe_managed_policy }}'
- '{{ custom_policy_name }}'
max_session_duration: 43200
path: '{{ test_path }}'
check_mode: yes
register: iam_role
- assert:
that:
- iam_role is changed
- name: Short pause for role creation to finish
pause:
seconds: 10
when: standard_pauses | bool
- name: 'iam_role_info after Complex Role creation in check_mode'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 0
- name: 'Complex IAM Role'
iam_role:
name: '{{ test_role }}'
assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}'
boundary: '{{ boundary_policy }}'
create_instance_profile: no
description: 'Ansible Test Role {{ resource_prefix }}'
managed_policy:
- '{{ safe_managed_policy }}'
- '{{ custom_policy_name }}'
max_session_duration: 43200
path: '{{ test_path }}'
register: iam_role
- assert:
that:
- iam_role is changed
- iam_role.iam_role.role_name == test_role
- 'iam_role.iam_role.arn.startswith("arn")'
- 'iam_role.iam_role.arn.endswith("role" + test_path + test_role )'
# Would be nice to test the contents...
- '"assume_role_policy_document" in iam_role.iam_role'
- iam_role.iam_role.attached_policies | length == 2
- iam_role.iam_role.max_session_duration == 43200
- iam_role.iam_role.path == test_path
- iam_role.iam_role.role_name == test_role
- '"create_date" in iam_role.iam_role'
- '"role_id" in iam_role.iam_role'
- name: Short pause for role creation to finish
pause:
seconds: 10
when: standard_pauses | bool
- name: 'Complex IAM role (no change)'
iam_role:
name: '{{ test_role }}'
assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}'
boundary: '{{ boundary_policy }}'
create_instance_profile: no
description: 'Ansible Test Role {{ resource_prefix }}'
managed_policy:
- '{{ safe_managed_policy }}'
- '{{ custom_policy_name }}'
max_session_duration: 43200
path: '{{ test_path }}'
register: iam_role
- assert:
that:
- iam_role is not changed
- iam_role.iam_role.role_name == test_role
- name: 'iam_role_info after Role creation'
iam_role_info:
name: '{{ test_role }}'
register: role_info
- assert:
that:
- role_info is succeeded
- role_info.iam_roles | length == 1
- 'role_info.iam_roles[0].arn.startswith("arn")'
- 'role_info.iam_roles[0].arn.endswith("role" + test_path + test_role )'
- '"assume_role_policy_document" in role_info.iam_roles[0]'
- '"create_date" in role_info.iam_roles[0]'
- 'role_info.iam_roles[0].description == "Ansible Test Role {{ resource_prefix }}"'
- 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 == 2
- safe_managed_policy in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- custom_policy_name in ( role_info | json_query("iam_roles[*].managed_policies[*].policy_name") | list | flatten )
- role_info.iam_roles[0].max_session_duration == 43200
- role_info.iam_roles[0].path == test_path
- role_info.iam_roles[0].permissions_boundary.permissions_boundary_arn == boundary_policy
- role_info.iam_roles[0].permissions_boundary.permissions_boundary_type == 'Policy'
- role_info.iam_roles[0].role_id == iam_role.iam_role.role_id
- role_info.iam_roles[0].role_name == test_role
always:
# ===================================================================
# Cleanup
# XXX iam_role fails to remove inline policies before deleting the role
- name: 'Detach inline policy a'
iam_policy:
state: absent
iam_type: 'role'
iam_name: '{{ test_role }}'
policy_name: 'inline-policy-a'
ignore_errors: true
- name: 'Detach inline policy b'
iam_policy:
state: absent
iam_type: 'role'
iam_name: '{{ test_role }}'
policy_name: 'inline-policy-b'
ignore_errors: true
- name: 'Remove IAM Role'
iam_role:
state: absent
name: '{{ test_role }}'
delete_instance_profile: yes
ignore_errors: true
- name: 'Remove IAM Role (with path)'
iam_role:
state: absent
name: '{{ test_role }}'
path: '{{ test_path }}'
delete_instance_profile: yes
ignore_errors: true
- name: 'iam_role_info after Role deletion'
iam_role_info:
name: '{{ test_role }}'
ignore_errors: true
- name: 'Remove test managed policy'
iam_managed_policy:
state: absent
policy_name: '{{ custom_policy_name }}'