この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
おはようございます。CX事業本部の佐藤です。
AWS CDKでAPI Gatewayのカスタムドメイン環境を作ってみました。
環境
項目 | バージョン |
---|---|
macOS | Mojave 10.14.5 |
node | v10.16.0 |
npm | 6.9.0 |
AWS CDK | 1.15.0 (build bdbe3aa) |
CDKでカスタムドメイン環境を構築する
事前準備
カスタムドメイン環境を構築するには、事前にドメインの取得や証明書の取得が必要です。今回は無料で取得できるドメインで試しました。
ドメインの取得
freenomなどのドメインレジストラで、無料のドメインを取得しDNSの設定をします。弊社の以下のブログが参考になります。
https://dev.classmethod.jp/cloud/aws/mesoko-r53-cdn/
Certificate ManagerでSSL証明書を取得
弊社の以下のブログが参考になります。
https://dev.classmethod.jp/cloud/aws/certificate-manager-dns-validation-support/
パラメータストアにドメイン名と取得した証明書のARNを設定します。
後ほど、CDKから参照して使用するため、設定しておきます。
aws ssm put-parameter --type 'String' --name 'APIG_CUSTOM_DOMAIN_NAME' --value 'www.example.com'
aws ssm put-parameter --type 'String' --name 'APIG_CERTIFICATE_ARN' --value 'arn:aws:XXXX'
CDKでAPI Gatewayを作成する
AWS CDKを使ってインフラを構築していきます。以下、サンプルコードです。
テスト用Lambdaコード
src/lambda/handler/api-gw/test.ts
export async function handler(event: any): Promise<any> {
return 'test api gateway!';
}
CDKのコード
lib/apig-sample-stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apig from '@aws-cdk/aws-apigateway';
import { NODE_LAMBDA_LAYER_DIR } from './process/setup';
import { Certificate } from '@aws-cdk/aws-certificatemanager';
import * as ssm from '@aws-cdk/aws-ssm';
export class ApigSampleStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// パラメータストアからドメイン名と証明書のARNを取得
const ApigCustomDomainName = ssm.StringParameter.fromStringParameterName(this, 'CustomDomainName', 'APIG_CUSTOM_DOMAIN_NAME');
const ApigCertificateArn = ssm.StringParameter.fromStringParameterName(this, 'CertificateArn', 'APIG_CERTIFICATE_ARN');
// Lambda Functionの作成
const testFunction = new lambda.Function(this, 'TestFunction', {
code: lambda.Code.fromAsset('src/lambda/handlers/api-gw'),
functionName: 'testFunction',
handler: 'test.handler',
runtime: lambda.Runtime.NODEJS_10_X,
memorySize: 256,
});
// API Gatewayの作成
const api = new apig.RestApi(this, 'RestApi', {
restApiName: 'test',
// エンドポイントタイプの設定(SSL証明書を東京リージョンで作成したため、REGIONALで作成します。)
endpointTypes: [
apig.EndpointType.REGIONAL
],
// CORSの設定
defaultCorsPreflightOptions: {
allowOrigins: apig.Cors.ALL_ORIGINS,
allowMethods: ['POST', 'OPTIONS'],
statusCode: 200,
},
description: "テスト用"
});
// カスタムドメインの設定
const domainName = new apig.DomainName(this, 'CustomDomain', {
// fromCertificateArnで証明書を取得します
certificate: Certificate.fromCertificateArn(this, 'Certificate', ApigCertificateArn.stringValue),
// パラメータストアに登録したドメイン名を設定します
domainName: ApigCustomDomainName.stringValue,
// REGINALタイプでカスタムドメインを設定します
endpointType: apig.EndpointType.REGIONAL
});
// ベースパスマッピングの設定
// https://www.example.com/v1/がベースパスとなります。
domainName.addBasePathMapping(api, {
basePath: 'v1'
});
// testリソース作成
const testResource = api.root.addResource('test');
// POSTメソッドの作成
testResource.addMethod('POST', new apig.LambdaIntegration(testFunction, {
connectionType: apig.ConnectionType.INTERNET,
// 統合リクエストの設定
requestTemplates: {
'application/json': "$input.json('$')"
},
// 統合レスポンスの設定(CORS)
integrationResponses: [
{
statusCode: '200',
contentHandling: apig.ContentHandling.CONVERT_TO_TEXT,
responseParameters: {
'method.response.header.Access-Control-Allow-Headers': "'Origin,Content-Type,Authorization'",
'method.response.header.Access-Control-Allow-Methods': "'POST,OPTIONS'",
'method.response.header.Access-Control-Allow-Origin': "'*'"
},
responseTemplates: {
'application/json': "$input.json('$')"
}
}
],
passthroughBehavior: apig.PassthroughBehavior.WHEN_NO_MATCH,
proxy: false,
}),
{
// メソッドレスポンスの設定(CORS)
methodResponses: [
{
statusCode: '200',
responseParameters: {
'method.response.header.Access-Control-Allow-Headers': true,
'method.response.header.Access-Control-Allow-Methods': true,
'method.response.header.Access-Control-Allow-Origin': true
}
}
]
}
);
}
}
デプロイ
AWSにデプロイします。
npm run build
cdk deploy
動作確認
デプロイできたら、動作確認をしてみます。PostmanでAPIを呼び出してみます。Lambdaが実行されて、 レスポンスが返ってきています。
まとめ
AWS CDKでカスタムドメイン環境を構築してみました。当初は、CDK + Swaggerの構成を考えていたんですが、CDKのAPI GatewayライブラリがまだSwaggerのインポートに対応していないため、SwaggerはAPI仕様書として別管理とし、現状はCDK単体で構築するのが良いかと思います。誰かの参考になれば幸いです。