証明書もNLBも不要!パブリックサブネットレスなECS Express ModeをAPI Gateway (VPC Link v2) で公開してみた

証明書もNLBも不要!パブリックサブネットレスなECS Express ModeをAPI Gateway (VPC Link v2) で公開してみた

パブリックサブネットレスVPC上のECS Express Mode環境に、API Gateway(REST/HTTP API)からVPC Link v2経由で接続する構成を検証しました。NLB不要でセキュアにインターネット公開が可能です。すぐに試せるCloudFormationテンプレートも掲載しています。
2026.03.03

以前、パブリックサブネットレスなVPCにECS Express Mode環境を構築し、CloudFront VPC Originを利用してインターネット公開する構成を紹介しました。

https://dev.classmethod.jp/articles/ecs-express-mode-public-subnet-less/

この時はCloudFrontを利用しましたが、API Gatewayでも VPC Link v2 を利用することで、パブリックサブネットレスな環境をインターネット公開できます。

2025年11月のアップデートにより、REST APIのプライベート統合でもALBを直接指定できるようになりました。裏側ではVPC Link v2が使われており、REST APIとHTTP APIの両方で同じVPC Linkを共有できます。

https://dev.classmethod.jp/articles/api-gateway-rest-apis-integration-load-balancer/

今回は、パブリックサブネットレスVPC上のECS Express Mode(Internal ALB)に対して、API Gateway REST APIとHTTP APIの両方からVPC Link v2経由で接続し、疎通確認を試みる機会がありましたので紹介します。

従来の v1 との主な違いは以下の通りです。

VPC Link v1 VPC Link v2
API タイプ REST API のみ REST API / HTTP API 両方
ターゲット NLB 必須 ALB, NLB, CLB, プライベート IP
裏側の仕組み PrivateLink(VPCエンドポイントサービス) ENI(サブネットに直接作成)
リソースタイプ AWS::ApiGateway::VpcLink AWS::ApiGatewayV2::VpcLink
料金 有料($0.01/時間 + データ処理料) 無料
未使用時の動作 維持される 60日間未使用で ENI 自動削除

VPC Link v2 自体に追加コストは発生しません。従来 v1 で必要だった NLB も不要です。

コスト項目 v1 構成(従来) v2 構成(今回)
VPC Link $0.01/時間(約 $7.3/月) 無料
NLB 約 $16/月〜(固定費 + LCU) 不要
API Gateway REST API: $3.50/100万req REST API: $3.50/100万req
HTTP API: $1.00/100万req
合計固定費 約 $23/月〜 $0

アーキテクチャ

今回の構成は以下の通りです。

前編との比較:

  • 前編: Client → CloudFront → VPC Origin → Internal ALB → ECS
  • 今回: Client → API Gateway → VPC Link v2 → Internal ALB → ECS

CloudFormation テンプレート解説

3スタック構成で、Export/ImportValue によるスタック間連携を行いました。

cfn/
  01-vpc.yaml              # Stack 1: パブリックサブネットレス VPC
  02-ecs-express.yaml      # Stack 2: ECS Express Mode (Nginx)
  03-apigw-vpclink.yaml    # Stack 3: REST API + HTTP API + VPC Link v2

Stack 1: VPC(01-vpc.yaml)

前編と同じパブリックサブネットレス構成です。プライベートサブネット x3、Regional NAT Gateway、Egress-Only IGW を作成します。

Stack 2: ECS Express Mode(02-ecs-express.yaml)

AWS::ECS::ExpressGatewayService で Nginx コンテナをデプロイしました。今回は Nginx イメージ(public.ecr.aws/nginx/nginx:stable-alpine)を使用しました。

Outputs で以下をエクスポートしています。

  • ServiceEndpoint: ECS Express Mode が自動付与する HTTPS エンドポイント(ap-xxxxx.ecs.region.on.aws
  • LoadBalancerArn: Internal ALB の ARN
  • ListenerArn: ALB リスナーの ARN(HTTP API の統合で使用)

今回、REST API と HTTP API で1つの VPC Link v2 を共有しています。

VpcLinkV2:
  Type: AWS::ApiGatewayV2::VpcLink
  Properties:
    Name: !Sub '${ProjectName}-vpclink'
    SecurityGroupIds:
      - !Ref VpcLinkSecurityGroup
    SubnetIds:
      Fn::Split:
        - ','
        - Fn::ImportValue: !Sub '${VPCStackName}-private-subnets'

HTTP API、REST API ともに、リソースタイプは AWS::ApiGatewayV2::VpcLink です。

REST API の統合設定

RootMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    RestApiId: !Ref RestApi
    ResourceId: !GetAtt RestApi.RootResourceId
    HttpMethod: ANY
    AuthorizationType: NONE
    Integration:
      Type: HTTP_PROXY
      IntegrationHttpMethod: ANY
      ConnectionType: VPC_LINK
      ConnectionId: !Ref VpcLinkV2
      IntegrationTarget:
        Fn::ImportValue: !Sub '${ProjectName}-alb-arn'
      Uri: !Sub
        - 'https://${Endpoint}/'
        - Endpoint:
            Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
      RequestParameters:
        integration.request.header.Host: !Sub
          - "'${Endpoint}'"
          - Endpoint:
              Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'

ポイントは3つです。

  1. IntegrationTarget に ALB ARN を直接指定
  2. ConnectionType: VPC_LINK + ConnectionId で VPC Link v2 を指定
  3. integration.request.header.Host で Host ヘッダーを ServiceEndpoint に上書き

Host ヘッダー上書きが必要な理由

API Gateway はデフォルトで自身のホスト名(xxx.execute-api.region.amazonaws.com)を Host ヘッダーとしてバックエンドに送信します。ECS Express Mode の ALB はホストベースルーティングでサービスを振り分けるため、ServiceEndpoint と一致しない Host ヘッダーではルーティングルールにマッチせず 404 が返ります。

REST API と HTTP API で Host ヘッダーの上書き記法が異なります。

# REST API — RequestParameters で上書き
RequestParameters:
  integration.request.header.Host: "'ap-xxxxx.ecs.region.on.aws'"

# HTTP API — overwrite:header.Host で上書き
RequestParameters:
  overwrite:header.Host: ap-xxxxx.ecs.region.on.aws

なお、Host ヘッダーを .on.aws で上書きするため、バックエンドアプリケーションはクライアントがアクセスした元のドメイン(API Gateway の URL)を Host ヘッダーからは取得できなくなります。リダイレクト URL の生成等で元のドメインが必要な場合は、X-Forwarded-Host ヘッダーの利用を検討してください。

HTTP API の統合設定

HttpApiIntegration:
  Type: AWS::ApiGatewayV2::Integration
  Properties:
    ApiId: !Ref HttpApi
    IntegrationType: HTTP_PROXY
    IntegrationMethod: ANY
    ConnectionType: VPC_LINK
    ConnectionId: !Ref VpcLinkV2
    IntegrationUri:
      Fn::ImportValue: !Sub '${ProjectName}-listener-arn'
    RequestParameters:
      overwrite:header.Host:
        Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
    TlsConfig:
      ServerNameToVerify:
        Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
    PayloadFormatVersion: '1.0'

HTTP API では IntegrationUri に ALB リスナーの ARN を指定しました。TlsConfig.ServerNameToVerify で TLS 検証のホスト名も ServiceEndpoint に合わせています。PayloadFormatVersion1.0 を指定しています。HTTP API のデフォルトは 2.0 ですが、VPC Link 経由の HTTP プロキシ統合では 1.0 が必須です。ルートは $default の1つだけで、AutoDeploy: true のステージを紐づけました。

セキュリティグループについて

VPC Link v2 用の SG を作成しました。ECS Express Mode の ALB SG は AWS が自動管理しており、本検証では追加設定なしで疎通できました。

疎通確認

検証リージョンは ap-northeast-3(大阪)を使用しました。デプロイ後(手順は末尾の参考情報に掲載)、API Gateway のエンドポイントを取得して curl で確認しました。

aws cloudformation describe-stacks \
  --stack-name apigw-vpclink-test-apigw \
  --query 'Stacks[0].Outputs' --output table \
  --region ap-northeast-3

REST API は /test ステージ、HTTP API は $default ステージ(パスなし)でアクセスします。

$ curl -s https://f5s2s3u41l.execute-api.ap-northeast-3.amazonaws.com/test
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
エンドポイント URL ステータス
REST API(ルート) https://f5s2s3u41l.execute-api.ap-northeast-3.amazonaws.com/test 200 OK
HTTP API(ルート) https://4j83booagl.execute-api.ap-northeast-3.amazonaws.com 200 OK

REST API、HTTP API ともに Nginx の Welcome ページが返ってきました。

所見・考察

ECS Express Mode の ALB は HTTPS エンドポイントと証明書が自動付与されるため、VPC Link v2 の HTTPS 必須要件をそのまま満たします。通常の ALB + ECS 構成では自前で証明書管理が必要ですが、ECS Express Mode では省略可能です。

CloudFront と API Gateway の使い分け

ECS Express Mode は CloudFront VPC Origin との組み合わせが一般的ですが、API Gateway の認証・認可や API 管理機能が必要な場合は VPC Link v2 での接続の採用をご検討ください。

  • HTTP API: JWT 認証、Lambda オーソライザー、CORS 自動処理
  • REST API: 上記に加え、API キー + 使用量プラン、WAF 直接統合、リクエスト変換
ECS Express Mode で公開したい
  ├─ API キー管理・使用量プラン・リクエスト変換が必要?
  │    └─ Yes → REST API + VPC Link v2
  ├─ JWT 認証・Lambda オーソライザーが必要?
  │    └─ Yes → HTTP API + VPC Link v2(低コスト)
  ├─ WAF・キャッシュ・地理的制限が必要?
  │    └─ Yes → CloudFront VPC Origin(前編の構成)
  └─ 上記いずれも不要
       └─ CloudFront VPC Origin(ファーストチョイス)

まとめ

パブリックサブネットレス VPC 上の ECS Express Mode 環境に対して、API Gateway REST API と HTTP API の両方から VPC Link v2 経由で接続できることを確認できました。認証・認可など API Gateway の機能を必要とするワークロードで ECS Express Mode を採用する場合、VPC Link v2 をお試しください。

参考情報:

本記事で使用した CloudFormation テンプレートの全文と、デプロイ・撤去手順です。

デプロイ、撤去

デプロイ(約10分)

REGION="ap-northeast-3"
PROFILE="your-profile"
PROJECT="apigw-vpclink-test"

# Stack 1: VPC(約2分)
aws cloudformation deploy \
  --template-file cfn/01-vpc.yaml \
  --stack-name ${PROJECT}-vpc \
  --region ${REGION} --profile ${PROFILE} \
  --no-fail-on-empty-changeset

# Stack 2: ECS Express Mode(約5〜7分)
aws cloudformation deploy \
  --template-file cfn/02-ecs-express.yaml \
  --stack-name ${PROJECT}-ecs \
  --capabilities CAPABILITY_NAMED_IAM \
  --region ${REGION} --profile ${PROFILE} \
  --no-fail-on-empty-changeset

# Stack 3: API Gateway + VPC Link v2(約2〜3分)
aws cloudformation deploy \
  --template-file cfn/03-apigw-vpclink.yaml \
  --stack-name ${PROJECT}-apigw \
  --region ${REGION} --profile ${PROFILE} \
  --no-fail-on-empty-changeset

撤去(逆順)

aws cloudformation delete-stack --stack-name ${PROJECT}-apigw --region ${REGION} --profile ${PROFILE}
aws cloudformation wait stack-delete-complete --stack-name ${PROJECT}-apigw --region ${REGION} --profile ${PROFILE}

aws cloudformation delete-stack --stack-name ${PROJECT}-ecs --region ${REGION} --profile ${PROFILE}
aws cloudformation wait stack-delete-complete --stack-name ${PROJECT}-ecs --region ${REGION} --profile ${PROFILE}

aws cloudformation delete-stack --stack-name ${PROJECT}-vpc --region ${REGION} --profile ${PROFILE}
aws cloudformation wait stack-delete-complete --stack-name ${PROJECT}-vpc --region ${REGION} --profile ${PROFILE}
CloudFormation テンプレート全文

cfn/01-vpc.yaml

<details><summary>クリックで展開</summary>

AWSTemplateFormatVersion: '2010-09-09'
Description: 'パブリックサブネットレスVPC with Regional NAT Gateway'

Parameters:
  ProjectName:
    Type: String
    Default: 'apigw-vpclink-test'

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '192.168.0.0/18'
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Ref ProjectName

  IPv6CidrBlock:
    Type: AWS::EC2::VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AmazonProvidedIpv6CidrBlock: true

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      CidrBlock: '192.168.0.0/20'
      AvailabilityZone: !Select [0, !GetAZs '']
      Ipv6CidrBlock: !Select [0, !Cidr [!Select [0, !GetAtt VPC.Ipv6CidrBlocks], 3, 64]]
      AssignIpv6AddressOnCreation: true
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-private-1a'

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      CidrBlock: '192.168.16.0/20'
      AvailabilityZone: !Select [1, !GetAZs '']
      Ipv6CidrBlock: !Select [1, !Cidr [!Select [0, !GetAtt VPC.Ipv6CidrBlocks], 3, 64]]
      AssignIpv6AddressOnCreation: true
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-private-1c'

  PrivateSubnet3:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      CidrBlock: '192.168.32.0/20'
      AvailabilityZone: !Select [2, !GetAZs '']
      Ipv6CidrBlock: !Select [2, !Cidr [!Select [0, !GetAtt VPC.Ipv6CidrBlocks], 3, 64]]
      AssignIpv6AddressOnCreation: true
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-private-1d'

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-igw'

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  EgressOnlyIGW:
    Type: AWS::EC2::EgressOnlyInternetGateway
    Properties:
      VpcId: !Ref VPC

  NATGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-nat-eip'

  RegionalNATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AvailabilityMode: regional
      ConnectivityType: public
      VpcId: !Ref VPC
      AvailabilityZoneAddresses:
        - AvailabilityZone: !Select [0, !GetAZs '']
          AllocationIds:
            - !GetAtt NATGatewayEIP.AllocationId
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-regional-nat-gw'

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-private-rt'

  PrivateRouteIPv4:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref RegionalNATGateway

  PrivateRouteIPv6:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationIpv6CidrBlock: '::/0'
      EgressOnlyInternetGatewayId: !Ref EgressOnlyIGW

  PrivateSubnet1Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet2Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet3Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet3
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VPCId:
    Value: !Ref VPC
    Export:
      Name: !Sub '${AWS::StackName}-vpc-id'

  PrivateSubnets:
    Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2, !Ref PrivateSubnet3]]
    Export:
      Name: !Sub '${AWS::StackName}-private-subnets'

</details>

cfn/02-ecs-express.yaml

<details><summary>クリックで展開</summary>

AWSTemplateFormatVersion: '2010-09-09'
Description: 'ECS Express Mode Service - Nginx public image'

Parameters:
  ProjectName:
    Type: String
    Default: 'apigw-vpclink-test'

  VPCStackName:
    Type: String
    Default: 'apigw-vpclink-test-vpc'

Resources:
  ECSLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/ecs/default/${ProjectName}-service'
      RetentionInDays: 7

  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${ProjectName}-task-execution-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

  ECSTaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${ProjectName}-task-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole

  ECSInfrastructureRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${ProjectName}-infrastructure-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRoleforExpressGatewayServices

  ExpressModeService:
    Type: AWS::ECS::ExpressGatewayService
    DependsOn: ECSLogGroup
    Properties:
      ServiceName: !Sub '${ProjectName}-service'
      Cluster: 'default'
      ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
      InfrastructureRoleArn: !GetAtt ECSInfrastructureRole.Arn
      TaskRoleArn: !GetAtt ECSTaskRole.Arn
      PrimaryContainer:
        Image: 'public.ecr.aws/nginx/nginx:stable-alpine'
        ContainerPort: 80
        AwsLogsConfiguration:
          LogGroup: !Sub '/aws/ecs/default/${ProjectName}-service'
          LogStreamPrefix: 'ecs'
      NetworkConfiguration:
        Subnets:
          Fn::Split:
            - ','
            - Fn::ImportValue: !Sub '${VPCStackName}-private-subnets'
      Cpu: '256'
      Memory: '512'
      HealthCheckPath: '/'
      ScalingTarget:
        MinTaskCount: 1
        MaxTaskCount: 1
        AutoScalingMetric: 'AVERAGE_CPU'
        AutoScalingTargetValue: 70

Outputs:
  ServiceEndpoint:
    Value: !GetAtt ExpressModeService.Endpoint
    Export:
      Name: !Sub '${ProjectName}-service-endpoint'

  LoadBalancerArn:
    Value: !GetAtt ExpressModeService.ECSManagedResourceArns.IngressPath.LoadBalancerArn
    Export:
      Name: !Sub '${ProjectName}-alb-arn'

  ListenerArn:
    Value: !GetAtt ExpressModeService.ECSManagedResourceArns.IngressPath.ListenerArn
    Export:
      Name: !Sub '${ProjectName}-listener-arn'

</details>

cfn/03-apigw-vpclink.yaml

<details><summary>クリックで展開</summary>

AWSTemplateFormatVersion: '2010-09-09'
Description: 'API Gateway REST API + HTTP API + VPC Link v2 → ECS Express Internal ALB'

Parameters:
  ProjectName:
    Type: String
    Default: 'apigw-vpclink-test'

  VPCStackName:
    Type: String
    Default: 'apigw-vpclink-test-vpc'

  ECSStackName:
    Type: String
    Default: 'apigw-vpclink-test-ecs'

Resources:
  # VPC Link v2 用セキュリティグループ
  VpcLinkSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'Security group for VPC Link v2'
      GroupName: !Sub '${ProjectName}-vpclink-sg'
      VpcId:
        Fn::ImportValue: !Sub '${VPCStackName}-vpc-id'
      Tags:
        - Key: Name
          Value: !Sub '${ProjectName}-vpclink-sg'

  # VPC Link v2
  VpcLinkV2:
    Type: AWS::ApiGatewayV2::VpcLink
    Properties:
      Name: !Sub '${ProjectName}-vpclink'
      SecurityGroupIds:
        - !Ref VpcLinkSecurityGroup
      SubnetIds:
        Fn::Split:
          - ','
          - Fn::ImportValue: !Sub '${VPCStackName}-private-subnets'

  # REST API
  RestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: !Sub '${ProjectName}-api'
      Description: 'REST API with VPC Link v2 to ECS Express Internal ALB'
      EndpointConfiguration:
        Types:
          - REGIONAL

  # /{proxy+} リソース
  ProxyResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref RestApi
      ParentId: !GetAtt RestApi.RootResourceId
      PathPart: '{proxy+}'

  # ルート ANY メソッド
  RootMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      RestApiId: !Ref RestApi
      ResourceId: !GetAtt RestApi.RootResourceId
      HttpMethod: ANY
      AuthorizationType: NONE
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: ANY
        ConnectionType: VPC_LINK
        ConnectionId: !Ref VpcLinkV2
        IntegrationTarget:
          Fn::ImportValue: !Sub '${ProjectName}-alb-arn'
        Uri: !Sub
          - 'https://${Endpoint}/'
          - Endpoint:
              Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
        RequestParameters:
          integration.request.header.Host: !Sub
            - "'${Endpoint}'"
            - Endpoint:
                Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'

  # プロキシ ANY メソッド
  ProxyMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      RestApiId: !Ref RestApi
      ResourceId: !Ref ProxyResource
      HttpMethod: ANY
      AuthorizationType: NONE
      RequestParameters:
        method.request.path.proxy: true
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: ANY
        ConnectionType: VPC_LINK
        ConnectionId: !Ref VpcLinkV2
        IntegrationTarget:
          Fn::ImportValue: !Sub '${ProjectName}-alb-arn'
        Uri: !Sub
          - 'https://${Endpoint}/{proxy}'
          - Endpoint:
              Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
        RequestParameters:
          integration.request.header.Host: !Sub
            - "'${Endpoint}'"
            - Endpoint:
                Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
          integration.request.path.proxy: method.request.path.proxy

  # デプロイ
  Deployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - RootMethod
      - ProxyMethod
    Properties:
      RestApiId: !Ref RestApi

  # ステージ
  Stage:
    Type: AWS::ApiGateway::Stage
    Properties:
      RestApiId: !Ref RestApi
      DeploymentId: !Ref Deployment
      StageName: 'test'

  # ===========================================
  # HTTP API (API Gateway v2)
  # ===========================================

  HttpApi:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: !Sub '${ProjectName}-http-api'
      Description: 'HTTP API with VPC Link v2 to ECS Express Internal ALB'
      ProtocolType: HTTP

  # VPC Link 統合
  HttpApiIntegration:
    Type: AWS::ApiGatewayV2::Integration
    Properties:
      ApiId: !Ref HttpApi
      IntegrationType: HTTP_PROXY
      IntegrationMethod: ANY
      ConnectionType: VPC_LINK
      ConnectionId: !Ref VpcLinkV2
      IntegrationUri:
        Fn::ImportValue: !Sub '${ProjectName}-listener-arn'
      RequestParameters:
        overwrite:header.Host:
          Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
      TlsConfig:
        ServerNameToVerify:
          Fn::ImportValue: !Sub '${ProjectName}-service-endpoint'
      PayloadFormatVersion: '1.0'

  # デフォルトルート
  HttpApiRoute:
    Type: AWS::ApiGatewayV2::Route
    Properties:
      ApiId: !Ref HttpApi
      RouteKey: '$default'
      Target: !Sub 'integrations/${HttpApiIntegration}'

  # ステージ(自動デプロイ)
  HttpApiStage:
    Type: AWS::ApiGatewayV2::Stage
    Properties:
      ApiId: !Ref HttpApi
      StageName: '$default'
      AutoDeploy: true

Outputs:
  RestApiEndpoint:
    Description: 'REST API Invoke URL'
    Value: !Sub 'https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/test'

  HttpApiEndpoint:
    Description: 'HTTP API Invoke URL'
    Value: !Sub 'https://${HttpApi}.execute-api.${AWS::Region}.amazonaws.com'

  VpcLinkId:
    Value: !Ref VpcLinkV2

  RestApiId:
    Value: !Ref RestApi

  HttpApiId:
    Value: !Ref HttpApi

  SecurityGroupId:
    Value: !Ref VpcLinkSecurityGroup

参考リンク

この記事をシェアする

FacebookHatena blogX

関連記事