in packages/aws-rfdk/lib/core/lib/x509-certificate.ts [161:233]
constructor(scope: Construct, id: string, props: X509CertificateBaseProps) {
super(scope, id);
this.database = new Table(this, 'Table', {
partitionKey: { name: 'PhysicalId', type: AttributeType.STRING },
sortKey: { name: 'CustomResource', type: AttributeType.STRING },
removalPolicy: RemovalPolicy.DESTROY,
encryption: TableEncryption.AWS_MANAGED,
billingMode: BillingMode.PAY_PER_REQUEST,
pointInTimeRecovery: true,
});
this.passphrase = new Secret(this, 'Passphrase', {
description: `Passphrase for the private key of the X509Certificate ${Names.uniqueId(this)}`,
encryptionKey: props.encryptionKey,
generateSecretString: {
excludeCharacters: '"()$\'', // Exclude characters that might interact with command shells.
excludePunctuation: true,
includeSpace: false,
passwordLength: 24,
requireEachIncludedType: true,
},
});
const region = Stack.of(this).region;
const openSslLayerName = 'openssl-al2';
const openSslLayerArns: any = ARNS[openSslLayerName];
const openSslLayerArn = openSslLayerArns[region];
const openSslLayer = LayerVersion.fromLayerVersionArn(this, 'OpenSslLayer', openSslLayerArn);
/*
* We cannot make this a singleton function; doing so would create circular references in the lambda role (to sign
* a cert we need a cert that this lambda generated).
*/
this.lambdaFunc = new LambdaFunction(this, 'Generator', {
description: `Used by a X509Certificate ${Names.uniqueId(this)} to generate certificates.`,
code: props.lambdaCode,
environment: {
DATABASE: this.database.tableName,
DEBUG: 'false',
},
runtime: Runtime.NODEJS_18_X,
layers: [ openSslLayer ],
handler: props.lambdaHandler,
timeout: Duration.seconds(90),
logRetention: RetentionDays.ONE_WEEK,
});
this.database.grantReadWriteData(this.lambdaFunc);
this.database.grant(this.lambdaFunc, 'dynamodb:DescribeTable');
props.encryptionKey?.grantEncrypt(this.lambdaFunc);
this.passphrase.grantRead(this.lambdaFunc);
const uniqueValue = crypto.createHash('md5').update(Names.uniqueId(this)).digest('hex');
this.uniqueTag = new Tag(
`X509SecretGrant-${uniqueValue.slice(0, 8).toUpperCase()}`,
uniqueValue,
);
const tagCondition: { [key: string]: any } = {};
tagCondition[`secretsmanager:ResourceTag/${this.uniqueTag.key}`] = this.uniqueTag.value;
this.lambdaFunc.addToRolePolicy(new PolicyStatement({
actions: [
'secretsmanager:CreateSecret',
'secretsmanager:DeleteSecret',
'secretsmanager:TagResource',
'secretsmanager:PutSecretValue',
],
resources: ['*'],
conditions: {
StringEquals: tagCondition,
},
}));
}