@ -152,7 +152,7 @@ iam_role:
from ansible . module_utils . _text import to_native
from ansible . module_utils . _text import to_native
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . ec2 import camel_dict_to_snake_dict , ec2_argument_spec , get_aws_connection_info , boto3_conn , sort_json_policy_dict
from ansible . module_utils . ec2 import camel_dict_to_snake_dict , ec2_argument_spec , get_aws_connection_info , boto3_conn , sort_json_policy_dict
from ansible . module_utils . ec2 import HAS_BOTO3
from ansible . module_utils . ec2 import HAS_BOTO3 , AWSRetry
import json
import json
import traceback
import traceback
@ -239,6 +239,10 @@ def create_or_update_role(connection, module):
try :
try :
if not module . check_mode :
if not module . check_mode :
role = connection . create_role ( * * params )
role = connection . create_role ( * * params )
# 'Description' is documented as key of the role returned by create_role
# but appears to be an AWS bug (the value is not returned using the AWS CLI either).
# Get the role after creating it.
role = get_role_with_backoff ( connection , module , params [ ' RoleName ' ] )
else :
else :
role = { ' MadeInCheckMode ' : True }
role = { ' MadeInCheckMode ' : True }
role [ ' AssumeRolePolicyDocument ' ] = json . loads ( params [ ' AssumeRolePolicyDocument ' ] )
role [ ' AssumeRolePolicyDocument ' ] = json . loads ( params [ ' AssumeRolePolicyDocument ' ] )
@ -324,6 +328,17 @@ def create_or_update_role(connection, module):
if not module . check_mode :
if not module . check_mode :
connection . add_role_to_instance_profile ( InstanceProfileName = params [ ' RoleName ' ] , RoleName = params [ ' RoleName ' ] )
connection . add_role_to_instance_profile ( InstanceProfileName = params [ ' RoleName ' ] , RoleName = params [ ' RoleName ' ] )
# Check Description update
if not role . get ( ' MadeInCheckMode ' ) and params . get ( ' Description ' ) and role [ ' Description ' ] != params [ ' Description ' ] :
try :
if not module . check_mode :
connection . update_role_description ( RoleName = params [ ' RoleName ' ] , Description = params [ ' Description ' ] )
changed = True
except ( BotoCoreError , ClientError ) as e :
module . fail_json ( msg = " Unable to update description for role {0} : {1} " . format ( params [ ' RoleName ' ] , to_native ( e ) ) ,
exception = traceback . format_exc ( ) )
# Get the role again
# Get the role again
if not role . get ( ' MadeInCheckMode ' , False ) :
if not role . get ( ' MadeInCheckMode ' , False ) :
role = get_role ( connection , module , params [ ' RoleName ' ] )
role = get_role ( connection , module , params [ ' RoleName ' ] )
@ -389,6 +404,13 @@ def destroy_role(connection, module):
module . exit_json ( changed = True )
module . exit_json ( changed = True )
def get_role_with_backoff ( connection , module , name ) :
try :
return AWSRetry . jittered_backoff ( catch_extra_error_codes = [ ' NoSuchEntity ' ] ) ( connection . get_role ) ( RoleName = name ) [ ' Role ' ]
except ( BotoCoreError , ClientError ) as e :
module . fail_json ( msg = " Unable to get role {0} : {1} " . format ( name , to_native ( e ) ) , exception = traceback . format_exc ( ) )
def get_role ( connection , module , name ) :
def get_role ( connection , module , name ) :
try :
try :
return connection . get_role ( RoleName = name ) [ ' Role ' ]
return connection . get_role ( RoleName = name ) [ ' Role ' ]