LoginSignup
3
1

More than 1 year has passed since last update.

AWS CDKで既存のacm証明書とroute53のゾーンを使ってカスタムドメインを当てたapigw&lambdaの作成

Last updated at Posted at 2021-09-21

概要/前提

route53ですでに管理している example.com を使って、 api.example.com を割り当てたapiを作成する想定

httpapiなので証明書はapigwと同リージョンに用意されていること

ディレクトリ構造に合わせてhandlerの設定をしているのでそこはよしなに

アプリのソースはpython、cdkのソースはtsで記述

やってることはだいたい以下

  • lambda作成
  • route53のゾーン参照
  • acmの証明書参照
  • apigwのカスタムドメイン登録
  • サブドメインのレコードを参照したゾーンに書き込み
  • apigw作成 & lambda紐付け

環境変数

.env
HOSTED_ZONE_ID=xxxxxxxxxxxxxxxxx
HOSTED_ZONE_NAME=example.com
CERT_ARN=arn:aws:acm:[REGION]:[ID]:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
API_DOMAIN_NAME=api.example.com

ディレクトリ構造

.
├── .env
├── .envrc
├── ...
└── src/
    ├── app/
    │   ├── pyproject.toml
    │   ├── poetry.lock
    │   └── handlers/
    │       └── hoge.py
    └── infra/
        ├── cdk.json
        ├── package.json
        ├── package-lock.json
        ├── tsconfig.json
        ├── bin/
        └── lib/
            └── hoge-stack.ts

CDKソース

lib/hoge-stack.ts
import * as cdk from "@aws-cdk/core";
import { CorsHttpMethod, HttpApi, HttpMethod, DomainName } from "@aws-cdk/aws-apigatewayv2";
import { LambdaProxyIntegration } from "@aws-cdk/aws-apigatewayv2-integrations";
import { Runtime } from "@aws-cdk/aws-lambda";
import { Role, ServicePrincipal, ManagedPolicy } from "@aws-cdk/aws-iam";
import * as path from "path";
import { PythonFunction } from "@aws-cdk/aws-lambda-python";
import { HostedZone, ARecord, RecordTarget } from "@aws-cdk/aws-route53";
import { Certificate } from "@aws-cdk/aws-certificatemanager";
import { ApiGatewayv2DomainProperties } from "@aws-cdk/aws-route53-targets";

export class HogeStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const lambdaExecutionRole = new Role(this, "LambdaExecutionRole", {
      roleName: "LambdaExecutionRole",
      assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
      managedPolicies: [ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")],
    });

    const handler = new PythonFunction(this, "Handler", {
      entry: path.resolve(path.join("", "../app")),
      index: "handlers/hoge.py",
      handler: "handler",
      memorySize: 128,
      runtime: Runtime.PYTHON_3_8,
      timeout: cdk.Duration.seconds(30),
      functionName: "Handler",
      environment: {},
      role: lambdaExecutionRole,
    });

    const integration = new LambdaProxyIntegration({
      handler,
    });

    const hostedZone = HostedZone.fromHostedZoneAttributes(this, "HostedZone", {
      hostedZoneId: process.env.HOSTED_ZONE_ID,
      zoneName: process.env.HOSTED_ZONE_NAME, // ゾーンで管理してるドメイン、e.g.) example.com
    });
    const certificate = Certificate.fromCertificateArn(
      this,
      "Certificate",
      process.env.CERT_ARN // arn:aws:acm:[REGION]:[ID]:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    );

    const domainName = new DomainName(this, "ApiDomainName", {
      domainName: process.env.API_DOMAIN_NAME,
      certificate,
    });

    const aRecord = new ARecord(this, "ARecord", {
      zone: hostedZone,
      recordName: process.env.API_DOMAIN_NAME, // 参照してるゾーンで管理していてこのapiに適用したいドメイン
      target: RecordTarget.fromAlias(
        new ApiGatewayv2DomainProperties(domainName.regionalDomainName, domainName.regionalHostedZoneId)
      ),
    });

    const api = new HttpApi(this, "ApiGateway", {
      defaultDomainMapping: {
        domainName,
      },
      apiName: "HOGEAPI",
      corsPreflight: {
        allowHeaders: ["*"],
        allowOrigins: ["*"],
        allowMethods: [
          CorsHttpMethod.HEAD,
          CorsHttpMethod.OPTIONS,
          CorsHttpMethod.GET,
          CorsHttpMethod.POST,
          CorsHttpMethod.PUT,
          CorsHttpMethod.DELETE,
        ],
      },
    });
    api.addRoutes({
      path: "/hoge",
      methods: [HttpMethod.GET],
      integration,
    });
  }
}

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1