AWS CloudFormation
User Guide (Version )

The AWS Documentation website is getting a new look!
Try it now and let us know what you think. Switch to the new look >>

You can return to the original look by selecting English in the language selector above.


The AWS::SecretsManager::RotationSchedule resource configures rotation for a secret. The secret must already be configured with the details of the database or service. If you define both the secret and the database or service in an AWS CloudFormation template, then define the AWS::SecretsManager::SecretTargetAttachment resource to populate the secret with the connection details of the database or service before you attempt to configure rotation.


When you configure rotation for a secret, AWS CloudFormation automatically rotates the secret one time. Ensure that you configure all your clients to retrieve the secret using Secrets Manager before configuring rotation to prevent breaking them.


To declare this entity in your AWS CloudFormation template, use the following syntax:


{ "Type" : "AWS::SecretsManager::RotationSchedule", "Properties" : { "RotationLambdaARN" : String, "RotationRules" : RotationRules, "SecretId" : String } }


Type: AWS::SecretsManager::RotationSchedule Properties: RotationLambdaARN: String RotationRules: RotationRules SecretId: String



Specifies the ARN of the Lambda function that can rotate the secret. If you don't specify this parameter, then the secret must already have the ARN of a Lambda function configured. To reference a Lambda function that's also created in this template, use the Ref function with the function's logical ID.

Required: No

Type: String

Update requires: No interruption


Specifies a structure that defines the rotation schedule for this secret.

Required: No

Type: RotationRules

Update requires: No interruption


Specifies the Amazon Resource Name (ARN) or the friendly name of the secret that you want to rotate. To reference a secret also that's created in this template, use the Ref function with the secret's logical ID.

Required: Yes

Type: String

Update requires: Replacement

Return Values


When you pass the logical ID of an AWS::SecretsManager::RotationSchedule resource to the intrinsic Ref function, the function returns the ARN of the secret that's being configured, such as:

arn:aws:secretsmanager: us-west-2:123456789012:secret:my-path/my-secret-name-1a2b3c

This enables you to reference a secret that you create in one part of the stack template from within the definition of another resource later, in the same template. You typically do this when you define the AWS::SecretsManager::SecretTargetAttachment resource type.

For more information about using the Ref function, see Ref.


Configuring a Secret to Rotate

The following example shows a complete example of creating a secret, creating an RDS database instance that's associated with the secret and configuring it to rotate. The example shows how to define a Lambda rotation function, attach the required trust and permissions policies, and associate the function with the secret on a defined schedule.


{ "MyRDSInstanceRotationSecret": { "Type": "AWS::SecretsManager::Secret", "Properties": { "Description": "This is my rds instance secret", "GenerateSecretString": { "SecretStringTemplate": "{\"username\": \"admin\"}", "GenerateStringKey": "password", "PasswordLength": 16, "ExcludeCharacters": "\"@/\\" } } }, "SecretRDSInstanceAttachment": { "Type": "AWS::SecretsManager::SecretTargetAttachment", "Properties": { "SecretId": {"Ref": "MyRDSInstanceRotationSecret"}, "TargetId": {"Ref": "MyDBInstance"}, "TargetType": "AWS::RDS::DBInstance" } }, "MyDBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "AllocatedStorage": "’20’", "DBInstanceClass": "db.t2.micro", "Engine": "mysql", "MasterUsername": {"Fn::Join": [ "", ["{{resolve:secretsmanager:",{"Ref": "MyRDSInstanceRotationSecret"},"::username}}"] ]}, "MasterUserPassword": {"Fn::Join": [ "", ["{{resolve:secretsmanager:",{"Ref": "MyRDSInstanceRotationSecret"},"::password}}"] ]}, "BackupRetentionPeriod": 0, "DBInstanceIdentifier": "rotation-instance" } }, "MySecretRotationSchedule": { "Type": "“AWS::SecretsManager::RotationSchedule\"", "DependsOn": "SecretRDSInstanceAttachment", "Properties": { "SecretId": {"Ref": "MyRDSInstanceRotationSecret"}, "RotationLambdaARN": {"Fn::GetAtt": ["MyRotationLambda", "Arn"]}, "RotationRules": { "AutomaticallyAfterDays": 5 } } }, "LambdaInvokePermission": { "Type": "AWS::Lambda::Permission", "DependsOn": "MyRotationLambda", "Properties": { "FunctionName": "cfn-rotation-lambda", "Action": "lambda:InvokeFunction", "Principal": "" } }, "MyLambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": "cfn-rotation-lambda-role", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Policies": [ { "PolicyName": "AWSSecretsManagerRotationPolicy", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:DescribeSecret", "secretsmanager:GetSecretValue", "secretsmanager:PutSecretValue", "secretsmanager:UpdateSecretVersionStage" ], "Resource": {"Fn::Sub": "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*"}, "Condition": { "StringEquals": { "secretsmanager:resource/AllowRotationLambdaArn": { "Fn::Sub": "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:cfn-rotation-lambda" } } } }, { "Effect": "Allow", "Action": [ "secretsmanager:GetRandomPassword" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:DescribeKey", "kms:GenerateDataKey" ], "Resource": "*" } ] } } ] } }, "MyRotationLambda": { "Type": "AWS::Lambda::Function", "Properties": { "Runtime": "python2.7", "Role": {"Fn::GetAtt": ["MyLambdaExecutionRole","Arn"]}, "Handler": "lambda_function.lambda_handler", "Description": "This is a lambda to rotate MySql user passwd", "FunctionName": "cfn-rotation-lambda", "Environment": { "Variables": { "SECRETS_MANAGER_ENDPOINT": {"Fn::Sub": "https://secretsmanager.${AWS::Region}"} } }, "Code": { "S3Bucket": "<% replace-this-with-name-of-s3-bucket-that-contains-lambda-function-code %>", "S3Key": "<% replace-this-with-path-and-filename-of-zip-file-that-contains-lambda-function-code %>", "S3ObjectVersion": "<% replace-this-with-lambda-zip-file-version-if-s3-bucket-versioning-is-enabled %>" } } } }


#This is a Secret resource with a randomly generated password in its SecretString JSON. MyRDSInstanceRotationSecret: Type: AWS::SecretsManager::Secret Properties: Description: "This is my rds instance secret" GenerateSecretString: SecretStringTemplate: '{"username": "admin"}' GenerateStringKey: "password" PasswordLength: 16 ExcludeCharacters: '"@/\' # This is an RDS instance resource. The master username and password use dynamic references # to resolve values from Secrets Manager. The dynamic reference guarantees that CloudFormation # will not log or persist the resolved value. We use a Ref to the secret resource's logical id # to construct the dynamic reference, since the secret name is generated by CloudFormation. MyDBInstance: Type: AWS::RDS::DBInstance Properties: AllocatedStorage: 20 DBInstanceClass: db.t2.micro Engine: mysql MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref MyRDSInstanceRotationSecret, '::username}}' ]] MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref MyRDSInstanceRotationSecret, '::password}}' ]] BackupRetentionPeriod: 0 DBInstanceIdentifier: 'rotation-instance' #This is a SecretTargetAttachment resource which updates the referenced Secret resource with properties about #the referenced RDS instance SecretRDSInstanceAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: !Ref MyRDSInstanceRotationSecret TargetId: !Ref MyDBInstance TargetType: AWS::RDS::DBInstance # This is a RotationSchedule resource. It configures rotation of the password for the referenced # secret using a Lambda rotation function. The first rotation happens immediately when # CloudFormation processes this resource type. All subsequent rotations are scheduled according to # the configured rotation rules. We explicitly depend on the SecretTargetAttachment resource to # ensure that the secret contains all the information necessary for rotation to succeed. MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretRDSInstanceAttachment Properties: SecretId: !Ref MyRDSInstanceRotationSecret RotationLambdaARN: !GetAtt MyRotationLambda.Arn RotationRules: AutomaticallyAfterDays: 5 #This is a Lambda Permission resource that grants Secrets Manager permission to invoke the function LambdaInvokePermission: Type: AWS::Lambda::Permission DependsOn: MyRotationLambda Properties: FunctionName: 'cfn-rotation-lambda' Action: 'lambda:InvokeFunction' Principal: # This is an IAM Role resource. It gets attached to the Lambda rotation function and grants # permissions to the function to retrieve and update the secret as part of the rotation process. # It also includes the required KMS permissions and CloudWatch logging permissions. MyLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: 'cfn-rotation-lambda-role' AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "" Action: - "sts:AssumeRole" Policies: - PolicyName: "AWSSecretsManagerRotationPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "secretsmanager:DescribeSecret" - "secretsmanager:GetSecretValue" - "secretsmanager:PutSecretValue" - "secretsmanager:UpdateSecretVersionStage" Resource: !Sub 'arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*' Condition: StringEquals: secretsmanager:resource/AllowRotationLambdaArn: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:cfn-rotation-lambda' - Effect: "Allow" Action: - "secretsmanager:GetRandomPassword" Resource: "*" - Effect: "Allow" Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: "arn:aws:logs:*:*:*" - Effect: "Allow" Action: - "kms:Decrypt" - "kms:DescribeKey" - "kms:GenerateDataKey" Resource: "*" # This is a Lambda Function resource. We use this to create the rotation function that rotate # our secret. For details about rotation Lambdas, see: # # This example assumes that the Lambda code is already present in an S3 bucket, and that it # is coded to rotate a MySQL database password MyRotationLambda: Type: AWS::Lambda::Function Properties: Runtime: python2.7 Role: !GetAtt MyLambdaExecutionRole.Arn Handler: lambda_function.lambda_handler Description: 'This is a lambda to rotate MySql user passwd' FunctionName: 'cfn-rotation-lambda' Environment: Variables: SECRETS_MANAGER_ENDPOINT: !Sub 'https://secretsmanager.${AWS::Region}' Code: S3Bucket: <% replace-this-with-name-of-s3-bucket-that-contains-lambda-function-code %> S3Key: <% replace-this-with-path-and-filename-of-zip-file-that-contains-lambda-function-code %> S3ObjectVersion: <% replace-this-with-lambda-zip-file-version-if-s3-bucket-versioning-is-enabled %>

See Also