Improve consistency of IAM_{role,user,group} behaviour (#64258)
* iam_user: use AnsibleAWSModule.client to fetch connection rather than C&P code * iam_role: Add deprecation warning so we can switch purge_polices default behaviour from true to false * iam_user/role/group: Rename 'managed_policy' and 'purge_policy' Rename from singluar to plural (we accept a *list* of policies), and add aliases for the old values. * Cleanup documentation * Changelog
This commit is contained in:
parent
784e507671
commit
6e652ae6df
5 changed files with 76 additions and 60 deletions
5
changelogs/fragments/64258-purge_policies.yml
Normal file
5
changelogs/fragments/64258-purge_policies.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
deprecated_features:
|
||||
- 'iam_role: The default value of the purge_policies has been deprecated and will change from true to false in Ansible 2.14'
|
||||
minor_changes:
|
||||
- 'iam_role, iam_user and iam_group: the managed_policy option has been renamed to managed_policies (with an alias added)'
|
||||
- 'iam_role, iam_user and iam_group: the purge_policy option has been renamed to purge_policies (with an alias added)'
|
|
@ -58,7 +58,7 @@ The following functionality will be removed in Ansible 2.14. Please update updat
|
|||
|
||||
* The :ref:`openssl_csr <openssl_csr_module>` module's option ``version`` no longer supports values other than ``1`` (the current only standardized CSR version).
|
||||
* :ref:`docker_container <docker_container_module>`: the ``trust_image_content`` option will be removed. It has always been ignored by the module.
|
||||
* :ref:`iam_managed_policy <iam_managed_policy_module>`: the ``fail_on_delete`` option wil be removed. It has always been ignored by the module.
|
||||
* :ref:`iam_managed_policy <iam_managed_policy_module>`: the ``fail_on_delete`` option will be removed. It has always been ignored by the module.
|
||||
* :ref:`s3_lifecycle <s3_lifecycle_module>`: the ``requester_pays`` option will be removed. It has always been ignored by the module.
|
||||
* :ref:`s3_sync <s3_sync_module>`: the ``retries`` option will be removed. It has always been ignored by the module.
|
||||
* The return values ``err`` and ``out`` of :ref:`docker_stack <docker_stack_module>` have been deprecated. Use ``stdout`` and ``stderr`` from now on instead.
|
||||
|
@ -76,6 +76,7 @@ The following functionality will change in Ansible 2.14. Please update update yo
|
|||
|
||||
* The :ref:`docker_container <docker_container_module>` module has a new option, ``container_default_behavior``, whose default value will change from ``compatibility`` to ``no_defaults``. Set to an explicit value to avoid deprecation warnings.
|
||||
* :ref:`iam_policy <iam_policy_module>`: the default value for the ``skip_duplicates`` option will change from ``true`` to ``false``. To maintain the existing behavior explicitly set it to ``true``.
|
||||
* :ref:`iam_role <iam_role_module>`: the ``purge_policies`` option (also know as ``purge_policy``) default value will change from ``true`` to ``false``
|
||||
|
||||
|
||||
The following modules will be removed in Ansible 2.14. Please update your playbooks accordingly.
|
||||
|
|
|
@ -26,7 +26,7 @@ DOCUMENTATION = '''
|
|||
module: iam_group
|
||||
short_description: Manage AWS IAM groups
|
||||
description:
|
||||
- Manage AWS IAM groups
|
||||
- Manage AWS IAM groups.
|
||||
version_added: "2.4"
|
||||
author:
|
||||
- Nick Aslanidis (@naslanidis)
|
||||
|
@ -37,31 +37,36 @@ options:
|
|||
- The name of the group to create.
|
||||
required: true
|
||||
type: str
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
description:
|
||||
- A list of managed policy ARNs or friendly names to attach to the role. To embed an inline policy, use M(iam_policy).
|
||||
- A list of managed policy ARNs or friendly names to attach to the role.
|
||||
- To embed an inline policy, use M(iam_policy).
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ['managed_policy']
|
||||
users:
|
||||
description:
|
||||
- A list of existing users to add as members of the group.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
state:
|
||||
description:
|
||||
- Create or remove the IAM group
|
||||
- Create or remove the IAM group.
|
||||
required: true
|
||||
choices: [ 'present', 'absent' ]
|
||||
type: str
|
||||
purge_policy:
|
||||
purge_policies:
|
||||
description:
|
||||
- Detach policy which not included in managed_policy list
|
||||
- When I(purge_policies=true) any managed policies not listed in I(managed_policies) will be detatched.
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
aliases: ['purge_policy', 'purge_managed_policies']
|
||||
purge_users:
|
||||
description:
|
||||
- Detach users which not included in users list
|
||||
- When I(purge_users=true) users which are not included in I(users) will be detached.
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
|
@ -82,14 +87,14 @@ EXAMPLES = '''
|
|||
# Create a group and attach a managed policy using its ARN
|
||||
- iam_group:
|
||||
name: testgroup1
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
|
||||
state: present
|
||||
|
||||
# Create a group with users as members and attach a managed policy using its ARN
|
||||
- iam_group:
|
||||
name: testgroup1
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
|
||||
users:
|
||||
- test_user1
|
||||
|
@ -100,12 +105,12 @@ EXAMPLES = '''
|
|||
- iam_group:
|
||||
name: testgroup1
|
||||
state: present
|
||||
purge_policy: true
|
||||
purge_policies: true
|
||||
|
||||
# Remove all group members from an existing group
|
||||
- iam_group:
|
||||
name: testgroup1
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
|
||||
purge_users: true
|
||||
state: present
|
||||
|
@ -233,10 +238,10 @@ def create_or_update_group(connection, module):
|
|||
|
||||
params = dict()
|
||||
params['GroupName'] = module.params.get('name')
|
||||
managed_policies = module.params.get('managed_policy')
|
||||
managed_policies = module.params.get('managed_policies')
|
||||
users = module.params.get('users')
|
||||
purge_users = module.params.get('purge_users')
|
||||
purge_policy = module.params.get('purge_policy')
|
||||
purge_policies = module.params.get('purge_policies')
|
||||
changed = False
|
||||
if managed_policies:
|
||||
managed_policies = convert_friendly_names_to_arns(connection, module, managed_policies)
|
||||
|
@ -267,7 +272,7 @@ def create_or_update_group(connection, module):
|
|||
current_attached_policies_arn_list.append(policy['PolicyArn'])
|
||||
|
||||
# If managed_policies has a single empty element we want to remove all attached policies
|
||||
if purge_policy:
|
||||
if purge_policies:
|
||||
# Detach policies not present
|
||||
for policy_arn in list(set(current_attached_policies_arn_list) - set(managed_policies)):
|
||||
changed = True
|
||||
|
@ -408,11 +413,11 @@ def main():
|
|||
|
||||
argument_spec = dict(
|
||||
name=dict(required=True),
|
||||
managed_policy=dict(default=[], type='list'),
|
||||
managed_policies=dict(default=[], type='list', aliases=['managed_policy']),
|
||||
users=dict(default=[], type='list'),
|
||||
state=dict(choices=['present', 'absent'], required=True),
|
||||
purge_users=dict(default=False, type='bool'),
|
||||
purge_policy=dict(default=False, type='bool')
|
||||
purge_policies=dict(default=False, type='bool', aliases=['purge_policy', 'purge_managed_policies'])
|
||||
)
|
||||
|
||||
module = AnsibleAWSModule(
|
||||
|
|
|
@ -14,7 +14,7 @@ DOCUMENTATION = '''
|
|||
module: iam_role
|
||||
short_description: Manage AWS IAM roles
|
||||
description:
|
||||
- Manage AWS IAM roles
|
||||
- Manage AWS IAM roles.
|
||||
version_added: "2.3"
|
||||
author: "Rob White (@wimnat)"
|
||||
options:
|
||||
|
@ -30,15 +30,15 @@ options:
|
|||
type: str
|
||||
description:
|
||||
description:
|
||||
- Provide a description of the new role.
|
||||
- Provides a description of the role.
|
||||
version_added: "2.5"
|
||||
type: str
|
||||
boundary:
|
||||
description:
|
||||
- The ARN of an IAM managed policy to use to restrict the permissions this role can pass on to IAM roles/users that it creates.
|
||||
- Boundaries cannot be set on Instance Profiles, so if this option is specified then I(create_instance_profile) must be false.
|
||||
- Boundaries cannot be set on Instance Profiles, as such if this option is specified then I(create_instance_profile) must be C(false).
|
||||
- This is intended for roles/users that have permissions to create new IAM objects.
|
||||
- For more information on boundaries, see U(https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
|
||||
- For more information on boundaries, see U(https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html).
|
||||
- Requires botocore 1.10.57 or above.
|
||||
aliases: [boundary_policy_arn]
|
||||
version_added: "2.7"
|
||||
|
@ -46,13 +46,14 @@ options:
|
|||
assume_role_policy_document:
|
||||
description:
|
||||
- The trust relationship policy document that grants an entity permission to assume the role.
|
||||
- "This parameter is required when I(state=present)."
|
||||
- This parameter is required when I(state=present).
|
||||
type: json
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
description:
|
||||
- A list of managed policy ARNs or, since Ansible 2.4, a list of either managed policy ARNs or friendly names.
|
||||
To embed an inline policy, use M(iam_policy). To remove existing policies, use an empty list item.
|
||||
aliases: [ managed_policies ]
|
||||
- To remove all policies set I(purge_polices=true) and I(managed_policies=[None]).
|
||||
- To embed an inline policy, use M(iam_policy).
|
||||
aliases: ['managed_policy']
|
||||
type: list
|
||||
max_session_duration:
|
||||
description:
|
||||
|
@ -62,10 +63,11 @@ options:
|
|||
type: int
|
||||
purge_policies:
|
||||
description:
|
||||
- Detaches any managed policies not listed in the I(managed_policy) option. Set to false if you want to attach policies elsewhere.
|
||||
default: true
|
||||
- When I(purge_policies=true) any managed policies not listed in I(managed_policies) will be detatched.
|
||||
- By default I(purge_policies=true). In Ansible 2.14 this will be changed to I(purge_policies=false).
|
||||
version_added: "2.5"
|
||||
type: bool
|
||||
aliases: ['purge_policy', 'purge_managed_policies']
|
||||
state:
|
||||
description:
|
||||
- Create or remove the IAM role.
|
||||
|
@ -80,8 +82,8 @@ options:
|
|||
type: bool
|
||||
delete_instance_profile:
|
||||
description:
|
||||
- When deleting a role will also delete the instance profile created with
|
||||
the same name as the role.
|
||||
- When I(delete_instance_profile=true) and I(state=absent) deleting a role will also delete the instance
|
||||
profile created with the same I(name) as the role.
|
||||
- Only applies when I(state=absent).
|
||||
default: false
|
||||
version_added: "2.10"
|
||||
|
@ -119,14 +121,14 @@ EXAMPLES = '''
|
|||
iam_role:
|
||||
name: mynewrole
|
||||
assume_role_policy_document: "{{ lookup('file','policy.json') }}"
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
- arn:aws:iam::aws:policy/PowerUserAccess
|
||||
|
||||
- name: Keep the role created above but remove all managed policies
|
||||
iam_role:
|
||||
name: mynewrole
|
||||
assume_role_policy_document: "{{ lookup('file','policy.json') }}"
|
||||
managed_policy: []
|
||||
managed_policies: []
|
||||
|
||||
- name: Delete the role
|
||||
iam_role:
|
||||
|
@ -276,7 +278,10 @@ def create_or_update_role(connection, module):
|
|||
params['Description'] = module.params.get('description')
|
||||
if module.params.get('boundary') is not None:
|
||||
params['PermissionsBoundary'] = module.params.get('boundary')
|
||||
managed_policies = module.params.get('managed_policy')
|
||||
managed_policies = module.params.get('managed_policies')
|
||||
purge_policies = module.params.get('purge_policies')
|
||||
if purge_policies is None:
|
||||
purge_policies = True
|
||||
create_instance_profile = module.params.get('create_instance_profile')
|
||||
if managed_policies:
|
||||
managed_policies = convert_friendly_names_to_arns(connection, module, managed_policies)
|
||||
|
@ -320,7 +325,7 @@ def create_or_update_role(connection, module):
|
|||
current_attached_policies_arn_list = [policy['PolicyArn'] for policy in current_attached_policies]
|
||||
|
||||
# If a single empty list item then all managed policies to be removed
|
||||
if len(managed_policies) == 1 and not managed_policies[0] and module.params.get('purge_policies'):
|
||||
if len(managed_policies) == 1 and not managed_policies[0] and purge_policies:
|
||||
|
||||
# Detach policies not present
|
||||
if remove_policies(connection, module, set(current_attached_policies_arn_list) - set(managed_policies), params):
|
||||
|
@ -329,7 +334,7 @@ def create_or_update_role(connection, module):
|
|||
# Make a list of the ARNs from the attached policies
|
||||
|
||||
# Detach roles not defined in task
|
||||
if module.params.get('purge_policies'):
|
||||
if purge_policies:
|
||||
if remove_policies(connection, module, set(current_attached_policies_arn_list) - set(managed_policies), params):
|
||||
changed = True
|
||||
|
||||
|
@ -565,14 +570,14 @@ def main():
|
|||
name=dict(type='str', required=True),
|
||||
path=dict(type='str', default="/"),
|
||||
assume_role_policy_document=dict(type='json'),
|
||||
managed_policy=dict(type='list', aliases=['managed_policies']),
|
||||
managed_policies=dict(type='list', aliases=['managed_policy']),
|
||||
max_session_duration=dict(type='int'),
|
||||
state=dict(type='str', choices=['present', 'absent'], default='present'),
|
||||
description=dict(type='str'),
|
||||
boundary=dict(type='str', aliases=['boundary_policy_arn']),
|
||||
create_instance_profile=dict(type='bool', default=True),
|
||||
delete_instance_profile=dict(type='bool', default=False),
|
||||
purge_policies=dict(type='bool', default=True),
|
||||
purge_policies=dict(type='bool', aliases=['purge_policy', 'purge_managed_policies']),
|
||||
tags=dict(type='dict'),
|
||||
purge_tags=dict(type='bool', default=True),
|
||||
)
|
||||
|
@ -580,6 +585,10 @@ def main():
|
|||
required_if=[('state', 'present', ['assume_role_policy_document'])],
|
||||
supports_check_mode=True)
|
||||
|
||||
if module.params.get('purge_policies') is None:
|
||||
module.deprecate('In Ansible 2.14 the default value of purge_policies will change from true to false.'
|
||||
' To maintain the existing behaviour explicity set purge_policies=true', version='2.14')
|
||||
|
||||
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`.")
|
||||
|
|
|
@ -14,7 +14,7 @@ DOCUMENTATION = '''
|
|||
module: iam_user
|
||||
short_description: Manage AWS IAM users
|
||||
description:
|
||||
- Manage AWS IAM users
|
||||
- Manage AWS IAM users.
|
||||
version_added: "2.5"
|
||||
author: Josh Souza (@joshsouza)
|
||||
options:
|
||||
|
@ -23,23 +23,26 @@ options:
|
|||
- The name of the user to create.
|
||||
required: true
|
||||
type: str
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
description:
|
||||
- A list of managed policy ARNs or friendly names to attach to the user. To embed an inline policy, use M(iam_policy).
|
||||
- A list of managed policy ARNs or friendly names to attach to the user.
|
||||
- To embed an inline policy, use M(iam_policy).
|
||||
required: false
|
||||
type: list
|
||||
aliases: ['managed_policy']
|
||||
state:
|
||||
description:
|
||||
- Create or remove the IAM user
|
||||
- Create or remove the IAM user.
|
||||
required: true
|
||||
choices: [ 'present', 'absent' ]
|
||||
type: str
|
||||
purge_policy:
|
||||
purge_policies:
|
||||
description:
|
||||
- Detach policies which are not included in managed_policy list
|
||||
- When I(purge_policies=true) any managed policies not listed in I(managed_policies) will be detatched.
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
aliases: ['purge_policy', 'purge_managed_policies']
|
||||
requirements: [ botocore, boto3 ]
|
||||
extends_documentation_fragment:
|
||||
- aws
|
||||
|
@ -60,7 +63,7 @@ EXAMPLES = '''
|
|||
# Create a user and attach a managed policy using its ARN
|
||||
- iam_user:
|
||||
name: testuser1
|
||||
managed_policy:
|
||||
managed_policies:
|
||||
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
|
||||
state: present
|
||||
|
||||
|
@ -68,7 +71,7 @@ EXAMPLES = '''
|
|||
- iam_user:
|
||||
name: testuser1
|
||||
state: present
|
||||
purge_policy: true
|
||||
purge_policies: true
|
||||
|
||||
# Delete the user
|
||||
- iam_user:
|
||||
|
@ -157,8 +160,8 @@ def create_or_update_user(connection, module):
|
|||
|
||||
params = dict()
|
||||
params['UserName'] = module.params.get('name')
|
||||
managed_policies = module.params.get('managed_policy')
|
||||
purge_policy = module.params.get('purge_policy')
|
||||
managed_policies = module.params.get('managed_policies')
|
||||
purge_policies = module.params.get('purge_policies')
|
||||
changed = False
|
||||
if managed_policies:
|
||||
managed_policies = convert_friendly_names_to_arns(connection, module, managed_policies)
|
||||
|
@ -189,7 +192,7 @@ def create_or_update_user(connection, module):
|
|||
current_attached_policies_arn_list.append(policy['PolicyArn'])
|
||||
|
||||
# If managed_policies has a single empty element we want to remove all attached policies
|
||||
if purge_policy:
|
||||
if purge_policies:
|
||||
# Detach policies not present
|
||||
for policy_arn in list(set(current_attached_policies_arn_list) - set(managed_policies)):
|
||||
changed = True
|
||||
|
@ -342,26 +345,19 @@ def delete_user_login_profile(connection, module, user_name):
|
|||
|
||||
def main():
|
||||
|
||||
argument_spec = ec2_argument_spec()
|
||||
argument_spec.update(
|
||||
dict(
|
||||
name=dict(required=True, type='str'),
|
||||
managed_policy=dict(default=[], type='list'),
|
||||
state=dict(choices=['present', 'absent'], required=True),
|
||||
purge_policy=dict(default=False, type='bool')
|
||||
)
|
||||
argument_spec = dict(
|
||||
name=dict(required=True, type='str'),
|
||||
managed_policies=dict(default=[], type='list', aliases=['managed_policy']),
|
||||
state=dict(choices=['present', 'absent'], required=True),
|
||||
purge_policies=dict(default=False, type='bool', aliases=['purge_policy', 'purge_managed_policies'])
|
||||
)
|
||||
|
||||
module = AnsibleAWSModule(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
if not HAS_BOTO3:
|
||||
module.fail_json(msg='boto3 required for this module')
|
||||
|
||||
region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)
|
||||
|
||||
connection = boto3_conn(module, conn_type='client', resource='iam', region=region, endpoint=ec2_url, **aws_connect_params)
|
||||
connection = module.client('iam')
|
||||
|
||||
state = module.params.get("state")
|
||||
|
||||
|
|
Loading…
Reference in a new issue