It’s a best practice to split your environments into separate AWS accounts. It does not cost you anything extra and you can guarantee that your development environment is completely isolated from the higher environments. With this setup, it’s also common to have a build or tooling account to be responsible for the deployment of your application.
But it does bring some other challenges, for example: When you have a web application it usually has a frontend and an API that it uses. If you use separate pipelines to deploy these components you need a way to share the endpoint. You could use a predictable schema to determine the endpoint programmatically when you build the web application. This works well for a URL, but this does not work for a Cognito Client ID.
Use SSM Parameters
SSM Parameters are a key/value store, they are perfect for configuration values. When you deploy your API, Cognito user pool and client. You can store the value in an SSM parameter like this:
UserPoolClientIdParameter:
Type: AWS::SSM::Parameter
Properties:
Name: /<Environment>/cognito/user-pool-client-id
Tier: Advanced
Type: String
Value: !Ref AppClient
Next, you can share this parameter with the build/tooling account:
ShareUserPoolClientIdParameter:
Type: AWS::RAM::ResourceShare
Properties:
AllowExternalPrincipals: true
Name: UserPool Client ID - <Environment>
PermissionArns:
- arn:aws:ram::aws:permission/AWSRAMDefaultPermissionSSMParameterReadOnly
Principals:
# This is the account id of your build/tooling account
- 111122223333
ResourceArns:
- !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${UserPoolClientIdParameter}
Resolve the values in CodeBuild
Now that we have shared the configuration with the build/tooling account. We need to resolve the value. First, make sure that the principle is allowed to resolve the parameter:
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:GetParameters"
],
"Resource": [
"arn:aws:ssm:eu-west-1:444455556666:parameter/<Environment>/cognito/user-pool-client-id"
]
}
Next, we need to add the parameter to the buildspec:
version: 0.2
env:
parameter-store:
USER_POOL_CLIENT_ID: arn:aws:ssm:eu-west-1:444455556666:parameter/<Environment>/cognito/user-pool-client-id
phases:
...
Now in theory this should work… However, this parameter will not resolve. I assume that CodeBuild can only resolve parameters stored in the same account. But you can simply work around this issue by fetching the parameter yourself:
export USER_POOL_CLIENT_ID=$(aws ssm get-parameter --name arn:aws:ssm:eu-west-1:444455556666:parameter/<Environment>/cognito/user-pool-client-id --output text --query 'Parameter.Value')
I preferred the native solution but unfortunately, this is not working. Until it is this would be my recommended solution.
Conclusion
Following best practices is always a good idea. But they can introduce new challenges. In the example given, I have shown you how to use an SSM parameter to share configuration across accounts.
Photo by Mostafa Meraji
The post Share your configuration across AWS accounts appeared first on Xebia.
Top comments (0)