CDK Snippets
Bootstrap with trusted account
bash
cdk bootstrap aws://${accountId}/ap-southeast-1 --trust ${trustedAccountId}Get stack name
typescript
console.log('stackName 👉', cdk.Stack.of(this).stackName);Read and Store value into Parameter Store
typescript
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
// retrieve value
const domainName = StringParameter.valueForStringParameter(this, '/kmp/config/domain-name');
// store into parameter store
new StringParameter(this, 'BucketName', {
parameterName: '/kmp/tenant/bucket-name',
stringValue: bucket.bucketName,
});Get Certificate and HostedZone
typescript
const domainName = StringParameter.valueForStringParameter(this, '/kmp/config/domain-name');
const certificateArn = StringParameter.valueForStringParameter(
this,
'/kmp/config/certificate-arn-ap-southeast-1'
);
const hostedZoneId = StringParameter.valueForStringParameter(this, '/kmp/config/hosted-zone-id');
const hostedZone = HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
hostedZoneId,
zoneName: domainName,
});
const certificate = Certificate.fromCertificateArn(this, 'Certificate', certificateArn);Create S3 Bucket that gets deleted when destroyed
typescript
const bucket = new Bucket(this, 'TenantBucket', {
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});Create DynamoDB Table
typescript
const table = new TableV2(this, 'TenantTable', {
partitionKey: { name: 'tenantName', type: AttributeType.STRING },
sortKey: { name: 'createdAt', type: AttributeType.STRING },
// destroy table when stack is destroyed
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
table.addGlobalSecondaryIndex({
indexName: 'userNameIndex',
partitionKey: { name: 'userName', type: AttributeType.STRING },
projectionType: ProjectionType.ALL,
});Create Lambda using NodejsFunction
typescript
const apiHandler = new NodejsFunction(this, 'TenantApiHandler', {
memorySize: 1024,
timeout: cdk.Duration.seconds(5),
runtime: Runtime.NODEJS_18_X,
entry: path.join(__dirname, '../src/api/index.ts'),
bundling: {
minify: true,
externalModules: ['@aws-sdk/*'],
},
environment: {
table: table.tableName,
},
});Create HTTP Api with Custom Domain
typescript
import { CorsHttpMethod, DomainName, HttpApi, HttpMethod } from '@aws-cdk/aws-apigatewayv2-alpha';
import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations-alpha';
import { ARecord, HostedZone, RecordTarget } from 'aws-cdk-lib/aws-route53';
import { ApiGatewayv2DomainProperties } from 'aws-cdk-lib/aws-route53-targets';
const hostname = 'tenant-api';
const customDomain = new DomainName(this, `TenantCustomDomain`, {
domainName: `${hostname}.${domainName}`,
certificate,
});
new ARecord(this, 'TenantCustomDomainRecord', {
recordName: hostname,
zone: hostedZone,
target: RecordTarget.fromAlias(
new ApiGatewayv2DomainProperties(
customDomain.regionalDomainName,
customDomain.regionalHostedZoneId
)
),
});
const httpApi = new HttpApi(this, 'TenantHttpApi', {
corsPreflight: {
allowOrigins: ['*'],
allowCredentials: false,
allowHeaders: ['Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key'],
allowMethods: [CorsHttpMethod.ANY],
},
defaultDomainMapping: {
domainName: customDomain,
},
});
httpApi.addRoutes({
path: '/',
methods: [HttpMethod.ANY],
integration: new HttpLambdaIntegration('TenantApiIntegration', apiHandler),
});Use CfnParameter
Deploy myStack:
bash
npx aws-cdk deploy MyStack --parameters databasePort=5000Inside the CDK:
typescript
const databasePort = new cdk.CfnParameter(this, 'databasePort', {
type: 'Number',
description: 'The database port to open for ingress connections',
minValue: 1,
maxValue: 10000,
default: 5432,
allowedValues: ['1000', '3000', '5000', '5432'],
});
console.log('database port 👉', databasePort.valueAsString);