
    Vh`v                        d Z dZdZddlZddlmZ ddlmZ ddlmZ ddlm	Z	 dd	lm
Z
 dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d de      Z ej<                  d      d        Zd Z d Z!d Z"d Z# ej<                  d       d!        Z$ ej<                  d"      d#        Z% ej<                  d$      d%        Z& ej<                  d&      d'        Z' ej<                  d(      d)        Z( ejR                  d*      d+        Z*d, Z+d- Z,d. Z-d/ Z.d0 Z/d1 Z0 ejR                  d2      d3        Z1 ej<                  d4       ejd                  d5g6      d7               Z3 ejh                  d8      d9        Z5d: Z6 ej<                  d;      d<        Z7d= Z8d> Z9e:d?k(  r e9        yy)@a  
---
module: iam_role
version_added: 1.0.0
version_added_collection: community.aws
short_description: Manage AWS IAM roles
description:
  - Manage AWS IAM roles.
author:
  - "Rob White (@wimnat)"
options:
  path:
    description:
      - The path of the role.
      - For more information about IAM paths, see the AWS IAM identifiers documentation
        U(https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html).
      - Updating the path on an existing role is not currently supported and will result in a
        warning.
      - O(path_prefix) and O(prefix) were added as aliases in release 7.2.0.
    type: str
    aliases: ["prefix", "path_prefix"]
  name:
    description:
      - The name of the role.
      - >-
        Note: Role names are unique within an account.  Paths (O(path)) do B(not) affect
        the uniqueness requirements of O(name).  For example it is not permitted to have both
        C(/Path1/MyRole) and C(/Path2/MyRole) in the same account.
      - O(role_name) was added as an alias in release 7.2.0.
    required: true
    type: str
    aliases: ["role_name"]
  description:
    description:
      - Provides a description of the role.
    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, as such if this option is specified then O(create_instance_profile) must be V(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).
    aliases: [boundary_policy_arn]
    type: str
  assume_role_policy_document:
    description:
      - The trust relationship policy document that grants an entity permission to assume the role.
      - This parameter is required when O(state=present).
    type: json
  managed_policies:
    description:
      - A list of managed policy ARNs, or friendly names.
      - To remove all policies set O(purge_policies=true) and O(managed_policies=[]).
      - To embed an inline policy, use M(amazon.aws.iam_policy).
    aliases: ['managed_policy']
    type: list
    elements: str
  max_session_duration:
    description:
      - The maximum duration (in seconds) of a session when assuming the role.
      - Valid values are between 1 and 12 hours (3600 and 43200 seconds).
    type: int
  purge_policies:
    description:
      - When O(purge_policies=true) any managed policies not listed in O(managed_policies) will be detatched.
    type: bool
    aliases: ['purge_policy', 'purge_managed_policies']
    default: true
  state:
    description:
      - Create or remove the IAM role.
    default: present
    choices: [ present, absent ]
    type: str
  create_instance_profile:
    description:
      - If no IAM instance profile with the same O(name) exists, setting O(create_instance_profile=True)
        will create an IAM instance profile along with the role.
      - This option has been deprecated and will be removed in a release after 2026-05-01.  The
        M(amazon.aws.iam_instance_profile) module can be used to manage instance profiles.
      - Defaults to V(True)
    type: bool
  delete_instance_profile:
    description:
      - When O(delete_instance_profile=true) and O(state=absent) deleting a role will also delete an
        instance profile with the same O(name) as the role, but only if the instance profile is
        associated with the role.
      - Only applies when O(state=absent).
      - This option has been deprecated and will be removed in a release after 2026-05-01.  The
        M(amazon.aws.iam_instance_profile) module can be used to manage instance profiles.
      - Defaults to V(False)
    type: bool
  wait_timeout:
    description:
      - How long (in seconds) to wait for creation / update to complete.
    default: 120
    type: int
  wait:
    description:
      - When O(wait=True) the module will wait for up to O(wait_timeout) seconds
        for IAM role creation before returning.
    default: True
    type: bool
extends_documentation_fragment:
  - amazon.aws.common.modules
  - amazon.aws.region.modules
  - amazon.aws.tags
  - amazon.aws.boto3
a  
# Note: These examples do not set authentication details, see the AWS Guide for details.

- name: Create a role with description and tags
  amazon.aws.iam_role:
    name: mynewrole
    assume_role_policy_document: "{{ lookup('file','policy.json') }}"
    description: This is My New Role
    tags:
      env: dev

- name: "Create a role and attach a managed policy called 'PowerUserAccess'"
  amazon.aws.iam_role:
    name: mynewrole
    assume_role_policy_document: "{{ lookup('file','policy.json') }}"
    managed_policies:
      - arn:aws:iam::aws:policy/PowerUserAccess

- name: Keep the role created above but remove all managed policies
  amazon.aws.iam_role:
    name: mynewrole
    assume_role_policy_document: "{{ lookup('file','policy.json') }}"
    managed_policies: []

- name: Delete the role
  amazon.aws.iam_role:
    name: mynewrole
    assume_role_policy_document: "{{ lookup('file', 'policy.json') }}"
    state: absent
a  
iam_role:
    description: Dictionary containing the IAM Role data.
    returned: success
    type: complex
    contains:
        path:
            description: The path to the role.
            type: str
            returned: always
            sample: /
        role_name:
            description: The friendly name that identifies the role.
            type: str
            returned: always
            sample: myrole
        role_id:
            description: The stable and unique string identifying the role.
            type: str
            returned: always
            sample: ABCDEFF4EZ4ABCDEFV4ZC
        arn:
            description: The Amazon Resource Name (ARN) specifying the role.
            type: str
            returned: always
            sample: "arn:aws:iam::1234567890:role/mynewrole"
        create_date:
            description: The date and time, in ISO 8601 date-time format, when the role was created.
            type: str
            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.
              - |
                Note: the case of keys in this dictionary are no longer converted from CamelCase to
                snake_case. This behaviour changed in release 8.0.0.
            type: dict
            returned: always
            sample: {
                        'statement': [
                            {
                                'action': 'sts:AssumeRole',
                                'effect': 'Allow',
                                'principal': {
                                    'service': 'ec2.amazonaws.com'
                                },
                                'sid': ''
                            }
                        ],
                        'version': '2012-10-17'
                    }
        assume_role_policy_document_raw:
            description:
              - |
                Note: this return value has been deprecated and will be removed in a release after
                2026-05-01. RV(iam_role.assume_role_policy_document) and RV(iam_role.assume_role_policy_document_raw)
                now use the same format.
            type: dict
            returned: always
            sample: {
                        'statement': [
                            {
                                'action': 'sts:AssumeRole',
                                'effect': 'Allow',
                                'principal': {
                                    'service': 'ec2.amazonaws.com'
                                },
                                'sid': ''
                            }
                        ],
                        'version': '2012-10-17'
                    }
            version_added: 5.3.0
        attached_policies:
            description: A list of dicts containing the name and ARN of the managed IAM policies attached to the role.
            type: list
            elements: dict
            returned: always
            sample: [
                {
                    'policy_arn': 'arn:aws:iam::aws:policy/PowerUserAccess',
                    'policy_name': 'PowerUserAccess'
                }
            ]
            contains:
                policy_arn:
                    description: The Amazon Resource Name (ARN) specifying the managed policy.
                    type: str
                    sample: "arn:aws:iam::123456789012:policy/test_policy"
                policy_name:
                    description: The friendly name that identifies the policy.
                    type: str
                    sample: test_policy
        description:
            description: A description of the role.
            type: str
            returned: always
            sample: "This is My New Role"
        max_session_duration:
            description: The maximum duration (in seconds) of a session when assuming the role.
            type: int
            returned: always
            sample: 3600
        role_last_used:
            description: Contains information about the last time that an IAM role was used.
            type: dict
            returned: always
            sample: {
                        "last_used_date": "2023-11-22T21:54:29+00:00",
                        "region": "us-east-2"
                    }
            contains:
                last_used_date:
                    description: The date and time, in  ISO 8601 date-time format that the role was last used.
                    type: str
                    returned: always
                region:
                    description: The name of the Amazon Web Services Region in which the role was last used.
                    type: str
                    returned: always
        tags:
            description: role tags
            type: dict
            returned: always
            sample: '{"Env": "Prod"}'
    N)validate_aws_arn)AnsibleIAMError)IAMErrorHandler) add_role_to_iam_instance_profile)$convert_managed_policy_names_to_arns)create_iam_instance_profile)delete_iam_instance_profile)get_iam_role)list_iam_instance_profiles)list_iam_role_attached_policies)normalize_iam_role)%remove_role_from_iam_instance_profile)validate_iam_identifiers)AnsibleAWSModule)compare_policies)AWSRetry)ansible_dict_to_boto3_tag_list)boto3_tag_list_to_ansible_dict)compare_aws_tagsc                       e Zd Zy)AnsibleIAMAlreadyExistsErrorN)__name__
__module____qualname__     g/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/amazon/aws/plugins/modules/iam_role.pyr   r   +  s    r   r   zwait for role creationc                 ~    |s|ry t        |d      }||z  }| j                  d      }|j                  ||d|       y )N   role_exists)DelayMaxAttempts)WaiterConfigRoleName)min
get_waiterwait)client
check_mode	role_namer'   wait_timeoutdelaymax_attemptswaiters           r   wait_iam_existsr/   /  sL    Ta E5(L}-F
KK$\B  r   c                     |sy|ry|D ]4  }  t        j                  d| d      | j                        ||d       6 y)NFTzattach policy z to roler$   	PolicyArn	aws_retry)r   common_error_handlerattach_role_policy)r(   r)   policies_to_attachr*   
policy_arns        r   attach_policiesr8   >  sV    ( 

nS,,~j\-RSTZTmTmn*	

 r   c                     |sy|ry|D ]4  }  t        j                  d| d      | j                        ||d       6 y)NFTzdetach policy z
 from roler1   )r   deletion_error_handlerdetach_role_policy)r(   r)   policies_to_remover*   policys        r   remove_policiesr>   K  sV    $ 
nS..xz/RSTZTmTmn&D	

 r   c                     t        | |      }|D ]4  }  t        j                  d| d      | j                        ||d       6 y )Nzdelete policy z embedded in roleT)r$   
PolicyNamer3   )get_inline_policy_listr   r:   delete_role_policy)r(   r*   current_inline_policiesr=   s       r   remove_inline_policiesrD   X  sS    4VYG) 
uZ..xGX/YZ[a[t[tu6T	

r   c                    t               }| j                  j                  d      xs d|d<   | j                  j                  d      |d<   | j                  j                  d      |d<   | j                  j                  d      | j                  j                  d      |d	<   | j                  j                  d
      | j                  j                  d
      |d<   | j                  j                  d      | j                  j                  d      |d<   | j                  j                  d      't        | j                  j                  d            |d<   |S )Npath/Pathnamer$   assume_role_policy_documentAssumeRolePolicyDocumentdescriptionDescriptionmax_session_durationMaxSessionDurationboundaryPermissionsBoundarytagsTags)dictparamsgetr   )modulerU   s     r   generate_create_paramsrX   `  s   VF]]&&v.5#F6N**62F:)/):):;X)YF%&}}'3 & 1 1- @}}}/0<'-}}'8'89O'P#$}}$0(.(9(9*(E$%}} ,78I8I&8QRvMr   zcreate rolec                     | j                   r| j                  d       t        |       } |j                  dddi|}t	        ||d         }|S )zi
    Perform the Role creation.
    Assumes tests for the role existing have already been performed.
    Tchangedr3   r$   r   )r)   	exit_jsonrX   create_role_get_role_with_backoff)rW   r(   rU   roles       r   create_basic_roler`   q  sZ     &#F+F6777D
 "&&*<=DKr   z"update assume role policy for rolec                 v    |t        |t        j                  |            sy|ry| j                  ||d       y)NFT)r$   PolicyDocumentr3   )r   jsonloadsupdate_assume_role_policy)r(   r)   r*   target_assumed_policycurrent_assumed_policys        r   update_role_assumed_policyrh     sE     $,<=SUYU_U_`uUv,w
$$iH]im$nr   zupdate description for rolec                 B    |||k(  ry|ry| j                  ||d       y)NFT)r$   rM   r3   update_role)r(   r)   r*   target_descriptioncurrent_descriptions        r   update_role_descriptionrn     s6     !%8<N%N
	7IUYZr   z(update maximum session duration for rolec                 B    |||k(  ry|ry| j                  ||d       y)NFT)r$   rO   r3   rj   )r(   r)   r*   target_durationcurrent_durations        r    update_role_max_session_durationrr     s4     "2o"E
	oY]^r   z#update permission boundary for rolec                 ,     | j                   dddi| y )Nr3   Tr   )put_role_permissions_boundaryr(   rU   s     r   _put_role_permissions_boundaryrv     s    (F((B4B6Br   z$remove permission boundary from rolec                 (     | j                   di | y )Nr   ) delete_role_permissions_boundaryru   s     r   !_delete_role_permissions_boundaryry     s    +F++5f5r   c                 \    |||k(  ry|ry|dk(  rt        | |       yt        | ||       y)NFT r$   )r$   rQ   )ry   rv   )r(   r)   r*   permissions_boundarycurrent_permissions_boundarys        r    update_role_permissions_boundaryr     sC    #';?['[r!)&9E  	'v	Wklr   c                 D   |yt        | |      }|D cg c]  }|d   	 }}t        |      dk(  r|d   g }t        |      t        |      z
  }|r|ng }t        |      t        |      z
  }	d}
|r|r|ry|
t        | |||      z  }
|	r|ry|
t	        | ||	|      z  }
|
S c c}w )NFr2      r   T)r   lensetr>   r8   )r(   r)   r*   managed_policiespurge_policiescurrent_attached_policiesr=   "current_attached_policies_arn_listr<   r6   r[   s              r   update_managed_policiesr     s     !@	 RLe)f&&*=)f&)f
!&6q&9&A?@3GWCXX/=+2-.5W1XXG,vz;MyYYGvz;MyYYGN- *gs   Bc           	         | j                   }| j                  j                  d      }| j                  j                  d      }| j                  j                  d      }| j                  j                  d      }| j                  j                  d      }	| j                  j                  d      }
| j                  j                  d      }|j                  d      }|j                  d	      }|j                  d
      }|j                  di       j                  dd      }|j                  dg       }t        ||||      r'| j	                  d|j                  d       d| d       d}|t        |||||
|      z  }|t        |||||      z  }|t        |||||      z  }|t        |||||      z  }|t        ||||	|      z  }|S )NrJ   rL   rN   rF   rP   
purge_tagsrR   rK   rM   rO   rQ   PermissionsBoundaryArnr{   rS   z:iam_role doesn't support updating the path: current path 'rH   z', requested path ''F)
r)   rU   rV   update_role_pathwarnupdate_role_tagsrh   rn   rr   r   )rW   r(   r*   r_   r)   assumed_policyrL   durationrF   r}   r   rR   rg   rm   rq   r~   current_tagsr[   s                     r   update_basic_roler     s   ""J]]&&'DEN--##M2K}}  !78H==V$D!==,,Z8""<0J==V$D "XX&@A((=1xx 45#'88,A2#F#J#JKceg#h 88FB'L 
D$7HRXIYHZZmnrmsstu	
 G 
ItZQ]^^G)&*iYoppG&vz9kSfggG/
IxYijjG/
I';=Y G Nr   c                 6   | j                   }| j                  j                  d      }| j                  j                  d      }| j                  j                  d      }| j                  j                  d      }| j                  j                  d      }	|	rt        ||	      }	d}
t	        ||      }|t        | |      }t        |||||       d}
nt        | |||      }
t        |||||       |r!	 |
t        ||||      z  }
t        |||||       |
t        || j                   ||	|      z  }
t        |||||       t	        ||      }t        ||      |d
<   t        |d      }| j                  |
|       y # t        $ r | j                  d| d	       Y w xY w)Nr'   r+   rF   r   r   FTprofile z' already exists and will not be updatedAttachedPolicies)
_v7_compat)r[   iam_role)r)   rU   rV   r   r
   r`   r/   r   create_instance_profilesr   r   r   r   r   r\   )rW   r(   r*   create_instance_profiler)   r'   r+   rF   r   r   r[   r_   
camel_roles                r   create_or_update_roler     s   ""J==V$D==$$^4L==V$D]]&&'78N}}(();<?HXYG 	*D | 0
It\J#FFItD
It\J	W/
ItTTGFJ	4N &vv/@/@)M]_mnnGFJ	4F 	*D>vyQD	#DT:J
Wz: , 	WKK(9+-TUV	Ws   0 E7 7FFc                     t        |       }t        fd|D              ryt        |       }|rt        d d      |ry|xs d}t        | |i        t	        |        y)	Nr_   c              3   .   K   | ]  }|d    k(    yw)InstanceProfileNameNr   ).0pr*   s     r   	<genexpr>z+create_instance_profiles.<locals>.<genexpr>5  s     
HQ1"#y0
Hs   F)rI   r   z already existsTrG   )r   anyr   r   r   )r(   r)   r*   rF   role_profilesnamed_profiles     `   r   r   r   1  so    .vIFM

H-
HH.vIFM*Xi[+PQQ;3D	4<$VY	Br   c                     t        | |      }|sy|ry|D ])  }|d   }t        | ||       |s||k(  st        | |       + y)zsRemoves the role from instance profiles and deletes the instance profile if
    delete_instance_profile is set
    r   FTr   N)r   r   r	   )r(   r)   r*   delete_instance_profileinstance_profilesprofileprofile_names          r   remove_instance_profilesr   G  s]    
 36	J % >45-flIN&9$'=>r   zdelete rolec                     t        | |      }|y|ryt        | |||       t        | ||g d       t        | |       | j	                  d|       y)NFT)r3   r$   )r
   r   r   rD   delete_role)r(   r)   r*   delete_profilesr_   s        r   destroy_roler   ]  s\    	*D| VZOLFJ	2tD69-
	:r   zget roleNoSuchEntity)catch_extra_error_codesc                 .    | j                  |      d    y )Nr|   Role)get_roler(   rI   s     r   r^   r^   s  s     OOTO"6*r   z&list attached inline policies for rolec                 .    | j                  |d      d   S )NT)r$   r3   PolicyNames)list_role_policiesr   s     r   rA   rA   y  s    $$dd$CMRRr   c                 <    |y||j                  d      k(  ry|ry	 y)NFrH   T)rV   )r(   r)   r_   rF   s       r   r   r   ~  s,    |txx 	r   zset tags for rolec                     |yt        |      }t        |||      \  }}|s|sy|ry|r| j                  ||d       |r| j                  |t	        |      d       y)NF)r   T)r$   TagKeysr3   )r$   rS   r3   )r   r   
untag_roletag_roler   )r(   r)   r*   new_tagsr   existing_tagstags_to_addtags_to_removes           r   r   r     sp    2=AM"2=(Wa"bK+9nPTU1OP[1\hlmr   c                 V   | j                   j                  d      rg| j                   j                  d      dur| j                  d       t        | j                   j                  d      d      s| j                  d       | j                   j                  d	      r7| j                   j                  d	      }|d
k  s|dkD  r| j                  d       t	        d| j                   j                  d      | j                   j                  d            }|r| j                  |       y y )NrP   r   FzOWhen using a boundary policy, `create_instance_profile` must be set to `false`.)msgiam)servicezBoundary policy must be an ARNrN   i  i  zLmax_session_duration must be between 1 and 12 hours (3600 and 43200 seconds)r_   rI   rF   )rI   rF   )rU   rV   	fail_jsonr   r   )rW   rN   identifier_problems      r   validate_paramsr     s    }}$==67uD!rs 1 1* =uM!AB}}/0%}}001GH$&*>*F!op1V]]&&v.V]]5F5Fv5N /0 r   c                     t        t        ddgd      t        dddg      t        d	      t        d
dgd      t        d	      t        dddgd      t        d	      t        ddg      t        d	      t        d	      t        ddddg      t        ddg      t        dd      t        dd      t        dd            } t        | dddgfgd      }|j                  dd d!"       |j                  j	                  d#      |j                  d$d d!"       |j                  j	                  d%      |j                  d&d d!"       t        |       |j                  d't        j                         (      }|j                  j	                  d      }|j                  j	                  d)      }|j                  j	                  d#      }|dn|}|j                  j	                  d%      xs d*}	 |dk(  rt        ||||       y |dk(  r+t        ||j                  ||      }|j                  |+       y y # t        $ r}|j                  |       Y d }~y d }~ww xY w),Nstrr*   T)typealiasesrequiredpath_prefixprefix)r   r   rc   )r   listmanaged_policy)r   r   elementsintpresentabsent)r   choicesdefaultboundary_policy_arnboolpurge_policypurge_managed_policies)r   r   r   rT   resource_tags)r   r   x   )r   r   )rI   rF   rJ   r   rN   staterL   rP   r   r   r   rR   r   r'   r+   r   rJ   )argument_specrequired_ifsupports_check_modezIn a release after 2026-05-01 iam_role.assume_role_policy_document_raw will no longer be returned.  Since release 8.0.0 assume_role_policy_document has been returned with the same format as iam_role.assume_role_policy_document_rawz
2026-05-01z
amazon.aws)datecollection_namer   zIn a release after 2026-05-01 the 'create_instance_profile' option will be removed. The amazon.aws.iam_instance_profile module can be used to manage instance profiles instead.r   zIn a release after 2026-05-01 the 'delete_instance_profile' option will be removed. The amazon.aws.iam_instance_profile module can be used to manage and delete instance profiles instead.r   )retry_decoratorrI   FrZ   )rT   r   	deprecaterU   rV   r   r(   r   jittered_backoffr   r   r)   r\   r   fail_json_aws_error)	r   rW   r(   r   r*   create_profiledelete_profiler[   es	            r   mainr     sm   u{mdCu}h&?@$(f$564D3EPUV!u-	8'<iPe$5+@*AB $& 1 $& 1DvPh?ijv'89VT2vt,#E2M$ #y+H*IJK F 	] $   }}23;j(	 	 	
 }}23;  ( 	 	
 F]]5(2K2K2M]NFMMg&E!!&)I]]&&'@AN+3TN]]&&'@AJUN&I!&&)^Lh"66+<+<iXGW-   &""1%%&s   5H: 	/H: :	III__main__);DOCUMENTATIONEXAMPLESRETURNrc   7ansible_collections.amazon.aws.plugins.module_utils.arnr   7ansible_collections.amazon.aws.plugins.module_utils.iamr   r   r   r   r   r	   r
   r   r   r   r   r   ;ansible_collections.amazon.aws.plugins.module_utils.modulesr   :ansible_collections.amazon.aws.plugins.module_utils.policyr   ;ansible_collections.amazon.aws.plugins.module_utils.retriesr   ;ansible_collections.amazon.aws.plugins.module_utils.taggingr   r   r   r   r4   r/   r8   r>   rD   rX   r`   rh   rn   rr   rv   r:   ry   r   r   r   r   r   r   r   r   r^   list_error_handlerrA   r   r   r   r   r   r   r   r   <module>r      sY  l\>~
@  T S S d h _ _ P ^ c V i \ X W P f f X	? 	 &%%&>? @


" &%%m4 5& &%%&JK L &%%&CD E &%%&PQ R &%%&KLC MC (''(NO6 P6@"J(;V,>, (''6 7* &%%j1N3CD+ E 2+ $##$LMS NS
 &%%&9: ;&1&B&J zF r   