Unlike an embarrassing Facebook post, developers can’t simply say “That wasn’t me, I got hacked” and expect it all to go away…
Sarcasm aside, security without passwords is not only convenient, it keeps the password from landing in the wrong hands.
Scenario
We (the vendor) like to ship our work to a client’s account with our Code Pipeline using a CodeBuild project. Rather than sharing access keys, we prefer to assume a cross-account role. This allows the client to control what permissions the role has access to, and we control who can access the role.
TL;DR; Scroll to the bottom if you simply want the assume-role.sh script!
The Process
We create a role on our vendor AWS account.
Client creates a role on their AWS account and allows the vendor role to assume their role.
The vendor role assumes the client role when we have to perform cross-account operations.
We are using a role here because the process executes from CodeBuild. This works with IAM users also.
This article is about cross-account roles, but you can use this script to assume any role you have access to.
Vendor Role
This CloudFormation snippet is usually part of a larger pipeline template. I scaled it down to just the role
AWSTemplateFormatVersion:"2010-09-09" Description:> Creates a role that will be used to assume client account role Parameters: ClientRoleArn: Type:String Default:'' Description:> Will be blank initially. Update with client's role arn after it has been created. Conditions: IsClientRoleArnSet:!Not [ !Equals [!RefClientRoleArn, '']] Resources: VendorRole: Type:AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version:2012-10-17 Statement: -Effect:Allow Principal: Service:codebuild.amazonaws.com Action:sts:AssumeRole Policies: -PolicyName:assume-client-role PolicyDocument: Version:'2012-10-17' Statement: # Add any additional permissions that you might need -Resource:"*" Effect:Allow Action: -logs:* # Will create this rule only once the ClientRoleArn is set -!If -IsClientRoleArnSet -Resource:!RefClientRoleArn Effect:Allow Action: -sts:AssumeRole -!RefAWS::NoValue Outputs: VendorRoleArn: Description:Passthistotheclient'sroletemplate. Value:!GetAtt [VendorRole, Arn]
./assume-role.sh $CLIENT_ROLE_ARN client aws s3 ls --profile client --region us-east-1
Tips
If you are using CodeBuild, assume-role.sh must be a separate file and not integrated into the buildspec.yml. This is because buildspec executes under SH rather than BASH so it does not support arrays.
Conclusion
This has been a huge help for me when deploying between AWS accounts - either our own or clients. I hope this helps you on your DevOps journey!