Get started with Dynamic References in AWS CloudFormation

Dynamic references provide a compact, powerful way for you to specify external values that are stored and managed in other services, such as the Systems Manager Parameter Store and AWS Secrets Manager, in your stack templates. When you use a dynamic reference, CloudFormation retrieves the value of the specified reference when necessary during stack and change set operations.

CloudFormation currently supports the following dynamic reference patterns:

  • ssm, for plaintext values stored in AWS Systems Manager Parameter Store.

  • ssm-secure, for secure strings stored in AWS Systems Manager Parameter Store.

  • secretsmanager, for entire secrets or secret values stored in AWS Secrets Manager.

Considerations when using dynamic references

Below are considerations you should take into account when using dynamic references:

It is recommended against including dynamic references, or any sensitive data, in resource properties that are part of a resource's primary identifier.

When a dynamic reference parameter is included in a property that forms a primary resource identifier, CloudFormation may use the actual plaintext value in the primary resource identifier. This resource ID may appear in any derived outputs or destinations.

To determine which resource properties comprise a resource type's primary identifier, refer to the resource reference documentation for that resource. In the Return values section, the Ref function return value represents the resource properties that comprise the resource type's primary identifier.

  • You can include up to 60 dynamic references in a stack template.

  • Dynamic references for secure values, such as ssm-secure and secretsmanager, aren't currently supported in custom resources.

Do not create a dynamic reference that has a backslash (\) as the final value. AWS CloudFormation cannot resolve those references, which results in a resource failure.

Specifying dynamic references in stack templates

Dynamic references adhere to the following pattern:

'{{resolve:service-name:reference-key}}' or

'{{resolve:ssm:[a-zA-Z0-9_.\-/]+(:\d+)?}}'

service-name

Specifies the service in which the value is stored and managed.

Required.

Currently, valid values include:

  • ssm: Systems Manager Parameter Store plaintext parameter.

  • ssm-secure: Systems Manager Parameter Store secure string parameter.

    For more information, see AWS Systems Manager Parameter Store in the AWS Systems Manager User Guide.

  • secretsmanager: Secrets Manager secret.

reference-key

The reference key. Depending on the type of dynamic reference, the reference key may be comprised of multiple segments.

Required.

SSM parameters

Use the ssm dynamic reference to include values stored in the Systems Manager Parameter Store of type String or StringList in your templates.

Reference pattern

For SSM Parameters, the reference-key segment is composed of the parameter name and version number. Use the following pattern:

'{{resolve:ssm:parameter-name:version}}'

Your reference must adhere to the following regular expression pattern for parameter-name and version:

'{{resolve:ssm:[a-zA-Z0-9_.-/]+:\\d+}}'

parameter-name

The name of the parameter in the Systems Manager Parameter Store. The parameter name is case-sensitive.

Required.

version

An integer that specifies the version of the parameter to use. If you don't specify the exact version, CloudFormation uses the latest version of the parameter whenever you create or update the stack. For more information, see Working with parameter versions in the AWS Systems Manager User Guide

Optional.

Hands-On Lab: SSM Dynamic Parameter

The following example uses an ssm dynamic reference to set the access control for an S3 bucket to a parameter value stored in Systems Manager Parameter Store. As specified, CloudFormation will use version 1 of the S3AccessControl parameter for stack and change set operations.

Resources:
  MyS3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      AccessControl: '{{resolve:ssm:S3AccessControl:1}}'

To specify a parameter stored in the Systems Manager Parameter Store, you must have access to call GetParameters for the specified parameter. For more information, see Controlling access to Systems Manager parameters in the AWS Systems Manager User Guide.

  1. First, you need to create S3AccessControl SSM parameter. To create this parameter use the following command:

     aws ssm put-parameter --name "S3AccessControl" --value "Private" --type "String"
    

  2. Then, deploy the CloudFormation stack with the following command:

     aws cloudformation create-stack --stack-name CFNDynamicReferenceDemo --template-body file://s3-access-control.yaml
    

    This will create S3 bucket with ACL set to private by using dynamic reference in the template body:

    SSM secure string parameters

    Use the ssm-secure dynamic reference pattern to specify AWS Systems Manager SecureString type parameters in your templates. For ssm-secure dynamic references, AWS CloudFormation never stores the actual parameter value. AWS CloudFormation accesses the parameter value during create and update operations for stacks and change sets. Currently, secure string parameters can only be used for resource properties that support the ssm-secure dynamic reference pattern.

    A secure string parameter is any sensitive data that needs to be stored and referenced in a secure manner. That is, data that you don't want users to alter or reference in clear text, such as passwords or license keys. For more information on secure strings, see Use secure string parameters in the AWS Systems Manager User Guide.

    Secure string parameters values aren't stored in CloudFormation, nor are they returned in any API call results.

    Reference pattern

    For ssm-secure dynamic references, the reference-key segment is composed of the parameter name and version number. Use the following pattern:

    '{{resolve:ssm-secure:parameter-name:version}}'

    Your reference must adhere to the following regular expression pattern for parameter-name and version:

    '{{resolve:ssm-secure:[a-zA-Z0-9_.-/]+:\\d+}}'

Hands-On Lab: SSM secure string parameters dynamic reference

The following example uses an ssm-secure dynamic reference to set the password for an IAM user to a secure string stored in Systems Manager Parameter Store. As specified, CloudFormation will use version 1 of the IAMUserPassword parameter for stack and change set operations.

Resources:
  MyIAMUser:
    Type: AWS::IAM::User
    Properties:
      UserName: 'MyUserName'
      LoginProfile:
        Password: '{{resolve:ssm-secure:IAMUserPassword:1}}'
  1. First, you need to create SSM Secure parameter that stores the password for the user. To create a parameter use the following command:

     aws ssm put-parameter --name <parameter_name> --value "<parameter_value>" --type SecureString
    
     aws ssm put-parameter --name IAMUserPassword --value "P@ssw0rd!" --type SecureString
    

  2. Then run the following command to create a CloudFormation stack that uses dynamic reference for SSM secure string:

     aws cloudformation create-stack --stack-name SSMSecureStringDemo --template-body file://iam-user-password-change.yaml --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM
    
  3. After successful creation of the stack, you will find the newly created user "MyUserName":

Secrets Manager secrets

Use the secretsmanager dynamic reference to retrieve entire secrets or secret values that are stored in Secrets Manager for use in your templates. Secrets can be database credentials, passwords, third-party API keys, or arbitrary text. Using Secrets Manager, you can store and control access to these secrets centrally, so that you can replace hardcoded credentials in your code (including passwords), with an API call to Secrets Manager to retrieve the secret programmatically. For more information, see What is AWS Secrets Manager? in the AWS Secrets Manager User Guide.

Important considerations when using dynamic references for Secrets Manager secrets

You should take the following important security considerations into account when using dynamic references to specify Secrets Manager secrets in your stack templates:

  • The secretsmanager dynamic reference can be used in all resource properties. Using the secretsmanager dynamic reference indicates that neither Secrets Manager nor CloudFormation logs should persist any resolved secret value. However, the secret value may show up in the service whose resource it's being used in. Review your usage to avoid leaking secret data.

  • Updating a secret in Secrets Manager doesn't automatically update the secret in CloudFormation. In order for CloudFormation to update a secretsmanager dynamic reference, you must perform a stack update that updates the resource containing the dynamic reference, either by updating the resource property that contains the secretsmanager dynamic reference, or updating another of the resource's properties.

    For example, suppose in your template you specify the MasterPassword property of an AWS::RDS::DBInstance resource to be a secretsmanager dynamic reference, and then create a stack from the template. You later update that secret's value in Secrets Manager, but don't update the AWS::RDS::DBInstance resource in your template. In this case, even if you perform a stack update, the secret value in the MasterPassword property isn't updated, and remains the previous secret value.

    Also, consider using Secrets Manager to automatically rotate the secret for a secured service or database. For more information, see Rotate AWS Secrets Manager secrets.

  • Dynamic references for secure values, such as secretsmanager, aren't currently supported in custom resources.

Permissions required

To specify a secret stored in Secrets Manager, you must have access to call GetSecretValue for the secret.

Reference pattern

For Secrets Manager secrets, the reference-key segment is composed of several segments, including the secret id, secret value key, version stage, and version id. Use the following pattern:

{{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}

secret-id

The name or ARN of the secret.

To access a secret in your AWS account, you need only specify the secret name. To access a secret in a different AWS account, specify the complete ARN of the secret.

Required.

secret-string

Currently, the only supported value is SecretString. The default is SecretString.

json-key

The key name of the key-value pair whose value you want to retrieve. If you don't specify a json-key, CloudFormation retrieves the entire secret text.

This segment may not include the colon character ( :).

version-stage

The staging label of the version of the secret to use. Secrets Manager uses staging labels to keep track of different versions during the rotation process. If you use version-stage then don't specify version-id. If you don't specify either version-stage or version-id, then the default is the AWSCURRENT version.

This segment may not include the colon character ( :).

version-id

The unique identifier of the version of the secret to use. If you specify version-id, then don't specify version-stage. If you don't specify either version-stage or version-id, then the default is the AWSCURRENT version.

This segment may not include the colon character ( :).

Hands-On Lab: Secrets Manager secrets dynamic reference

The following example uses the secret-name and json-key segments to retrieve the user name and password values stored in the MyRDSSecret secret. By default, the secret version retrieved is the version with the version stage value of AWSCURRENT.

Resources:
  MyRDSInstance:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      DBName: MyRDSInstance
      AllocatedStorage: '20'
      DBInstanceClass: db.t2.micro
      Engine: mysql
      MasterUsername: '{{resolve:secretsmanager:MyRDSSecret:SecretString:username}}'
      MasterUserPassword: '{{resolve:secretsmanager:MyRDSSecret:SecretString:password}}'
  1. First, you need to create a secret in Secrets Manager. To create username and password secrets use the following command:

     aws secretsmanager create-secret --name MyRDSSecret --secret-string '{"username": "admin", "password": "Passw0rd"}'
    

  2. Next, deploy your CloudFormation stack with the following command:

     aws cloudformation create-stack --stack-name CFNSecretsManagerDemo --template-body file://rds-instance-credentials-setup.yaml --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM
    

    This will create a MySQL RDS instance with a username and password set from Secrets Manager:

References:

  1. Using dynamic references to specify template values