AWS::SecretsManager::RotationSchedule
Configure the rotation schedule and Lambda rotation function for a secret. For more information, see How rotation works.
For database credentials, refer to the following resources:
-
Amazon RDS master user credentials: AWS::RDS::DBCluster MasterUserSecret
-
Amazon Redshift admin user credentials: AWS::Redshift::Cluster
Choose one of the following options for the rotation function:
-
Create a new rotation function using
HostedRotationLambda
based on a Secrets Manager rotation function template. -
Use an existing rotation function by specifying its ARN with
RotationLambdaARN
.
Important
For database secrets defined in the same AWS CloudFormation template as the database or service:
-
Use the AWS::SecretsManager::SecretTargetAttachment resource to populate the secret with connection details.
-
Add a
DependsOn
attribute to theRotationSchedule
resource that uses aSecretTargetAttachment
. This ensures the rotation is configured after the secret is populated with connection details.
Note
You can define only one rotation schedule per secret.
Syntax
To declare this entity in your AWS CloudFormation template, use the following syntax:
JSON
{ "Type" : "AWS::SecretsManager::RotationSchedule", "Properties" : { "HostedRotationLambda" :
HostedRotationLambda
, "RotateImmediatelyOnUpdate" :Boolean
, "RotationLambdaARN" :String
, "RotationRules" :RotationRules
, "SecretId" :String
} }
YAML
Type: AWS::SecretsManager::RotationSchedule Properties: HostedRotationLambda:
HostedRotationLambda
RotateImmediatelyOnUpdate:Boolean
RotationLambdaARN:String
RotationRules:RotationRules
SecretId:String
Properties
HostedRotationLambda
-
Creates a new Lambda rotation function based on one of the Secrets Manager rotation function templates. To use a rotation function that already exists, specify
RotationLambdaARN
instead.You must specify
Transform: AWS::SecretsManager-2024-09-16
at the beginning of the CloudFormation template. Transforms are macros hosted by AWS CloudFormation that help you create and manage complex infrastructure. TheTransform: AWS::SecretsManager-2024-09-16
transform automatically extends the CloudFormation stack to include a nested stack (of typeAWS::CloudFormation::Stack
), which then creates and updates on your behalf during subsequent stack operations, the appropriate rotation Lambda function for your database or service. For general information on transforms, see the AWS CloudFormation documentation.For Amazon RDS master user credentials, see AWS::RDS::DBCluster MasterUserSecret.
For Amazon Redshift admin user credentials, see AWS::Redshift::Cluster.
Required: No
Type: HostedRotationLambda
Update requires: No interruption
RotateImmediatelyOnUpdate
-
Determines whether to rotate the secret immediately or wait until the next scheduled rotation window when the rotation schedule is updated. The rotation schedule is defined in
RotationRules
.The default for
RotateImmediatelyOnUpdate
istrue
. If you don't specify this value, Secrets Manager rotates the secret immediately.If you set
RotateImmediatelyOnUpdate
tofalse
, Secrets Manager tests the rotation configuration by running thetestSecret
step of the Lambda rotation function. This test creates anAWSPENDING
version of the secret and then removes it.Important
When changing an existing rotation schedule and setting
RotateImmediatelyOnUpdate
tofalse
:-
If using
AutomaticallyAfterDays
or aScheduleExpression
withrate()
, the previously scheduled rotation might still occur. -
To prevent unintended rotations, use a
ScheduleExpression
withcron()
for granular control over rotation windows.
Rotation is an asynchronous process. For more information, see How rotation works.
Required: No
Type: Boolean
Update requires: No interruption
-
RotationLambdaARN
-
The ARN of an existing Lambda rotation function. To specify a rotation function that is also defined in this template, use the Ref function.
For Amazon RDS master user credentials, see AWS::RDS::DBCluster MasterUserSecret.
For Amazon Redshift admin user credentials, see AWS::Redshift::Cluster.
To create a new rotation function based on one of the Secrets Manager rotation function templates, specify
HostedRotationLambda
instead.Required: No
Type: String
Update requires: No interruption
RotationRules
-
A structure that defines the rotation configuration for this secret.
Required: No
Type: RotationRules
Update requires: No interruption
SecretId
-
The ARN or name of the secret to rotate. This is unique for each rotation schedule definition.
To reference a secret also created in this template, use the Ref function with the secret's logical ID.
Required: Yes
Type: String
Update requires: Replacement
Return values
Ref
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 being configured, such as:
arn:aws:secretsmanager: us-west-2:123456789012:secret:my-path/my-secret-name-1a2b3c
You can use the ARN to reference a secret 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.
Fn::GetAtt
The Fn::GetAtt
intrinsic function returns a value for a specified attribute of this type. The following are the available attributes and sample return values.
For more information about using the Fn::GetAtt
intrinsic function, see Fn::GetAtt
.
Examples
Automatic rotation with a cron expression
The following example rotates a secret every day between 1:00 AM and 3:00 AM UTC.
JSON
"MySecretRotationSchedule": { "Type": "AWS::SecretsManager::RotationSchedule", "DependsOn": "MyRotationLambda", "Properties": { "SecretId": {"Ref": "MySecret"}, "RotationLambdaARN": {"Fn::GetAtt": "MyRotationLambda.Arn"}, "RotationRules": { "Duration": "2h", "ScheduleExpression": "cron(0 1 * * ? *)" } } }
YAML
MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: MyRotationLambda Properties: SecretId: !Ref MySecret RotationLambdaARN: !GetAtt MyRotationLambda.Arn RotationRules: Duration: 2h ScheduleExpression: 'cron(0 1 * * ? *)'
Automatic rotation with a rate expression
The following example rotates a secret between midnight and 6:00 AM UTC every 10 days.
JSON
"MySecretRotationSchedule": { "Type": "AWS::SecretsManager::RotationSchedule", "DependsOn": "MyRotationLambda", "Properties": { "SecretId": {"Ref": "MySecret"}, "RotationLambdaARN": {"Fn::GetAtt": "MyRotationLambda.Arn"}, "RotationRules": { "Duration": "6h", "ScheduleExpression": "rate(10 days)" } } }
YAML
MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: MyRotationLambda Properties: SecretId: !Ref MySecret RotationLambdaARN: !GetAtt MyRotationLambda.Arn RotationRules: Duration: 6h ScheduleExpression: 'rate(10 days)'
DocumentDB secret rotation example
The following example creates a DocumentDB database instance and a secret with credentials. The secret is configured to rotate on the first Sunday of every month between 4:00 AM and 6:00 AM UTC.
JSON
{ "AWSTemplateFormatVersion":"2010-09-09", "Transform":"AWS::SecretsManager-2024-09-16", "Resources":{ "TestVPC":{ "Type":"AWS::EC2::VPC", "Properties":{ "CidrBlock":"10.0.0.0/16", "EnableDnsHostnames":true, "EnableDnsSupport":true } }, "TestSubnet01":{ "Type":"AWS::EC2::Subnet", "Properties":{ "CidrBlock":"10.0.96.0/19", "AvailabilityZone":{ "Fn::Select":[ "0", { "Fn::GetAZs":{ "Ref":"AWS::Region" } } ] }, "VpcId":{ "Ref":"TestVPC" } } }, "TestSubnet02":{ "Type":"AWS::EC2::Subnet", "Properties":{ "CidrBlock":"10.0.128.0/19", "AvailabilityZone":{ "Fn::Select":[ "1", { "Fn::GetAZs":{ "Ref":"AWS::Region" } } ] }, "VpcId":{ "Ref":"TestVPC" } } }, "SecretsManagerVPCEndpoint":{ "Type":"AWS::EC2::VPCEndpoint", "Properties":{ "SubnetIds":[ { "Ref":"TestSubnet01" }, { "Ref":"TestSubnet02" } ], "SecurityGroupIds":[ { "Fn::GetAtt":[ "TestVPC", "DefaultSecurityGroup" ] } ], "VpcEndpointType":"Interface", "ServiceName":{ "Fn::Sub":"com.amazonaws.${AWS::Region}.secretsmanager" }, "PrivateDnsEnabled":true, "VpcId":{ "Ref":"TestVPC" } } }, "MyDocDBClusterRotationSecret":{ "Type":"AWS::SecretsManager::Secret", "Properties":{ "GenerateSecretString":{ "SecretStringTemplate":"{\"username\": \"someadmin\",\"ssl\": true}", "GenerateStringKey":"password", "PasswordLength":16, "ExcludeCharacters":"\"@/\\" }, "Tags":[ { "Key":"AppName", "Value":"MyApp" } ] } }, "MyDocDBCluster":{ "Type":"AWS::DocDB::DBCluster", "Properties":{ "DBSubnetGroupName":{ "Ref":"MyDBSubnetGroup" }, "MasterUsername":{ "Fn::Sub":"{{resolve:secretsmanager:${MyDocDBClusterRotationSecret}::username}}" }, "MasterUserPassword":{ "Fn::Sub":"{{resolve:secretsmanager:${MyDocDBClusterRotationSecret}::password}}" }, "VpcSecurityGroupIds":[ { "Fn::GetAtt":[ "TestVPC", "DefaultSecurityGroup" ] } ] } }, "DocDBInstance":{ "Type":"AWS::DocDB::DBInstance", "Properties":{ "DBClusterIdentifier":{ "Ref":"MyDocDBCluster" }, "DBInstanceClass":"db.r5.large" } }, "MyDBSubnetGroup":{ "Type":"AWS::DocDB::DBSubnetGroup", "Properties":{ "DBSubnetGroupDescription":"", "SubnetIds":[ { "Ref":"TestSubnet01" }, { "Ref":"TestSubnet02" } ] } }, "SecretDocDBClusterAttachment":{ "Type":"AWS::SecretsManager::SecretTargetAttachment", "Properties":{ "SecretId":{ "Ref":"MyDocDBClusterRotationSecret" }, "TargetId":{ "Ref":"MyDocDBCluster" }, "TargetType":"AWS::DocDB::DBCluster" } }, "MySecretRotationSchedule":{ "Type":"AWS::SecretsManager::RotationSchedule", "DependsOn":"SecretDocDBClusterAttachment", "Properties":{ "SecretId":{ "Ref":"MyDocDBClusterRotationSecret" }, "HostedRotationLambda":{ "RotationType":"MongoDBSingleUser", "RotationLambdaName":"MongoDBSingleUser", "VpcSecurityGroupIds":{ "Fn::GetAtt":[ "TestVPC", "DefaultSecurityGroup" ] }, "VpcSubnetIds":{ "Fn::Join":[ ",", [ { "Ref":"TestSubnet01" }, { "Ref":"TestSubnet02" } ] ] } }, "RotationRules":{ "Duration": "2h", "ScheduleExpression": "cron(0 4 ? * SUN#1 *)" } } } } }
YAML
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::SecretsManager-2024-09-16 Resources: TestVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true TestSubnet01: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.96.0/19 AvailabilityZone: Fn::Select: - '0' - Fn::GetAZs: Ref: AWS::Region VpcId: Ref: TestVPC TestSubnet02: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.128.0/19 AvailabilityZone: Fn::Select: - '1' - Fn::GetAZs: Ref: AWS::Region VpcId: Ref: TestVPC SecretsManagerVPCEndpoint: Type: AWS::EC2::VPCEndpoint Properties: SubnetIds: - Ref: TestSubnet01 - Ref: TestSubnet02 SecurityGroupIds: - Fn::GetAtt: - TestVPC - DefaultSecurityGroup VpcEndpointType: Interface ServiceName: Fn::Sub: com.amazonaws.${AWS::Region}.secretsmanager PrivateDnsEnabled: true VpcId: Ref: TestVPC MyDocDBClusterRotationSecret: Type: AWS::SecretsManager::Secret Properties: GenerateSecretString: SecretStringTemplate: '{\"username\": \"someadmin\",\"ssl\": true}' GenerateStringKey: password PasswordLength: 16 ExcludeCharacters: "\"@/\\" Tags: - Key: AppName Value: MyApp MyDocDBCluster: Type: AWS::DocDB::DBCluster Properties: DBSubnetGroupName: Ref: MyDBSubnetGroup MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${MyDocDBClusterRotationSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${MyDocDBClusterRotationSecret}::password}}" VpcSecurityGroupIds: - Fn::GetAtt: - TestVPC - DefaultSecurityGroup DocDBInstance: Type: AWS::DocDB::DBInstance Properties: DBClusterIdentifier: Ref: MyDocDBCluster DBInstanceClass: db.r5.large MyDBSubnetGroup: Type: AWS::DocDB::DBSubnetGroup Properties: DBSubnetGroupDescription: '' SubnetIds: - Ref: TestSubnet01 - Ref: TestSubnet02 SecretDocDBClusterAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: Ref: MyDocDBClusterRotationSecret TargetId: Ref: MyDocDBCluster TargetType: AWS::DocDB::DBCluster MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretDocDBClusterAttachment Properties: SecretId: Ref: MyDocDBClusterRotationSecret HostedRotationLambda: RotationType: MongoDBSingleUser RotationLambdaName: MongoDBSingleUser VpcSecurityGroupIds: Fn::GetAtt: - TestVPC - DefaultSecurityGroup VpcSubnetIds: Fn::Join: - "," - - Ref: TestSubnet01 - Ref: TestSubnet02 RotationRules: Duration: 2h ScheduleExpression: 'cron(0 4 ? * SUN#1 *)'
See also
-
RotateSecret in the AWS Secrets Manager API Reference
-
Rotate secrets in the AWS Secrets Manager User Guide