_templates/new-lambda/api-gateway/cdk-lib.ejs.t (110 lines of code) (raw):
---
# This template creates a CDK definition for the new lambda
to: cdk/lib/<%=lambdaName%>.ts
sh: git add cdk/lib/<%=lambdaName%>.ts
---
<% PascalCase = h.changeCase.pascal(lambdaName) %>
import { GuApiLambda } from '@guardian/cdk';
import { GuAlarm } from '@guardian/cdk/lib/constructs/cloudwatch';
import type { GuStackProps } from '@guardian/cdk/lib/constructs/core';
import { GuStack } from '@guardian/cdk/lib/constructs/core';
import type { App } from 'aws-cdk-lib';
import { Duration } from 'aws-cdk-lib';
<% if (includeApiKey === 'Y'){ %>
import { ApiKeySourceType } from 'aws-cdk-lib/aws-apigateway';
<% } %>
import { CfnBasePathMapping, CfnDomainName } from 'aws-cdk-lib/aws-apigateway';
import { ComparisonOperator, Metric } from 'aws-cdk-lib/aws-cloudwatch';
import { Effect, Policy, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { CfnRecordSet } from 'aws-cdk-lib/aws-route53';
import { nodeVersion } from './node-version';
export interface <%= PascalCase %>Props extends GuStackProps {
stack: string;
stage: string;
certificateId: string;
domainName: string;
hostedZoneId: string;
}
export class <%= PascalCase %> extends GuStack {
constructor(scope: App, id: string, props: <%= PascalCase %>Props) {
super(scope, id, props);
const app = '<%= lambdaName %>';
const nameWithStage = `${app}-${this.stage}`;
const commonEnvironmentVariables = {
App: app,
Stack: this.stack,
Stage: this.stage,
};
// ---- API-triggered lambda functions ---- //
const lambda = new GuApiLambda(this, `${app}-lambda`, {
description:
'An API Gateway triggered lambda generated in the support-service-lambdas repo',
functionName: nameWithStage,
fileName: `${app}.zip`,
handler: 'index.handler',
runtime: nodeVersion,
memorySize: 1024,
timeout: Duration.seconds(300),
environment: commonEnvironmentVariables,
// Create an alarm
monitoringConfiguration: {
http5xxAlarm: { tolerated5xxPercentage: 5 },
snsTopicName: `alarms-handler-topic-${this.stage}`,
},
app: app,
api: {
id: nameWithStage,
restApiName: nameWithStage,
description: 'API Gateway created by CDK',
proxy: true,
deployOptions: {
stageName: this.stage,
},
<% if (includeApiKey === 'Y'){ %>
apiKeySourceType: ApiKeySourceType.HEADER,
defaultMethodOptions: {
apiKeyRequired: true,
},
<% } %>
},
});
<% if (includeApiKey === 'Y'){ %>
const usagePlan = lambda.api.addUsagePlan('UsagePlan', {
name: nameWithStage,
description: 'REST endpoints for <%= lambdaName %>',
apiStages: [
{
stage: lambda.api.deploymentStage,
api: lambda.api,
},
],
});
// create api key
const apiKey = lambda.api.addApiKey(`${app}-key-${this.stage}`, {
apiKeyName: `${app}-key-${this.stage}`,
});
// associate api key to plan
usagePlan.addApiKey(apiKey);
<% } %>
// ---- DNS ---- //
const certificateArn = `arn:aws:acm:eu-west-1:${this.account}:certificate/${props.certificateId}`;
const cfnDomainName = new CfnDomainName(this, 'DomainName', {
domainName: props.domainName,
regionalCertificateArn: certificateArn,
endpointConfiguration: {
types: ['REGIONAL'],
},
});
new CfnBasePathMapping(this, 'BasePathMapping', {
domainName: cfnDomainName.ref,
restApiId: lambda.api.restApiId,
stage: lambda.api.deploymentStage.stageName,
});
new CfnRecordSet(this, 'DNSRecord', {
name: props.domainName,
type: 'CNAME',
hostedZoneId: props.hostedZoneId,
ttl: '120',
resourceRecords: [cfnDomainName.attrRegionalDomainName],
});
}
}