kakakakakku blog

Weekly Tech Blog: Keep on Learning!

AWS CDK で Amazon API Gateway にカスタムドメインを設定する

AWS CDK で Amazon API Gateway に Amazon Route 53 のカスタムドメインを設定してみた💡

実際に試したログをまとめておく \( 'ω')/

サンプルコード

今回は Amazon Route 53 でドメインを取得してある前提とする.サンプルコード上では xxxxx.com にしておく📝

👾 api-gateway-custom-domain.ts

import {
    Stack,
    StackProps,
    aws_apigateway,
    aws_certificatemanager,
    aws_route53,
    aws_route53_targets,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'

export class ApiGatewayCustomDomainStack extends Stack {
    constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props)

        const hostedZone = aws_route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
            hostedZoneId: 'xxxxx',
            zoneName: 'xxxxx.com',
        })

        const certificate = new aws_certificatemanager.Certificate(this, 'Certificate', {
            domainName: 'api.xxxxx.com',
            validation: aws_certificatemanager.CertificateValidation.fromDns(hostedZone),
        })

        const api = new aws_apigateway.RestApi(this, 'ApiGateway', {
            restApiName: 'sandbox-api-gateway-custom-domain',
            domainName: {
                domainName: 'api.xxxxx.com',
                certificate: certificate,
            },
            disableExecuteApiEndpoint: true,
        })

        api.root.addMethod('GET', new aws_apigateway.HttpIntegration('https://dog.ceo/api/breeds/image/random'))

        new aws_route53.ARecord(this, 'ARecod', {
            zone: hostedZone,
            recordName: 'api',
            target: aws_route53.RecordTarget.fromAlias(new aws_route53_targets.ApiGateway(api)),
        })
    }
}

ポイント

AWS Certificate Manager

AWS Certificate Manager で証明書を取得するために aws_certificatemanager.Certificate を使う.そして今回は Amazon Route 53 で取得したドメインを使うため,DNS 検証で使う CNAME レコードも自動的に作ってくれて便利👌 ちなみに aws_certificatemanager.DnsValidatedCertificate は既に Deprecated になっているので注意🚨

docs.aws.amazon.com

Amazon API Gateway

addDomainName() でカスタムドメインの設定を詳細に実装することもできるけど,今回はシンプルに aws_apigateway.RestApidomainName を使った.さらに disableExecuteApiEndpoint も設定しておくと Amazon API Gateway のデフォルトドメインのアクセスを拒否できる👌

docs.aws.amazon.com

Amazon API Gateway にカスタムドメインを設定するときの解説は aws_apigateway モジュールの Overview にも詳しく載っているからあわせて見ておくと良いかと❗️

docs.aws.amazon.com

Amazon Route 53

最後は aws_route53.ARecord を使って Amazon API Gateway に対して A レコード(エイリアスレコード)を設定する.デフォルトだと Apex ドメインになるため,今回は recordName を設定して api サブドメインにした.

docs.aws.amazon.com

デプロイ

さっそく cdk diffcdk deploy を実行する❗️証明書の DNS 検証待ちもあって多少デプロイ時間は長かった.

$ cdk diff ApiGatewayCustomDomainStack

Resources
[+] AWS::CertificateManager::Certificate Certificate Certificate4E7ABB08 
[+] AWS::ApiGateway::RestApi ApiGateway ApiGateway11E7F47B 
[+] AWS::ApiGateway::Deployment ApiGateway/Deployment ApiGatewayDeploymentA26796E824a5989fccba92ddf3192941a8d88d82 
[+] AWS::ApiGateway::Stage ApiGateway/DeploymentStage.prod ApiGatewayDeploymentStageprod1C6D5CD6 
[+] AWS::ApiGateway::DomainName ApiGateway/CustomDomain ApiGatewayCustomDomainDD503C48 
[+] AWS::ApiGateway::BasePathMapping ApiGateway/CustomDomain/Map:--=>ApiGatewayCustomDomainStackApiGateway93CA03C8 ApiGatewayCustomDomainMapApiGatewayCustomDomainStackApiGateway93CA03C8B11D3EE6 
[+] AWS::ApiGateway::Method ApiGateway/Default/GET ApiGatewayGET25EBFEA3 
[+] AWS::Route53::RecordSet ARecod ARecod5038ED2E 

$ cdk deploy ApiGatewayCustomDomainStack

✨  Synthesis time: 2.98s
✨  Deployment time: 88.42s
✨  Total time: 91.4s

動作確認

今回は Amazon API Gateway の「HTTP 統合」を使って Dog API を呼び出すようにしている.実際に試したところ,カスタムドメインで Amazon API Gateway を呼び出すことができた❗️さらにデフォルトドメインだと Forbidden になるのを確認できた.

$ curl -s https://api.xxxxx.com | jq .
{
  "message": "https://images.dog.ceo/breeds/hound-blood/n02088466_9237.jpg",
  "status": "success"
}

$ curl -s https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/ | jq .
{
  "message": "Forbidden"
}

関連ドキュメント

docs.aws.amazon.com

docs.aws.amazon.com