The recommended way of managing credentials used to sign API requests to other AWS services is using IAM roles. When an IAM role is attached to an instance, it retrieves a temporary credentials from the instance metadata. These credentials are valid for a limited period of time, however SDK manages them transparently. So, instead of creating and distributing your AWS credentials to instance, you can delegate permissions using IAM role.
When creating the IAM role, in addition to access policies, you have to attach a trust policy (e.g what service can assume this role) as well.
Assume role policy
An assume role policy (also called as a trust policy) is a policy that grants an access to AWS service to use (assume) that particular role. So, if you are using EC2 instance, a trust policy could look like:
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
Access policy
The access policy on another hand, grants an access to IAM role to specific AWS resources. So, for example the policy for full access to S3 service would look like
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": ["*"]
}
]
}
Once you have a role created and attached to particular instance, you can use SDK without supplying any credential or region to it and use it in your code like
s3 = boto3.resource('s3')
bucket = s3.Bucket(os.environ.get('S3_BUCKET'))