2020-05-26 17:37:41 -07:00
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Purpose
Shows how to use AWS Identity and Access Management (IAM) roles.
"""
2021-10-07 15:59:25 -07:00
# snippet-start:[python.example_code.iam.role_wrapper.imports]
2020-05-26 17:37:41 -07:00
import json
import logging
import pprint
import boto3
from botocore . exceptions import ClientError
logger = logging . getLogger ( __name__ )
2023-10-18 10:35:05 -07:00
iam = boto3 . resource ( " iam " )
2021-10-07 15:59:25 -07:00
# snippet-end:[python.example_code.iam.role_wrapper.imports]
2020-05-26 17:37:41 -07:00
2021-10-07 15:59:25 -07:00
# snippet-start:[python.example_code.iam.CreateRole]
2020-05-26 17:37:41 -07:00
def create_role ( role_name , allowed_services ) :
"""
Creates a role that lets a list of specified services assume the role.
:param role_name: The name of the role.
:param allowed_services: The services that can assume the role.
:return: The newly created role.
"""
trust_policy = {
2023-10-18 10:35:05 -07:00
" Version " : " 2012-10-17 " ,
" Statement " : [
{
" Effect " : " Allow " ,
" Principal " : { " Service " : service } ,
" Action " : " sts:AssumeRole " ,
}
for service in allowed_services
] ,
2020-05-26 17:37:41 -07:00
}
try :
role = iam . create_role (
2023-10-18 10:35:05 -07:00
RoleName = role_name , AssumeRolePolicyDocument = json . dumps ( trust_policy )
)
2020-05-26 17:37:41 -07:00
logger . info ( " Created role %s . " , role . name )
except ClientError :
logger . exception ( " Couldn ' t create role %s . " , role_name )
raise
else :
return role
2023-10-18 10:35:05 -07:00
2021-10-07 15:59:25 -07:00
# snippet-end:[python.example_code.iam.CreateRole]
2020-05-26 17:37:41 -07:00
2022-01-27 16:41:51 -08:00
# snippet-start:[python.example_code.iam.GetRole]
def get_role ( role_name ) :
"""
Gets a role by name.
:param role_name: The name of the role to retrieve.
:return: The specified role.
"""
try :
role = iam . Role ( role_name )
role . load ( ) # calls GetRole to load attributes
logger . info ( " Got role with arn %s . " , role . arn )
except ClientError :
logger . exception ( " Couldn ' t get role named %s . " , role_name )
raise
else :
return role
2023-10-18 10:35:05 -07:00
2022-01-27 16:41:51 -08:00
# snippet-end:[python.example_code.iam.GetRole]
# snippet-start:[python.example_code.iam.ListRoles]
def list_roles ( count ) :
"""
Lists the specified number of roles for the account.
:param count: The number of roles to list.
"""
try :
roles = list ( iam . roles . limit ( count = count ) )
for role in roles :
logger . info ( " Role: %s " , role . name )
except ClientError :
logger . exception ( " Couldn ' t list roles for the account. " )
raise
else :
return roles
2023-10-18 10:35:05 -07:00
2022-01-27 16:41:51 -08:00
# snippet-end:[python.example_code.iam.ListRoles]
2021-10-07 15:59:25 -07:00
# snippet-start:[python.example_code.iam.DeleteRole]
2020-05-26 17:37:41 -07:00
def delete_role ( role_name ) :
"""
Deletes a role.
:param role_name: The name of the role to delete.
"""
try :
iam . Role ( role_name ) . delete ( )
logger . info ( " Deleted role %s . " , role_name )
except ClientError :
logger . exception ( " Couldn ' t delete role %s . " , role_name )
raise
2023-10-18 10:35:05 -07:00
2021-10-07 15:59:25 -07:00
# snippet-end:[python.example_code.iam.DeleteRole]
2020-05-26 17:37:41 -07:00
2021-10-07 15:59:25 -07:00
# snippet-start:[python.example_code.iam.AttachRolePolicy_Role]
2020-05-26 17:37:41 -07:00
def attach_policy ( role_name , policy_arn ) :
"""
Attaches a policy to a role.
:param role_name: The name of the role. **Note** this is the name, not the ARN.
:param policy_arn: The ARN of the policy.
"""
try :
iam . Role ( role_name ) . attach_policy ( PolicyArn = policy_arn )
logger . info ( " Attached policy %s to role %s . " , policy_arn , role_name )
except ClientError :
logger . exception ( " Couldn ' t attach policy %s to role %s . " , policy_arn , role_name )
raise
2023-10-18 10:35:05 -07:00
2021-10-07 15:59:25 -07:00
# snippet-end:[python.example_code.iam.AttachRolePolicy_Role]
2020-05-26 17:37:41 -07:00
2022-01-27 16:41:51 -08:00
# snippet-start:[python.example_code.iam.ListRolePolicies]
def list_policies ( role_name ) :
"""
Lists inline policies for a role.
:param role_name: The name of the role to query.
"""
try :
role = iam . Role ( role_name )
for policy in role . policies . all ( ) :
logger . info ( " Got inline policy %s . " , policy . name )
except ClientError :
logger . exception ( " Couldn ' t list inline policies for %s . " , role_name )
raise
2023-10-18 10:35:05 -07:00
2022-01-27 16:41:51 -08:00
# snippet-end:[python.example_code.iam.ListRolePolicies]
# snippet-start:[python.example_code.iam.ListAttachedRolePolicies]
def list_attached_policies ( role_name ) :
"""
Lists policies attached to a role.
:param role_name: The name of the role to query.
"""
try :
role = iam . Role ( role_name )
for policy in role . attached_policies . all ( ) :
logger . info ( " Got policy %s . " , policy . arn )
except ClientError :
logger . exception ( " Couldn ' t list attached policies for %s . " , role_name )
raise
2023-10-18 10:35:05 -07:00
2022-01-27 16:41:51 -08:00
# snippet-end:[python.example_code.iam.ListAttachedRolePolicies]
2021-10-07 15:59:25 -07:00
# snippet-start:[python.example_code.iam.DetachRolePolicy_Role]
2020-05-26 17:37:41 -07:00
def detach_policy ( role_name , policy_arn ) :
"""
Detaches a policy from a role.
:param role_name: The name of the role. **Note** this is the name, not the ARN.
:param policy_arn: The ARN of the policy.
"""
try :
iam . Role ( role_name ) . detach_policy ( PolicyArn = policy_arn )
logger . info ( " Detached policy %s from role %s . " , policy_arn , role_name )
except ClientError :
logger . exception (
2023-10-18 10:35:05 -07:00
" Couldn ' t detach policy %s from role %s . " , policy_arn , role_name
)
2020-05-26 17:37:41 -07:00
raise
2023-10-18 10:35:05 -07:00
2021-10-07 15:59:25 -07:00
# snippet-end:[python.example_code.iam.DetachRolePolicy_Role]
2020-05-26 17:37:41 -07:00
2021-10-07 15:59:25 -07:00
# snippet-start:[python.example_code.iam.Scenario_RoleManagement]
2020-05-26 17:37:41 -07:00
def usage_demo ( ) :
""" Shows how to use the role functions. """
2023-10-18 10:35:05 -07:00
logging . basicConfig ( level = logging . INFO , format = " %(levelname)s : %(message)s " )
print ( " - " * 88 )
2020-05-26 17:37:41 -07:00
print ( " Welcome to the AWS Identity and Account Management role demo. " )
2023-10-18 10:35:05 -07:00
print ( " - " * 88 )
print (
" Roles let you define sets of permissions and can be assumed by "
" other entities, like users and services. "
)
2022-01-27 16:41:51 -08:00
print ( " The first 10 roles currently in your account are: " )
roles = list_roles ( 10 )
print ( f " The inline policies for role { roles [ 0 ] . name } are: " )
list_policies ( roles [ 0 ] . name )
2020-05-26 17:37:41 -07:00
role = create_role (
2023-10-18 10:35:05 -07:00
" demo-iam-role " , [ " lambda.amazonaws.com " , " batchoperations.s3.amazonaws.com " ]
)
2020-05-26 17:37:41 -07:00
print ( f " Created role { role . name } , with trust policy: " )
pprint . pprint ( role . assume_role_policy_document )
2023-10-18 10:35:05 -07:00
policy_arn = " arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess "
2020-05-26 17:37:41 -07:00
attach_policy ( role . name , policy_arn )
print ( f " Attached policy { policy_arn } to { role . name } . " )
2022-01-27 16:41:51 -08:00
print ( f " Policies attached to role { role . name } are: " )
list_attached_policies ( role . name )
2020-05-26 17:37:41 -07:00
detach_policy ( role . name , policy_arn )
print ( f " Detached policy { policy_arn } from { role . name } . " )
delete_role ( role . name )
print ( f " Deleted { role . name } . " )
print ( " Thanks for watching! " )
2023-10-18 10:35:05 -07:00
2021-10-07 15:59:25 -07:00
# snippet-end:[python.example_code.iam.Scenario_RoleManagement]
2020-05-26 17:37:41 -07:00
2023-10-18 10:35:05 -07:00
if __name__ == " __main__ " :
2020-05-26 17:37:41 -07:00
usage_demo ( )