Namespace Amazon.CDK.AWS.SecretsManager
AWS Secrets Manager Construct Library
using Amazon.CDK.AWS.SecretsManager;
Create a new Secret in a Stack
To have SecretsManager generate a new secret value automatically, follow this example:
IVpc vpc;
var instance1 = new DatabaseInstance(this, "PostgresInstance1", new DatabaseInstanceProps {
Engine = DatabaseInstanceEngine.POSTGRES,
// Generate the secret with admin username `postgres` and random password
Credentials = Credentials.FromGeneratedSecret("postgres"),
Vpc = vpc
});
// Templated secret with username and password fields
var templatedSecret = new Secret(this, "TemplatedSecret", new SecretProps {
GenerateSecretString = new SecretStringGenerator {
SecretStringTemplate = JSON.Stringify(new Dictionary<string, string> { { "username", "postgres" } }),
GenerateStringKey = "password",
ExcludeCharacters = "/@\""
}
});
// Using the templated secret as credentials
var instance2 = new DatabaseInstance(this, "PostgresInstance2", new DatabaseInstanceProps {
Engine = DatabaseInstanceEngine.POSTGRES,
Credentials = new Dictionary<string, object> {
{ "username", templatedSecret.SecretValueFromJson("username").ToString() },
{ "password", templatedSecret.SecretValueFromJson("password") }
},
Vpc = vpc
});
If you need to use a pre-existing secret, the recommended way is to manually
provision the secret in AWS SecretsManager and use the Secret.fromSecretArn
or Secret.fromSecretAttributes
method to make it available in your CDK Application:
Key encryptionKey;
var secret = Secret.FromSecretAttributes(this, "ImportedSecret", new SecretAttributes {
SecretArn = "arn:aws:secretsmanager:<region>:<account-id-number>:secret:<secret-name>-<random-6-characters>",
// If the secret is encrypted using a KMS-hosted CMK, either import or reference that key:
EncryptionKey = encryptionKey
});
SecretsManager secret values can only be used in select set of properties. For the list of properties, see the CloudFormation Dynamic References documentation.
A secret can set RemovalPolicy
. If it set to RETAIN
, removing that secret will fail.
Grant permission to use the secret to a role
You must grant permission to a resource for that resource to be allowed to
use a secret. This can be achieved with the Secret.grantRead
and/or Secret.grantWrite
method, depending on your need:
var role = new Role(this, "SomeRole", new RoleProps { AssumedBy = new AccountRootPrincipal() });
var secret = new Secret(this, "Secret");
secret.GrantRead(role);
secret.GrantWrite(role);
If, as in the following example, your secret was created with a KMS key:
Role role;
var key = new Key(this, "KMS");
var secret = new Secret(this, "Secret", new SecretProps { EncryptionKey = key });
secret.GrantRead(role);
secret.GrantWrite(role);
then Secret.grantRead
and Secret.grantWrite
will also grant the role the
relevant encrypt and decrypt permissions to the KMS key through the
SecretsManager service principal.
The principal is automatically added to Secret resource policy and KMS Key policy for cross account access:
var otherAccount = new AccountPrincipal("1234");
var key = new Key(this, "KMS");
var secret = new Secret(this, "Secret", new SecretProps { EncryptionKey = key });
secret.GrantRead(otherAccount);
Using a Custom Lambda Function
A rotation schedule can be added to a Secret using a custom Lambda function:
using Amazon.CDK.AWS.Lambda;
Function fn;
var secret = new Secret(this, "Secret");
secret.AddRotationSchedule("RotationSchedule", new RotationScheduleOptions {
RotationLambda = fn,
AutomaticallyAfter = Duration.Days(15),
RotateImmediatelyOnUpdate = false
});
Note: The required permissions for Lambda to call SecretsManager and the other way round are automatically granted based on AWS Documentation as long as the Lambda is not imported.
See Overview of the Lambda Rotation Function on how to implement a Lambda Rotation Function.
Using a Hosted Lambda Function
Use the hostedRotation
prop to rotate a secret with a hosted Lambda function:
var secret = new Secret(this, "Secret");
secret.AddRotationSchedule("RotationSchedule", new RotationScheduleOptions {
HostedRotation = HostedRotation.MysqlSingleUser()
});
Hosted rotation is available for secrets representing credentials for MySQL, PostgreSQL, Oracle, MariaDB, SQLServer, Redshift and MongoDB (both for the single and multi user schemes).
When deployed in a VPC, the hosted rotation implements ec2.IConnectable
:
IVpc myVpc;
Connections dbConnections;
Secret secret;
var myHostedRotation = HostedRotation.MysqlSingleUser(new SingleUserHostedRotationOptions { Vpc = myVpc });
secret.AddRotationSchedule("RotationSchedule", new RotationScheduleOptions { HostedRotation = myHostedRotation });
dbConnections.AllowDefaultPortFrom(myHostedRotation);
Use the excludeCharacters
option to customize the characters excluded from
the generated password when it is rotated. By default, the rotation excludes
the same characters as the ones excluded for the secret. If none are defined
then the following set is used: % +~
#$&*()|[]{}:;<>?!'/@"`.
See also Automating secret creation in AWS CloudFormation.
Rotating database credentials
Define a SecretRotation
to rotate database credentials:
Secret mySecret;
IConnectable myDatabase;
Vpc myVpc;
new SecretRotation(this, "SecretRotation", new SecretRotationProps {
Application = SecretRotationApplication.MYSQL_ROTATION_SINGLE_USER, // MySQL single user scheme
Secret = mySecret,
Target = myDatabase, // a Connectable
Vpc = myVpc, // The VPC where the secret rotation application will be deployed
ExcludeCharacters = " %+:;{}"
});
The secret must be a JSON string with the following format:
{
"engine": "<required: database engine>",
"host": "<required: instance host name>",
"username": "<required: username>",
"password": "<required: password>",
"dbname": "<optional: database name>",
"port": "<optional: if not specified, default port will be used>",
"masterarn": "<required for multi user rotation: the arn of the master secret which will be used to create users/change passwords>"
}
For the multi user scheme, a masterSecret
must be specified:
Secret myUserSecret;
Secret myMasterSecret;
IConnectable myDatabase;
Vpc myVpc;
new SecretRotation(this, "SecretRotation", new SecretRotationProps {
Application = SecretRotationApplication.MYSQL_ROTATION_MULTI_USER,
Secret = myUserSecret, // The secret that will be rotated
MasterSecret = myMasterSecret, // The secret used for the rotation
Target = myDatabase,
Vpc = myVpc
});
By default, any stack updates will cause AWS Secrets Manager to rotate a secret immediately. To prevent this behavior and wait until the next scheduled rotation window specified via the automaticallyAfter
property, set the rotateImmediatelyOnUpdate
property to false:
Secret myUserSecret;
Secret myMasterSecret;
IConnectable myDatabase;
Vpc myVpc;
new SecretRotation(this, "SecretRotation", new SecretRotationProps {
Application = SecretRotationApplication.MYSQL_ROTATION_MULTI_USER,
Secret = myUserSecret, // The secret that will be rotated
MasterSecret = myMasterSecret, // The secret used for the rotation
Target = myDatabase,
Vpc = myVpc,
AutomaticallyAfter = Duration.Days(7),
RotateImmediatelyOnUpdate = false
});
See also aws-rds where credentials generation and rotation is integrated.
Importing Secrets
Existing secrets can be imported by ARN, name, and other attributes (including the KMS key used to encrypt the secret). Secrets imported by name should use the short-form of the name (without the SecretsManager-provided suffix); the secret name must exist in the same account and region as the stack. Importing by name makes it easier to reference secrets created in different regions, each with their own suffix and ARN.
var secretCompleteArn = "arn:aws:secretsmanager:eu-west-1:111111111111:secret:MySecret-f3gDy9";
var secretPartialArn = "arn:aws:secretsmanager:eu-west-1:111111111111:secret:MySecret"; // No Secrets Manager suffix
var encryptionKey = Key.FromKeyArn(this, "MyEncKey", "arn:aws:kms:eu-west-1:111111111111:key/21c4b39b-fde2-4273-9ac0-d9bb5c0d0030");
var mySecretFromCompleteArn = Secret.FromSecretCompleteArn(this, "SecretFromCompleteArn", secretCompleteArn);
var mySecretFromPartialArn = Secret.FromSecretPartialArn(this, "SecretFromPartialArn", secretPartialArn);
var mySecretFromName = Secret.FromSecretNameV2(this, "SecretFromName", "MySecret");
var mySecretFromAttrs = Secret.FromSecretAttributes(this, "SecretFromAttributes", new SecretAttributes {
SecretCompleteArn = secretCompleteArn,
EncryptionKey = encryptionKey
});
Replicating secrets
Secrets can be replicated to multiple regions by specifying replicaRegions
:
Key myKey;
new Secret(this, "Secret", new SecretProps {
ReplicaRegions = new [] { new ReplicaRegion {
Region = "eu-west-1"
}, new ReplicaRegion {
Region = "eu-central-1",
EncryptionKey = myKey
} }
});
Alternatively, use addReplicaRegion()
:
var secret = new Secret(this, "Secret");
secret.AddReplicaRegion("eu-west-1");
Creating JSON Secrets
Sometimes it is necessary to create a secret in SecretsManager that contains a JSON object. For example:
{
"username": "myUsername",
"database": "foo",
"password": "mypassword"
}
In order to create this type of secret, use the secretObjectValue
input prop.
Stack stack;
var user = new User(this, "User");
var accessKey = new AccessKey(this, "AccessKey", new AccessKeyProps { User = user });
new Secret(this, "Secret", new SecretProps {
SecretObjectValue = new Dictionary<string, SecretValue> {
{ "username", SecretValue.UnsafePlainText(user.UserName) },
{ "database", SecretValue.UnsafePlainText("foo") },
{ "password", accessKey.SecretAccessKey }
}
});
In this case both the username
and database
are not a Secret
so SecretValue.unsafePlainText
needs to be used.
This means that they will be rendered as plain text in the template, but in this case neither of those
are actual "secrets".
Classes
AttachedSecretOptions | Options to add a secret attachment to a secret. |
AttachmentTargetType | The type of service or database that's being associated with the secret. |
CfnResourcePolicy | Attaches a resource-based permission policy to a secret. |
CfnResourcePolicyProps | Properties for defining a |
CfnRotationSchedule | Sets the rotation schedule and Lambda rotation function for a secret. For more information, see How rotation works . |
CfnRotationSchedule.HostedRotationLambdaProperty | Creates a new Lambda rotation function based on one of the Secrets Manager rotation function templates . |
CfnRotationSchedule.RotationRulesProperty | The rotation schedule and window. |
CfnRotationScheduleProps | Properties for defining a |
CfnSecret | Creates a new secret. |
CfnSecret.GenerateSecretStringProperty | Generates a random password. |
CfnSecret.ReplicaRegionProperty | Specifies a |
CfnSecretProps | Properties for defining a |
CfnSecretTargetAttachment | The |
CfnSecretTargetAttachmentProps | Properties for defining a |
HostedRotation | A hosted rotation. |
HostedRotationType | Hosted rotation type. |
MultiUserHostedRotationOptions | Multi user hosted rotation options. |
ReplicaRegion | Secret replica region. |
ResourcePolicy | Resource Policy for SecretsManager Secrets. |
ResourcePolicyProps | Construction properties for a ResourcePolicy. |
RotationSchedule | A rotation schedule. |
RotationScheduleOptions | Options to add a rotation schedule to a secret. |
RotationScheduleProps | Construction properties for a RotationSchedule. |
Secret | Creates a new secret in AWS SecretsManager. |
SecretAttachmentTargetProps | Attachment target specifications. |
SecretAttributes | Attributes required to import an existing secret into the Stack. |
SecretProps | The properties required to create a new secret in AWS Secrets Manager. |
SecretRotation | Secret rotation for a service or database. |
SecretRotationApplication | A secret rotation serverless application. |
SecretRotationApplicationOptions | Options for a SecretRotationApplication. |
SecretRotationProps | Construction properties for a SecretRotation. |
SecretStringGenerator | Configuration to generate secrets such as passwords automatically. |
SecretStringValueBeta1 | (deprecated) An experimental class used to specify an initial secret value for a Secret. |
SecretTargetAttachment | An attached secret. |
SecretTargetAttachmentProps | Construction properties for an AttachedSecret. |
SingleUserHostedRotationOptions | Single user hosted rotation options. |
Interfaces
CfnRotationSchedule.IHostedRotationLambdaProperty | Creates a new Lambda rotation function based on one of the Secrets Manager rotation function templates . |
CfnRotationSchedule.IRotationRulesProperty | The rotation schedule and window. |
CfnSecret.IGenerateSecretStringProperty | Generates a random password. |
CfnSecret.IReplicaRegionProperty | Specifies a |
IAttachedSecretOptions | Options to add a secret attachment to a secret. |
ICfnResourcePolicyProps | Properties for defining a |
ICfnRotationScheduleProps | Properties for defining a |
ICfnSecretProps | Properties for defining a |
ICfnSecretTargetAttachmentProps | Properties for defining a |
IMultiUserHostedRotationOptions | Multi user hosted rotation options. |
IReplicaRegion | Secret replica region. |
IResourcePolicyProps | Construction properties for a ResourcePolicy. |
IRotationScheduleOptions | Options to add a rotation schedule to a secret. |
IRotationScheduleProps | Construction properties for a RotationSchedule. |
ISecret | A secret in AWS Secrets Manager. |
ISecretAttachmentTarget | A secret attachment target. |
ISecretAttachmentTargetProps | Attachment target specifications. |
ISecretAttributes | Attributes required to import an existing secret into the Stack. |
ISecretProps | The properties required to create a new secret in AWS Secrets Manager. |
ISecretRotationApplicationOptions | Options for a SecretRotationApplication. |
ISecretRotationProps | Construction properties for a SecretRotation. |
ISecretStringGenerator | Configuration to generate secrets such as passwords automatically. |
ISecretTargetAttachment | |
ISecretTargetAttachmentProps | Construction properties for an AttachedSecret. |
ISingleUserHostedRotationOptions | Single user hosted rotation options. |