Configure Multiple AWS Profiles
When we configured our AWS CLI in the Configure the AWS CLI chapter, we used the aws configure
command to set the IAM credentials of the AWS account we wanted to use to deploy our serverless application to.
These credentials are stored in ~/.aws/credentials
and are used by the Serverless Framework when we run serverless deploy
. Behind the scenes Serverless uses these credentials and the AWS SDK to create the necessary resources on your behalf to the AWS account specified in the credentials.
There are cases where you might have multiple credentials configured in your AWS CLI. This usually happens if you are working on multiple projects or if you want to separate the different stages of the same project.
In this chapter let’s take a look at how you can work with multiple AWS credentials.
Create a New AWS Profile
Let’s say you want to create a new AWS profile to work with. Follow the steps outlined in the Create an IAM User chapter to create an IAM user in another AWS account and take a note of the Access key ID and Secret access key.
To configure the new profile in your AWS CLI use:
$ aws configure --profile newAccount
Where newAccount
is the name of the new profile you are creating. You can leave the Default region name and Default output format the way they are.
Set a Profile on Local
We mentioned how the Serverless Framework uses your AWS profile to deploy your resources on your behalf. But while developing on your local using the serverless invoke local
command things are a little different.
In this case your Lambda function is run locally and has not been deployed yet. So any calls made in your Lambda function to any other AWS resources on your account will use the default AWS profile that you have. You can check your default AWS profile in ~/.aws/credentials
under the [default]
tag.
To switch the default AWS profile to a new profile for the serverless invoke local
command, you can run the following:
$ AWS_PROFILE=newAccount serverless invoke local --function hello
Here newAccount
is the name of the profile you want to switch to and hello
is the name of the function that is being invoked locally. By adding AWS_PROFILE=newAccount
at the beginning of our serverless invoke local
command we are setting the variable that the AWS SDK will use to figure out what your default AWS profile is.
If you want to set this so that you don’t add it to each of your commands, you can use the following command:
$ export AWS_PROFILE=newAccount
Where newAccount
is the profile you want to switch to. Now for the rest of your shell session, newAccount
will be your default profile.
You can read more about this in the AWS Docs here.
Set a Profile While Deploying
Now if we want to deploy using this newly created profile we can use the --aws-profile
option for the serverless deploy
command.
$ serverless deploy --aws-profile newAccount
Again, newAccount
is the AWS profile Serverless Framework will be using to deploy.
If you don’t want to set the profile every time you run serverless deploy
, you can add it to your serverless.yml
.
service: service-name
provider:
name: aws
stage: dev
profile: newAccount
Note the profile: newAccount
line here. This is telling Serverless Framework to use the newAccount
profile while running serverless deploy
.
Set Profiles per Stage
There are cases where you would like to specify a different AWS profile per stage. A common scenario for this is when you have a completely separate staging environment than your production one. Each environment has its own API endpoint, database tables, and more importantly, the IAM policies to secure the environment. A simple yet effective way to achieve this is to keep the environments in separate AWS accounts. AWS Organizations was in fact introduced to help teams to create and manage these accounts and consolidate the usage charges into a single bill.
Let’s look at a quick example of how to work with multiple profiles per stage. So following the examples from before, if you wanted to deploy to your production environment, you would:
$ serverless deploy --stage prod --aws-profile prodAccount
And to deploy to the staging environment you would:
$ serverless deploy --stage dev --aws-profile devAccount
Here, prodAccount
and devAccount
are the AWS profiles for the production and staging environment respectively.
To simplify this process you can add the profiles to your serverless.yml
. So you don’t have to specify them in your serverless deploy
commands.
service: service-name
custom:
myStage: ${opt:stage, self:provider.stage}
myProfile:
prod: prodAccount
dev: devAccount
provider:
name: aws
stage: dev
profile: ${self:custom.myProfile.${self:custom.myStage}}
There are a couple of things happening here.
- We first defined
custom.myStage
as${opt:stage, self:provider.stage}
. This is telling Serverless Framework to use the value from the--stage
CLI option if it exists. If not, use the default stage specified inprovider.stage
. - We also defined
custom.myProfile
, which contains the AWS profiles we want to use to deploy for each stage. Just as before we want to use theprodAccount
profile if we are deploying to stageprod
and thedevAccount
profile if we are deploying to stagedev
. - Finally, we set the
provider.profile
to${self:custom.myProfile.${self:custom.myStage}}
. This picks the value of our profile depending on the current stage defined incustom.myStage
.
We used the concept of variables in Serverless Framework in this example. You can read more about this in the chapter on Serverless Environment Variables.
Now, when you deploy to production, Serverless Framework is going to use the prodAccount
profile. And the resources will be provisioned inside prodAccount
profile user’s AWS account.
$ serverless deploy --stage prod
And when you deploy to staging, the exact same set of AWS resources will be provisioned inside devAccount
profile user’s AWS account.
$ serverless deploy --stage dev
Notice that we did not have to set the --aws-profile
option. And that’s it, this should give you a good understanding of how to work with multiple AWS profiles and credentials.
For help and discussion
Comments on this chapter