amazon-web-servicesaws-cloudformationamazon-ecsaws-secrets-manager

How to specify a secret from SecretManager in CloudFormation container definition


Hey guys I have the following CF configuration and want to resolve a secret from SecretManager.

  DefinitionBackend:
    Type: AWS::ECS::TaskDefinition
    DependsOn: TaskPolicy
    Properties:
      ExecutionRoleArn: !GetAtt TaskRole.Arn
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      Cpu: 1024
      Memory: 5120
      ContainerDefinitions:
        - Name: admin
          Essential: true
          Image: !Sub XXXXXXXXXX.dkr.ecr.${AWS::REGION}.amazonaws.com/some-image:${AWS::StackName}-${ImageTag}
          PortMappings:
            - ContainerPort: 8003
          Command:
            - ....
          Secrets:
            - Name: DATABASE_URL
              ValueFrom: '{{resolve:secretsmanager:Dev:SecretString:DATABASE_URL}}'

The secret is called Dev and there are a few KEY:VALUE pairs in it, such as DATABASE_URL which is a database connection string. I want to use the abovementioned configuration to resolve the secret from SecretManager but I am getting an error:

Resource handler returned message: "Invalid request provided: Create TaskDefinition: The Systems Manager parameter name specified for secret DATABASE_URL is invalid. The parameter name can be up to 2048 characters and include the following letters and symbols: a-zA-Z0-9_.-,

The database string is in the following format and worked perfectly before in the environment variables:

"DATABASE_URL":"postgresql://web:PASSWORD@dev.234098234uuoi.eu-central-1.rds.amazonaws.com:5432/database"

Do you have any ideas - am I retrieving it wrong or do I just need to convert it to a different format like Base64 to be able to use it with the secrets?


Solution

  • You are trying to resolve the value of the secret, and pass that value directly into the task definition. That's not how ECS container secrets work. It's asking you where to get the value from not what the actual value is. You need to pass the ARN of the secret, not the value of the secret.

    I believe you need to change your template to:

    ValueFrom: !GetAtt Dev.Arn 
    

    When the container starts up, the ECS service will look up the value of the secret in Secrets Manager, and add it as an environment variable at that time.