After some hours of try and error, i've came to the following Solution:
DatabaseSecret:
Type: "AWS::SecretsManager::Secret"
Properties:
Name: !Sub "application-${Stage}-databasesecret"
Description: AWS RDS admin credentials
GenerateSecretString:
SecretStringTemplate: '{"POSTGRES_USER": "username"}'
GenerateStringKey: POSTGRES_PASSWORD
PasswordLength: 32
ExcludeCharacters: '"@/\_[]'
This will generate a Secret having 2 values: POSTGRES_PASSWORD
and POSTGRES_USER
Database:
Type: AWS::RDS::DBInstance
Properties:
Engine: postgres
VPCSecurityGroups:
- !Ref DatabaseSecurityGroup
DBInstanceClass: db.t3.micro
AllocatedStorage: "5"
MasterUsername: !Sub "{{resolve:secretsmanager:${DatabaseSecret}::POSTGRES_USER}}"
MasterUserPassword: !Sub "{{resolve:secretsmanager:${DatabaseSecret}::POSTGRES_PASSWORD}}"
This will apply the values to the RDS instance.
I was unable to address the Properties directly. But i was able to retrieve the whole Secret as JSON (having only the 2 secret strings)
ApiTaskDefinition:
Type: AWS::ECS::TaskDefinition
UpdateReplacePolicy: Retain
Properties:
...
ContainerDefinitions:
- Name: "some-name"
Image: !Ref ImageName
Memory: 512
...
Environment:
- Name: POSTGRES_HOST
Value: !GetAtt Database.Endpoint.Address
- Name: POSTGRES_PORT
Value: !GetAtt Database.Endpoint.Port
- Name: POSTGRES_DB
Value: "postgres"
Secrets:
- Name: POSTGRES_CREDENTIALS
ValueFrom: !Ref DatabaseSecret
This will set an environment variable to the ECS like e.g.
[{"POSTGRES_USER": "username", "POSTGRES_PASSWORD": "password"}]
You can then access these values by parsing the environment variable as JSON
Typescript example:
const dbCredentialsConfig = this.configService.get('POSTGRES_CREDENTIALS');
const dbCredentials = JSON.parse(dbCredentialsConfig)[0];
return {
type: 'postgres',
host: this.configService.get('POSTGRES_HOST'),
port: this.configService.get('POSTGRES_PORT'),
username: dbCredentials.POSTGRES_USER,
password: dbCredentials.POSTGRES_PASSWORD,
database: this.configService.get('POSTGRES_DB'),
...
};