Skip to content

Commit

Permalink
fix(secretsmanager): support secrets rotation in partition 'aws-cn' (a…
Browse files Browse the repository at this point in the history
…ws#14608)

closes aws#13385

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
zxkane authored Jun 16, 2021
1 parent a418ea6 commit 5061a8d
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 32 deletions.
7 changes: 7 additions & 0 deletions .gitallowed
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ account: '856666278305'
account: '840364872350'
account: '422531588944'
account: '924023996002'

# The account IDs of password rotation applications of Serverless Application Repository
# https://docs.aws.amazon.com/secretsmanager/latest/userguide/enable-rotation-rds.html
# partition aws
account: '297356227824'
# partition aws-cn
account: '193023089310'
8 changes: 4 additions & 4 deletions packages/@aws-cdk/aws-docdb/test/cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,8 @@ describe('DatabaseCluster', () => {
// THEN
expectCDK(stack).to(haveResource('AWS::Serverless::Application', {
Location: {
ApplicationId: 'arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerMongoDBRotationSingleUser',
SemanticVersion: '1.1.60',
ApplicationId: { 'Fn::FindInMap': ['DatabaseRotationSingleUserSARMapping9AEB3E55', { Ref: 'AWS::Partition' }, 'applicationId'] },
SemanticVersion: { 'Fn::FindInMap': ['DatabaseRotationSingleUserSARMapping9AEB3E55', { Ref: 'AWS::Partition' }, 'semanticVersion'] },
},
Parameters: {
endpoint: {
Expand Down Expand Up @@ -653,8 +653,8 @@ describe('DatabaseCluster', () => {
// THEN
expectCDK(stack).to(haveResource('AWS::Serverless::Application', {
Location: {
ApplicationId: 'arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerMongoDBRotationMultiUser',
SemanticVersion: '1.1.60',
ApplicationId: { 'Fn::FindInMap': ['DatabaseRotationSARMappingE46CFA92', { Ref: 'AWS::Partition' }, 'applicationId'] },
SemanticVersion: { 'Fn::FindInMap': ['DatabaseRotationSARMappingE46CFA92', { Ref: 'AWS::Partition' }, 'semanticVersion'] },
},
Parameters: {
endpoint: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@
"VPCPublicSubnet1NATGatewayE0556630": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VPCPublicSubnet1SubnetB4246D30"
},
"AllocationId": {
"Fn::GetAtt": [
"VPCPublicSubnet1EIP6AD938E8",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VPCPublicSubnet1SubnetB4246D30"
},
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -193,15 +193,15 @@
"VPCPublicSubnet2NATGateway3C070193": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VPCPublicSubnet2Subnet74179F39"
},
"AllocationId": {
"Fn::GetAtt": [
"VPCPublicSubnet2EIP4947BC00",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VPCPublicSubnet2Subnet74179F39"
},
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -290,15 +290,15 @@
"VPCPublicSubnet3NATGatewayD3048F5C": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VPCPublicSubnet3Subnet631C5E25"
},
"AllocationId": {
"Fn::GetAtt": [
"VPCPublicSubnet3EIPAD4BC883",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VPCPublicSubnet3Subnet631C5E25"
},
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -747,8 +747,24 @@
"Type": "AWS::Serverless::Application",
"Properties": {
"Location": {
"ApplicationId": "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerMongoDBRotationSingleUser",
"SemanticVersion": "1.1.3"
"ApplicationId": {
"Fn::FindInMap": [
"DatabaseRotationSingleUserSARMapping9AEB3E55",
{
"Ref": "AWS::Partition"
},
"applicationId"
]
},
"SemanticVersion": {
"Fn::FindInMap": [
"DatabaseRotationSingleUserSARMapping9AEB3E55",
{
"Ref": "AWS::Partition"
},
"semanticVersion"
]
}
},
"Parameters": {
"endpoint": {
Expand Down Expand Up @@ -794,5 +810,17 @@
}
}
}
},
"Mappings": {
"DatabaseRotationSingleUserSARMapping9AEB3E55": {
"aws": {
"applicationId": "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerMongoDBRotationSingleUser",
"semanticVersion": "1.1.60"
},
"aws-cn": {
"applicationId": "arn:aws-cn:serverlessrepo:cn-north-1:193023089310:applications/SecretsManagerMongoDBRotationSingleUser",
"semanticVersion": "1.1.37"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@
"VPCPublicSubnet1NATGatewayE0556630": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VPCPublicSubnet1SubnetB4246D30"
},
"AllocationId": {
"Fn::GetAtt": [
"VPCPublicSubnet1EIP6AD938E8",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VPCPublicSubnet1SubnetB4246D30"
},
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -193,15 +193,15 @@
"VPCPublicSubnet2NATGateway3C070193": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VPCPublicSubnet2Subnet74179F39"
},
"AllocationId": {
"Fn::GetAtt": [
"VPCPublicSubnet2EIP4947BC00",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VPCPublicSubnet2Subnet74179F39"
},
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -290,15 +290,15 @@
"VPCPublicSubnet3NATGatewayD3048F5C": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"SubnetId": {
"Ref": "VPCPublicSubnet3Subnet631C5E25"
},
"AllocationId": {
"Fn::GetAtt": [
"VPCPublicSubnet3EIPAD4BC883",
"AllocationId"
]
},
"SubnetId": {
"Ref": "VPCPublicSubnet3Subnet631C5E25"
},
"Tags": [
{
"Key": "Name",
Expand Down Expand Up @@ -769,8 +769,24 @@
"Type": "AWS::Serverless::Application",
"Properties": {
"Location": {
"ApplicationId": "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSMySQLRotationSingleUser",
"SemanticVersion": "1.1.60"
"ApplicationId": {
"Fn::FindInMap": [
"DatabaseRotationSingleUserSARMapping9AEB3E55",
{
"Ref": "AWS::Partition"
},
"applicationId"
]
},
"SemanticVersion": {
"Fn::FindInMap": [
"DatabaseRotationSingleUserSARMapping9AEB3E55",
{
"Ref": "AWS::Partition"
},
"semanticVersion"
]
}
},
"Parameters": {
"endpoint": {
Expand Down Expand Up @@ -817,5 +833,17 @@
}
}
}
},
"Mappings": {
"DatabaseRotationSingleUserSARMapping9AEB3E55": {
"aws": {
"applicationId": "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSMySQLRotationSingleUser",
"semanticVersion": "1.1.60"
},
"aws-cn": {
"applicationId": "arn:aws-cn:serverlessrepo:cn-north-1:193023089310:applications/SecretsManagerRDSMySQLRotationSingleUser",
"semanticVersion": "1.1.37"
}
}
}
}
32 changes: 30 additions & 2 deletions packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,24 @@
"Type": "AWS::Serverless::Application",
"Properties": {
"Location": {
"ApplicationId": "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSOracleRotationSingleUser",
"SemanticVersion": "1.1.60"
"ApplicationId": {
"Fn::FindInMap": [
"InstanceRotationSingleUserSARMappingFEA0C86E",
{
"Ref": "AWS::Partition"
},
"applicationId"
]
},
"SemanticVersion": {
"Fn::FindInMap": [
"InstanceRotationSingleUserSARMappingFEA0C86E",
{
"Ref": "AWS::Partition"
},
"semanticVersion"
]
}
},
"Parameters": {
"endpoint": {
Expand Down Expand Up @@ -1122,5 +1138,17 @@
"Type": "String",
"Description": "Artifact hash for asset \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\""
}
},
"Mappings": {
"InstanceRotationSingleUserSARMappingFEA0C86E": {
"aws": {
"applicationId": "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSOracleRotationSingleUser",
"semanticVersion": "1.1.60"
},
"aws-cn": {
"applicationId": "arn:aws-cn:serverlessrepo:cn-north-1:193023089310:applications/SecretsManagerRDSOracleRotationSingleUser",
"semanticVersion": "1.1.37"
}
}
}
}
58 changes: 56 additions & 2 deletions packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ec2 from '@aws-cdk/aws-ec2';
import * as lambda from '@aws-cdk/aws-lambda';
import * as serverless from '@aws-cdk/aws-sam';
import { Duration, Names, Stack, Token } from '@aws-cdk/core';
import { Duration, Names, Stack, Token, CfnMapping, Aws } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { ISecret } from './secret';

Expand All @@ -20,6 +20,7 @@ export interface SecretRotationApplicationOptions {
*/
readonly isMultiUser?: boolean;
}

/**
* A secret rotation serverless application.
*/
Expand Down Expand Up @@ -110,11 +111,15 @@ export class SecretRotationApplication {

/**
* The application identifier of the rotation application
*
* @deprecated only valid when deploying to the 'aws' partition. Use `applicationArnForPartition` instead.
*/
public readonly applicationId: string;

/**
* The semantic version of the rotation application
*
* @deprecated only valid when deploying to the 'aws' partition. Use `semanticVersionForPartition` instead.
*/
public readonly semanticVersion: string;

Expand All @@ -123,11 +128,45 @@ export class SecretRotationApplication {
*/
public readonly isMultiUser?: boolean;

/**
* The application name of the rotation application
*/
private readonly applicationName: string;

constructor(applicationId: string, semanticVersion: string, options?: SecretRotationApplicationOptions) {
this.applicationId = `arn:aws:serverlessrepo:us-east-1:297356227824:applications/${applicationId}`;
this.semanticVersion = semanticVersion;
this.applicationName = applicationId;
this.isMultiUser = options && options.isMultiUser;
}

/**
* Returns the application ARN for the current partition.
* Can be used in combination with a `CfnMapping` to automatically select the correct ARN based on the current partition.
*/
public applicationArnForPartition(partition: string) {
if (partition === 'aws') {
return this.applicationId;
} else if (partition === 'aws-cn') {
return `arn:aws-cn:serverlessrepo:cn-north-1:193023089310:applications/${this.applicationName}`;
} else {
throw new Error(`unsupported partition: ${partition}`);
}
}

/**
* The semantic version of the app for the current partition.
* Can be used in combination with a `CfnMapping` to automatically select the correct version based on the current partition.
*/
public semanticVersionForPartition(partition: string) {
if (partition === 'aws') {
return this.semanticVersion;
} else if (partition === 'aws-cn') {
return '1.1.37';
} else {
throw new Error(`unsupported partition: ${partition}`);
}
}
}

/**
Expand Down Expand Up @@ -255,8 +294,23 @@ export class SecretRotation extends CoreConstruct {
}
}

const sarMapping = new CfnMapping(this, 'SARMapping', {
mapping: {
'aws': {
applicationId: props.application.applicationArnForPartition('aws'),
semanticVersion: props.application.semanticVersionForPartition('aws'),
},
'aws-cn': {
applicationId: props.application.applicationArnForPartition('aws-cn'),
semanticVersion: props.application.semanticVersionForPartition('aws-cn'),
},
},
});
const application = new serverless.CfnApplication(this, 'Resource', {
location: props.application,
location: {
applicationId: sarMapping.findInMap(Aws.PARTITION, 'applicationId'),
semanticVersion: sarMapping.findInMap(Aws.PARTITION, 'semanticVersion'),
},
parameters,
});

Expand Down
Loading

0 comments on commit 5061a8d

Please sign in to comment.