By using AWS re:Post, you agree to the AWS re:Post Terms of Use

When I update a secret in Secrets Manager, why doesn't the secret in AWS CloudFormation automatically update?

3 minute read
0

I updated my secret in AWS Secrets Manager, but the dynamic reference didn't update during my AWS CloudFormation stack update.

Short description

When you update a secret in Secrets Manager, CloudFormation doesn't automatically detect the value of the secret that you changed. When you change the dynamic reference during a stack update, CloudFormation retrieves only the value of the dynamic reference.

After you update the secret in Secrets Manager, you must update the CloudFormation stack, and specify the VersionId in the dynamic reference string. It's a best practice to specify the VersionId so that CloudFormation retrieves the updated version of the secret. You can also add a timestamp parameter to your CloudFormation template to force updates on resources.

Resolution

Update with VersionID

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshoot AWS CLI errors. Also, make sure that you're using the most recent AWS CLI version.

Complete the following steps:

  1. Dynamically reference the Secrets Manager secret in your CloudFormation template.
    In the following example, the CloudFormation template dynamically references a Secrets Manager secret with the mysecret secret-id and {"MyKey":"MyValue"} secret-string:

    Resources:
        SG:
            Type: AWS::EC2::SecurityGroup
            Properties:
                GroupDescription: '{{resolve:secretsmanager:mysecret:SecretString:MyKey}}'
                SecurityGroupIngress:
                      - IpProtocol: tcp
                        FromPort: 8080
                        ToPort: 8080
                        CidrIp: 0.0.0.0/0

    Note: The preceding dynamic reference resolves to MyValue for the GroupDescription property.

  2. To update the secret in Secrets Manager, run the update-secret AWS CLI command, and then specify the secret-string.
    In the example scenario, the secret-string is {"MyKey":"NewValue"}.
    Note: The VersionId doesn't appear on the AWS Management Console. If you used the Console to update your secret, then run the get-secret-value AWS CLI command to retrieve the VersionId.

  3. Note the VersionId from the output:

    $ aws secretsmanager update-secret --secret-id mysecret --secret-string {\"MyKey\":\"NewValue\"}{
        "ARN": "arn:aws:secretsmanager:us-east-1:############:secret:mysecret-ABCDeF",
        "Name": "mysecret",
        "VersionId": "ab01234c-5d67-89ef-01gh-2ijk345l6m78"
    }

    Note: The VersionId "ab01234c-5d67-89ef-01gh-2ijk345l6m78" from the preceding output doesn't automatically apply to the dynamic reference in the CloudFormation stack.

  4. Update the stack, and specify the VersionId in the dynamic reference string:

    Resources:
        SG:
            Type: AWS::EC2::SecurityGroup
            Properties:
                GroupDescription: '{{resolve:secretsmanager:mysecret:SecretString:MyKey::ab01234c-5d67-89ef-01gh-2ijk345l6m78}}'
                SecurityGroupIngress:
                      - IpProtocol: tcp
                        FromPort: 8080
                        ToPort: 8080
                        CidrIp: 0.0.0.0/0

    Note: In the preceding example template, the :: before "ab01234c-5d67-89ef-01gh-2ijk345l6m78" is the correct syntax. Keep this section of the dynamic reference string blank because you don't need to specify the version stage.

Use a timestamp to force updates

You can also add a timestamp parameter to your CloudFormation template to force updates on resources. Modify a property that allows nondisruptive updates, such as tags or environment variables.

For example, you can add a DeployTimestamp parameter to your CloudFormation template:

Parameters:
  DeployTimestamp:
    Type: String

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Environment:
        Variables:
          SECRET_KEY: !Sub '{{resolve:secretsmanager:${Secret}:SecretString:KEY}}'
          SECRET_KEY_UPDATED: !Ref DeployTimestamp

When you update the stack, specify the current date and time for DeployTimestamp to initiate the resource update. Use either the Console or AWS CLI to manually enter the details:

aws cloudformation deploy --parameter-overrides "DeployTimestamp=$(date)"

Note: This method works only with resources that support tags or have properties that allow for nondisruptive updates. If the resource type doesn't support either of these, then use the VersionId to update.

AWS OFFICIAL
AWS OFFICIALUpdated 4 months ago
2 Comments

I'm sorry, this isn't a resolution that works with CloudFormation. You want us to update the secret and then change the VersionId in EVERY template using the password EVERY TIME we update a password manually?

Templates should work dynamically with your services, give us an option to simply use the latest version of a secret stored in secret manager and make redeploying that same template grab the latest secret.

Edit: This is a better solution https://stackoverflow.com/a/60067235/357291

profile picture
replied 10 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
EXPERT
replied 10 months ago