I want to perform cross account access to AWS secrets manager to populate the ElasticBeanstalk environment variable so that application can use it from another account.
Short Description
Elastic Beanstalk can fetch values from AWS Secrets Manager during instance bootstrapping and assign them to environment variables for your application to use. You can also use cross account access to allow ElasticBeanstalk instances in one account to access secrets in another account.
Resolution
Suppose you have a secret and KMS encryption key in Account1 and ElasticBeanstalk environment in Account2
Account1
- Create the secret and Resource based policy to allow instance role of ElasticBeanstalk in Account2 to access the secret in Account1 (place the ARN of the instance role in the Principal)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account2ID>:role/elasticbeanstalk-ec2-role"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}
]
}
- You must encrypt your secret with a customer managed KMS key that you create, and then attach a key policy to it that allows instance role of ElasticBeanstalk in Account2 to use the KMS key in Account1 to decrypt the secret in Account1.
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account2ID>:role/elasticbeanstalk-ec2-role"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "*"
}
Account2
- Update the instance profile of the ElasticBeanstalk environment with following permissions grant access to fetch encrypted secrets from the AWS Secrets Manager store from Account1:
{
"Version" : "2012-10-17",
"Statement" : [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:Region:<Account1ID>:secret:mysecret"
},
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:Region:<Account1ID>:key/EncryptionKey"
}
]
}
Different ways to configure the secret as the environment variable:
* Using Console:
- Open AWS ElasticBeanstalk Console and choose the correct Region
- Choose Environments and and then choose the environment name
- Choose Configuration and edit Updates, monitoring, and logging
- Scroll down to Runtime environment variables and Add environment variable
- For Source select Secrets Manager
- For Environment variable name enter the name of the environment variable and for Environment variable value enter the ARN Secrets Manager secret
* Using .ebextensions namespace aws:elasticbeanstalk:application:environmentsecrets:
option_settings:
aws:elasticbeanstalk:application:environmentsecrets:
MY_SECRET: arn:aws:secretsmanager:Region:<Account1ID>:secret:mysecret
* AWS CLI : create-environment or update-environment API call. e.g- update-environment API call as below or use an options.json file to specify the namespace options
aws elasticbeanstalk update-environment \
--region us-east-1 \
--application-name my-app \
--environment-name my-env \
--solution-stack-name "64bit Amazon Linux 2023 v6.5.0 running Node.js 20" \
--option-settings \
Namespace=aws:elasticbeanstalk:application:environmentsecrets,OptionName=MY_SECRET,Value= arn:aws:secretsmanager:Region:<Account1ID>:secret:mysecret
References:
- https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_examples_cross.html
- https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.secrets.IAM-permissions.html
- https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.secrets.env-vars.html