1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

API Gateway(エッジ最適化とリージョン)にカスタムドメインを設定してみた

Posted at

背景・目的

運用中の API Gateway(エッジ最適化エンドポイント)とリージョンタイプに対して、カスタムドメインを設定してみました。

API Gateway のエンドタイプごとに、証明書の発行リージョンやRoute 53設定など複数の考慮点があります。

今回は、CloudFormation を使ってエッジ最適化とリージョンエンドポイントそれぞれの挙動を確認します。

なお、以前も似たようなことを試してみます。

実践

前提

今回、下記の環境で試しています

  • Route 53のホストゾーンがある
  • Cursor

事前準備

  1. 新規にプロジェクトを作成します

    % gh repo create api-gateway-migration-example --public --clone
    ✓ Created repository XXXX/api-gateway-migration-example on github.com
      https://github.com/XXXX/api-gateway-migration-example
    % 
    
  2. 上記のプロジェクトをCursorのワークスペースに追加します

バックエンドのLambda

  1. Lambdaのテンプレートを作成します
    AWSTemplateFormatVersion: '2010-09-09'
    Description: Shared Lambda (creates minimal IAM role)
    
    Resources:
      LambdaBasicRole:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Principal: { Service: lambda.amazonaws.com }
                Action: sts:AssumeRole
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    
      SharedHelloFn:
        Type: AWS::Lambda::Function
        Properties:
          Runtime: python3.11
          Handler: index.handler
          Role: !GetAtt LambdaBasicRole.Arn
          Code:
            ZipFile: |
              def handler(event, context):
                  return {"statusCode": 200, "body": "Hello from Shared Lambda"}
    
    Outputs:
      SharedLambdaArn:
        Value: !GetAtt SharedHelloFn.Arn
        Export:
          Name: SharedLambdaArn
    
  2. 実行します。できました
    % aws cloudformation deploy \
      --template-file lambda-shared.yaml \
      --stack-name shared-lambda \
      --capabilities CAPABILITY_IAM
    
    
    Waiting for changeset to be created..
    Waiting for stack create/update to complete
    Successfully created/updated stack - shared-lambda
    % 
    

Edge最適化タイプ

まずは、Edge最適化のAPI Gatewayを作成します。下記のような構成を作成します

image.png

ACM証明書の作成

  1. AWSにサインインします

エッジ最適化用(us-east-1)

  1. エッジ最適化のため、us-east-1リージョンに移動します

  2. AWS Certificate Manager に移動します

  3. 「証明書をリクエスト」をクリックします

  4. 「次へ」をクリックします
    image.png

  5. 下記を設定し、「リクエスト」をクリックします

    • FQDN:任意(Route 53のサブドメイン)
    • エクスポートを許可:無効
    • 検証方法:DNS検証
    • キーアルゴリズム:RSA2048
      image.png
  6. 作成後、保留中になります
    image.png

レコードの作成

  1. 上記のACMで作成した証明書の画面で「Route 53でレコードを作成」をクリックします
    image.png

  2. 「レコードを作成」をクリックします
    image.png

  3. Route 53のホストゾーンに登録されました
    image.png

  4. しばらく(5分程度)すると、ステータスが「発行済み」になりました
    image.png

CloudFormationの作成

Edge最適化のREST API、カスタムドメインを作成します

  1. テンプレートを作成します

    Parameters:
      HostedZoneId:
        Type: String
      DomainName:
        Type: String
      EdgeCertArnUsEast1:
        Type: String
      LambdaArn:             # ★ 共有LambdaのARNを受ける
        Type: String
      RecordWeight:
        Type: Number
        Default: 100
    
    Resources:
      Api:
        Type: AWS::ApiGateway::RestApi
        Properties:
          Name: !Sub edge-api-${DomainName}
          EndpointConfiguration: { Types: [EDGE] }
    
      RootGet:
        Type: AWS::ApiGateway::Method
        Properties:
          RestApiId: !Ref Api
          ResourceId: !GetAtt Api.RootResourceId
          HttpMethod: GET
          AuthorizationType: NONE
          Integration:
            Type: AWS_PROXY
            IntegrationHttpMethod: POST
            Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaArn}/invocations
    
      LambdaInvokePermissionForEdgeApi:
        Type: AWS::Lambda::Permission
        Properties:
          FunctionName: !Ref LambdaArn
          Action: lambda:InvokeFunction
          Principal: apigateway.amazonaws.com
          SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${Api}/*/*/*
    
      Deployment:
        Type: AWS::ApiGateway::Deployment
        DependsOn: RootGet
        Properties:
          RestApiId: !Ref Api
          StageName: prod
    
      EdgeDomain:
        Type: AWS::ApiGateway::DomainName
        Properties:
          DomainName: !Ref DomainName
          CertificateArn: !Ref EdgeCertArnUsEast1
          EndpointConfiguration: { Types: [EDGE] }
    
      BasePathMapping:
        Type: AWS::ApiGateway::BasePathMapping
        Properties:
          DomainName: !Ref EdgeDomain
          RestApiId: !Ref Api
          Stage: prod
    
      ApiAliasRecordEdge:
        Type: AWS::Route53::RecordSet
        Properties:
          HostedZoneId: !Ref HostedZoneId
          Name: !Ref DomainName
          Type: A
          SetIdentifier: edge
          Weight: !Ref RecordWeight
          AliasTarget:
            DNSName: !GetAtt EdgeDomain.DistributionDomainName
            HostedZoneId: !GetAtt EdgeDomain.DistributionHostedZoneId
            EvaluateTargetHealth: false
    
    
  2. 実行します。できました

    % aws cloudformation deploy \
     --template-file edge-template.yaml \
     --stack-name edge-api-stack \
     --region ap-northeast-1 \
    --parameter-overrides \
      HostedZoneId=$HOSTED_ZONE_ID \
      DomainName=$DOMAIN_NAME \
      EdgeCertArnUsEast1=$EDGE_CERT_ARN_USEAST1
    
    Waiting for changeset to be created..
    Waiting for stack create/update to complete
    Successfully created/updated stack - edge-api-stack
    
  3. Route 53にAレコードが登録されました(見づらくてすみません)
    image.png

  4. API Gatewayもエッジタイプでできていました。
    image.png

  5. CloudFrontもできていました

    % aws apigateway get-domain-name \
     --region ap-northeast-1 \
    --domain-name XXXXXX         
    {
        "domainName": "XXXXXX",
        "domainNameArn": "arn:aws:apigateway:ap-northeast-1::/domainnames/XXXXXX",
        "certificateArn": "arn:aws:acm:us-east-1:XXXXXX:certificate/XXXXXX",
        "certificateUploadDate": "2025-08-15T22:06:19+09:00",
        "distributionDomainName": "XXXXXX.cloudfront.net",
        "distributionHostedZoneId": "XXXXXX",
        "endpointConfiguration": {
            "types": [
                "EDGE"
            ],
            "ipAddressType": "ipv4"
        },
        "domainNameStatus": "AVAILABLE",
        "securityPolicy": "TLS_1_2",
        "tags": {},
        "routingMode": "BASE_PATH_MAPPING_ONLY"
    }
    % 
    

疎通

  1. リクエストを送ってみます。想定通りのメッセージが返されました
    % curl https://apigw.XXXXXXXXXXXXX
    Hello from Shared Lambda%
    % 
    

リージョンタイプ

次に、リージョンタイプのAPI Gatewayを作成し、並行稼働させます。
下記のような構成を作成し、ドメインを分けてアクセスします
image.png

リージョン用(ap-northeast-1)

  1. リージョン用のため、今回使用するap-northeast-1リージョンに移動します

  2. AWS Certificate Manager に移動します

  3. 「証明書をリクエスト」をクリックします

  4. 「次へ」をクリックします
    image.png

  5. 下記を設定し、「リクエスト」をクリックします

    • FQDN:任意(Route 53のサブドメイン)※ このとき、事前に作成したエッジ最適化とは別のFQDNとします
    • エクスポートを許可:無効
    • 検証方法:DNS検証
    • キーアルゴリズム:RSA2048
      image.png
  6. 作成後、保留中になります

レコードの作成

  1. 上記のACMで作成した証明書の画面で「Route 53でレコードを作成」をクリックします
  2. 「レコードを作成」をクリックします
  3. Route 53のホストゾーンに登録されました
  4. しばらく(5分程度)すると、ステータスが「発行済み」になりました
    image.png

CloudFormationの作成

  1. テンプレートを作成します

    AWSTemplateFormatVersion: '2010-09-09'
    Description: Regional API Gateway using shared Lambda (ImportValue)
    
    Parameters:
      HostedZoneId:
        Type: String
      DomainName:
        Type: String
      RegionalCertArn:
        Type: String
      RecordWeight:
        Type: Number
        Default: 100
    
    Resources:
      Api:
        Type: AWS::ApiGateway::RestApi
        Properties:
          Name: !Sub regional-api-${DomainName}
          EndpointConfiguration:
            Types: [REGIONAL]
    
      RootGet:
        Type: AWS::ApiGateway::Method
        Properties:
          RestApiId: !Ref Api
          ResourceId: !GetAtt Api.RootResourceId
          HttpMethod: GET
          AuthorizationType: NONE
          Integration:
            Type: AWS_PROXY
            IntegrationHttpMethod: POST
            Uri: !Sub
              - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SharedLambdaArn}/invocations
              - { SharedLambdaArn: !ImportValue SharedLambdaArn }
    
      LambdaInvokePermissionForRegionalApi:
        Type: AWS::Lambda::Permission
        Properties:
          FunctionName: !ImportValue SharedLambdaArn
          Action: lambda:InvokeFunction
          Principal: apigateway.amazonaws.com
          SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${Api}/*/*/*
    
      # ← デプロイはステージ名を付けずに作る
      ApiDeployment:
        Type: AWS::ApiGateway::Deployment
        DependsOn: RootGet
        Properties:
          RestApiId: !Ref Api
          Description: Initial deployment
    
      # ← ステージを明示的に作る(prod)
      ApiStage:
        Type: AWS::ApiGateway::Stage
        Properties:
          RestApiId: !Ref Api
          DeploymentId: !Ref ApiDeployment
          StageName: prod
    
      RegionalDomain:
        Type: AWS::ApiGateway::DomainName
        Properties:
          DomainName: !Ref DomainName
          RegionalCertificateArn: !Ref RegionalCertArn
          EndpointConfiguration:
            Types: [REGIONAL]
    
      # ← ステージが完成してからマッピングを作る
      BasePathMapping:
        Type: AWS::ApiGateway::BasePathMapping
        DependsOn:
          - RegionalDomain
          - ApiStage
        Properties:
          DomainName: !Ref RegionalDomain
          RestApiId: !Ref Api
          Stage: prod
    
      ApiAliasRecordRegional:
        Type: AWS::Route53::RecordSet
        DependsOn: RegionalDomain
        Properties:
          HostedZoneId: !Ref HostedZoneId
          Name: !Ref DomainName
          Type: A
          SetIdentifier: regional
          Weight: !Ref RecordWeight
          AliasTarget:
            DNSName: !GetAtt RegionalDomain.RegionalDomainName
            HostedZoneId: !GetAtt RegionalDomain.RegionalHostedZoneId
            EvaluateTargetHealth: false
    
    
  2. 実行します。できました

    % aws cloudformation deploy \
      --region ap-northeast-1 \
      --template-file region-template.yaml \
    --stack-name regional-api-stack \
    --parameter-overrides \
     HostedZoneId=$HOSTED_ZONE_ID \
     DomainName=$REGIONAL_DOMAIN_NAME \
     RegionalCertArn=$REGIONAL_CERT_ARN_APNORTHEAST1
    
    Waiting for changeset to be created..
    Waiting for stack create/update to complete
    Successfully created/updated stack - regional-api-stack
    %
    
  3. Route 53にAレコードが登録されました

  4. API Gatewayに、リージョンタイプが追加されました
    image.png

  5. リクエストを送ってみます。想定通りのメッセージが返されました(ドメインを伏せているのでわからないですね。)

    % curl https://region-apigw.XXXXXXXXXXXXX
    Hello from Shared Lambda%
    % 
    

考察

今回は、API Gatewayのエッジ最適化タイプとリージョンタイプについて、カスタムドメインを使って挙動を確認しました。証明書やDNSレコード、CloudFrontの有無などの関係性について、以前より理解が深まったように思います。

参考

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?