diff --git a/changelogs/fragments/64258-purge_policies.yml b/changelogs/fragments/64258-purge_policies.yml new file mode 100644 index 00000000000..8d3a3beb8a4 --- /dev/null +++ b/changelogs/fragments/64258-purge_policies.yml @@ -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)' diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.10.rst b/docs/docsite/rst/porting_guides/porting_guide_2.10.rst index 29542a4b224..5199503837a 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.10.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.10.rst @@ -58,7 +58,7 @@ The following functionality will be removed in Ansible 2.14. Please update updat * The :ref:`openssl_csr ` module's option ``version`` no longer supports values other than ``1`` (the current only standardized CSR version). * :ref:`docker_container `: the ``trust_image_content`` option will be removed. It has always been ignored by the module. -* :ref:`iam_managed_policy `: the ``fail_on_delete`` option wil be removed. It has always been ignored by the module. +* :ref:`iam_managed_policy `: the ``fail_on_delete`` option will be removed. It has always been ignored by the module. * :ref:`s3_lifecycle `: the ``requester_pays`` option will be removed. It has always been ignored by the module. * :ref:`s3_sync `: the ``retries`` option will be removed. It has always been ignored by the module. * The return values ``err`` and ``out`` of :ref:`docker_stack ` 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 ` 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 `: 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 `: 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. diff --git a/lib/ansible/modules/cloud/amazon/iam_group.py b/lib/ansible/modules/cloud/amazon/iam_group.py index 48d47107fed..4a9ae593b22 100644 --- a/lib/ansible/modules/cloud/amazon/iam_group.py +++ b/lib/ansible/modules/cloud/amazon/iam_group.py @@ -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( diff --git a/lib/ansible/modules/cloud/amazon/iam_role.py b/lib/ansible/modules/cloud/amazon/iam_role.py index dc4f62b0001..7e841ff3d18 100644 --- a/lib/ansible/modules/cloud/amazon/iam_role.py +++ b/lib/ansible/modules/cloud/amazon/iam_role.py @@ -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`.") diff --git a/lib/ansible/modules/cloud/amazon/iam_user.py b/lib/ansible/modules/cloud/amazon/iam_user.py index 2f5afec7e09..ea56ef07bbd 100644 --- a/lib/ansible/modules/cloud/amazon/iam_user.py +++ b/lib/ansible/modules/cloud/amazon/iam_user.py @@ -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")