- 1 Amazon EventBridge × VPC Lattice × Fargate — イベント駆動サービス間通信ハンズオン
- 1.1 アーキテクチャ概要
- 1.2 前提条件
- 1.3 構築するリソース一覧
- 1.4 概算コスト
- 1.5 アーキテクチャ構成図
- 1.6 コンソールハンズオン Phase 1: VPC・ネットワーク基盤の準備
- 1.7 コンソールハンズオン Phase 2: Fargate用APIコンテナの準備とECS構築
- 1.8 コンソールハンズオン Phase 3: VPC Lattice 構成
- 1.9 コンソールハンズオン Phase 4: VPC Lattice Resource Gateway 構成
- 1.10 コンソールハンズオン Phase 5: EventBridge 構成
- 1.11 コンソールハンズオン Phase 6: 動作確認
- 1.12 コンソールハンズオン Phase 7: クリーンアップ
- 1.13 TerraformでEventBridge × VPC Lattice × Fargate構成を構築する
- 1.13.1 5-1. ディレクトリ構成
- 1.13.2 5-2. variables.tf — 変数定義
- 1.13.3 5-3. main.tf — Provider設定
- 1.13.4 5-4. vpc.tf — ネットワーク基盤
- 1.13.5 5-5. iam.tf — IAMロール(4種)
- 1.13.6 5-6. ecs.tf — ECS Fargate
- 1.13.7 5-7. lattice.tf — VPC Lattice構成
- 1.13.8 5-8. eventbridge.tf — EventBridge構成
- 1.13.9 5-9. outputs.tf — 出力値
- 1.13.10 5-10. デプロイ手順
- 1.14 まとめ
- 1.15 参考リンク
Amazon EventBridge × VPC Lattice × Fargate — イベント駆動サービス間通信ハンズオン
マイクロサービスアーキテクチャが普及するにつれて、「サービスAのイベントをトリガーに、VPC内のプライベートなサービスBを呼び出したい」というユースケースが増えています。従来はこのパターンを実現するためにALBをインターネット側に公開するか、Lambdaをプロキシに挟む構成が一般的でした。
2024年11月、Amazon EventBridgeはプライベート接続機能を追加しました。EventBridge ConnectionにVPC Lattice Resource Configuration ARNを指定することで、EventBridgeからVPC内のプライベートAPIをインターネットを経由せずに直接呼び出せるようになっています。本記事ではこの新機能とVPC Lattice・ECS Fargateを組み合わせた、セキュアなイベント駆動アーキテクチャの構築手順をコンソール操作とTerraformの両方で解説します。
この記事で学ぶこと
– EventBridgeのAPI DestinationとVPC Lattice Resource Gatewayを連携させる方法
– ECS FargateサービスをVPC LatticeのTarget Groupに自動登録する仕組み
– S3イベントをトリガーにFargate上のプライベートAPIを呼び出す構成
– コンソール手順とTerraform両方での構築方法
アーキテクチャ概要
全体フロー
このハンズオンで構築するシステムは、S3バケットへのファイルアップロードをトリガーに、VPC内のECS Fargateコンテナで動くプライベートAPIを安全に呼び出すイベント駆動アーキテクチャです。
EventBridge Rule
→ API Destination (HTTPS)
→ Connection (Resource Configuration ARN)
→ VPC Lattice Resource Gateway (in VPC)
→ VPC Lattice Service (FQDN)
→ Listener (HTTP:80)
→ Target Group (IP type)
→ ECS Fargate Tasks (HTTP API)
各区間の通信プロトコルと役割:
| 区間 | プロトコル | 説明 |
|---|---|---|
| Rule → API Destination | HTTPS | EventBridgeがAPI Destinationに対してHTTPS呼び出しを行う |
| API Destination ↔ Connection | — | ConnectionがAPI Destinationに認証情報・プライベート接続設定を提供 |
| Connection → Resource Gateway | HTTPS / TCP | Resource Configuration ARNを経由してVPC内Resource Gatewayに到達 |
| Resource Gateway → VPC Lattice Service | HTTP | VPC内でHTTPルーティング(Resource Gatewayが終端) |
| Listener → Target Group | HTTP:80 | FargateタスクのIPへ転送 |

各コンポーネントの役割
Amazon EventBridge
EventBridge Event Bus
S3からのイベントを受信するイベントバスです。S3バケットに対して「EventBridgeへの通知」を有効化すると、PutObject等のイベントがJSONペイロードとして送られてきます。カスタムイベントバスを使用することも、デフォルトイベントバスをそのまま使うこともできます。
EventBridge Rule
イベントパターンに一致するイベントをフィルタリングし、API Destinationに転送します。本ハンズオンでは以下のパターンで特定のS3バケットへのオブジェクト作成イベントのみをキャッチします。
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {"name": ["demo-event-bucket"]}
}
}
EventBridge Connection
API Destinationに対する認証情報とプライベート接続設定を保持します。invocation_connectivity_parametersにresource_configuration_arnを指定することで、EventBridgeがResource Gateway経由でVPC内のAPIを呼び出せるようになります。認証方式はAPI_KEY / BASIC / OAUTHのいずれかを選択します(本ハンズオンではAPI_KEY)。
EventBridge API Destination
VPC Lattice Service FQDNをエンドポイントとして定義します。connection_arnにConnectionを紐付け、HTTPメソッド(POST)・呼び出しレート制限(10 req/sec)を設定します。
VPC Lattice
Service Network
サービスとVPCを論理的にグループ化するネットワーク基盤です。VPCをService Networkに関連付けることで、そのVPC内のリソースからService Network内のサービスにアクセスできるようになります。1つのService Networkに最大500のサービスを登録可能です。
Service
Fargate APIへのルーティングを提供するサービスエンティティです。作成時に一意のFQDN({service-id}.{region}.vpc-lattice-svcs.{region}.on.aws形式)が自動生成されます。このFQDNをEventBridge API Destinationのエンドポイントとして使用します。
Listener
HTTP:80でインバウンドリクエストを受け付け、Target Groupに転送するルールを定義します。デフォルトアクションとして「Target Groupへ転送」を設定します。
Target Group (IP type)
ECS Fargateタスクのプライベートサブネット内IPアドレスをターゲットとして管理します。type: IPを指定し、ポート80・プロトコルHTTP・VPC IDを設定します。ECS Serviceのvpc_lattice_configurationsを設定することで、タスクの起動・終了に合わせて自動的に登録・解除が行われます。
Resource Gateway
VPC内に配置されるネットワークエントリーポイントです。EventBridgeからResource Configuration経由で送られてくる通信を受け入れ、VPC内のリソースに転送します。プライベートサブネットに配置し、セキュリティグループでポート443(EventBridgeからの接続用)のインバウンドを許可します。
Resource Configuration
リソースの識別情報(ドメイン名またはIP)と接続方法(プロトコル・ポート)を定義します。EventBridge ConnectionからARNで参照されることで、EventBridgeがどのリソースに接続するかを指定します。type: SINGLE、protocol: TCP、port_ranges: [80]が基本設定です。
ECS Fargate
本ハンズオンでは、/processエンドポイントでHTTP POSTリクエストを受け付け、リクエストボディをCloudWatch Logsに出力するシンプルなFlask(またはNode.js Express)APIをFargateで動かします。
ECS Serviceにvpc_lattice_configurationsを設定すると、ECS Infrastructure Role経由でVPC Lattice Target Groupへの自動登録が行われます。この設定により、以下が自動化されます。
- タスク起動時: タスクのプライベートIPがTarget Groupに登録される
- タスク終了時: ターゲット登録が自動解除される
- スケールアウト時: 追加されたタスク分のIPが追加登録される
このアーキテクチャが解決すること
3つの課題を解決するアーキテクチャ
1. プライベートVPC内APIをインターネット公開せずEventBridgeから呼び出せる
Resource Gateway経由のプライベート接続により、FargateのAPIをインターネットに公開する必要がなくなります。パブリックIPもALBも不要です。セキュリティグループで通信経路を厳格に制御できます。
2. ECSタスクのスケールイン/アウトに応じてTarget Groupが自動更新vpc_lattice_configurationsにより、Fargateタスクの起動・終了と連動してTarget Groupのメンバーシップが自動管理されます。手動でのターゲット登録・解除が不要です。
3. VPC Latticeでサービス間通信を一元管理
Service NetworkにVPCとサービスを関連付けることで、サービスメッシュとして機能します。クロスアカウント・クロスVPCのサービス間通信も同一インターフェースで管理可能です。
前提条件
このハンズオンを始める前に以下を確認してください
– AWSアカウント: ECS / VPC Lattice / EventBridge / S3 / IAMの操作権限が必要です
– AWS CLI v2: インストール・設定済み(aws configureでリージョン・認証情報設定済み)
– Docker: ローカル環境にインストール済み(Fargateコンテナイメージのビルド・ECR push用)
– Terraform >= 1.3: Terraformセクションを使用する場合に必要
– 対象リージョン: ap-northeast-1(東京)
VPC Lattice Resource Gatewayはap-northeast-1を含む主要リージョンで利用可能です。EventBridgeとのプライベート接続機能は2024年11月リリース。使用前にリージョンのサービス提供状況を確認してください。
構築するリソース一覧
このハンズオンで作成するAWSリソースの全体像です。手順を始める前に全体像を把握しておくと、各ステップの目的が理解しやすくなります。
| リソース | サービス | 役割 |
|---|---|---|
| ECSクラスター / タスク定義 / サービス | Amazon ECS | HTTP APIホスト(Fargate) |
| VPC Lattice Target Group (IP) | VPC Lattice | ECSタスク自動登録先 |
| VPC Lattice Listener / Service | VPC Lattice | APIへのルーティング |
| VPC Lattice Service Network | VPC Lattice | サービスメッシュ基盤・VPC関連付け |
| VPC Lattice Resource Gateway | VPC Lattice | EventBridgeからのプライベート接続入口 |
| VPC Lattice Resource Configuration | VPC Lattice | リソース接続定義(ポート/プロトコル) |
| EventBridge Connection | EventBridge | Resource Configuration経由のプライベート接続設定 |
| EventBridge API Destination | EventBridge | Fargate APIのHTTPSエンドポイント定義 |
| EventBridge Rule + Target | EventBridge | S3イベント → API Destinationへのルーティング |
| S3バケット | S3 | イベントソース(PutObjectでEventBridge発火) |
| VPC / サブネット / NAT Gateway | VPC | ネットワーク基盤(プライベート × 2、パブリック × 2) |
| IAMロール(4種) | IAM | ECS実行・タスク・VPC Lattice統合・EventBridge呼び出し |
概算コスト
ハンズオン規模でのコスト目安
| サービス | 課金項目 | 単価 |
|———|———|—–|
| VPC Lattice | データ処理料金 | $0.025/GB |
| VPC Lattice | リクエスト料金 | $0.10/100万リクエスト |
| Resource Gateway | 時間課金 + データ処理課金 | PrivateLink料金に準ずる($0.01/時間程度) |
| EventBridge | API Destination呼び出し | $1.00/100万回 |
| Fargate | vCPU時間 | $0.04048/vCPU時間 |
| Fargate | メモリ時間 | $0.004445/GB時間 |
ハンズオン規模(数時間・数十リクエスト)であれば無料枠内または数十円程度の見込みです。
ただし、Resource GatewayはPrivateLinkに準ずる時間課金が発生するため、使用後は必ずクリーンアップを実施してください。Terraform使用時はterraform destroyで一括削除できます。
アーキテクチャ構成図

図1: EventBridge × VPC Lattice × Fargate 全体アーキテクチャ

図2: VPCネットワーク詳細構成

図3: EventBridgeイベント駆動フロー
コンソールハンズオン Phase 1: VPC・ネットワーク基盤の準備
ECS Fargateのコンテナと、VPC Lattice Resource Gatewayを配置するためのVPCネットワークを構築します。プライベートサブネットにアプリケーションを配置し、NAT Gatewayを経由してECRからコンテナイメージをpullできる構成にします。
1-1. VPCの作成
- AWSマネジメントコンソールにログインし、VPC サービスを開きます
- 左メニューから 「Your VPCs」 → 「Create VPC」 をクリック
- 以下の設定を入力します
| 項目 | 値 |
|---|---|
| Name tag | eventbridge-lattice-vpc |
| IPv4 CIDR block | 10.0.0.0/16 |
| IPv6 CIDR block | No IPv6 CIDR block |
| Tenancy | Default |
- 「Create VPC」 をクリックして作成
1-2. サブネットの作成
プライベートサブネット(×2、異なるAZ)
- 左メニューから 「Subnets」 → 「Create subnet」 をクリック
- VPC ID に先ほど作成した
eventbridge-lattice-vpcを選択 - 以下の2つのサブネットを同じ画面で追加します(「Add new subnet」で追加)
| Name | AZ | IPv4 CIDR |
|---|---|---|
private-subnet-a | ap-northeast-1a | 10.0.1.0/24 |
private-subnet-c | ap-northeast-1c | 10.0.2.0/24 |
「Auto-assign public IPv4 address」 は 無効(デフォルト) のままにします
「Create subnet」 をクリック
パブリックサブネット(×2、NAT Gateway配置用)
同様の手順で以下のサブネットを作成します。
| Name | AZ | IPv4 CIDR |
|---|---|---|
public-subnet-a | ap-northeast-1a | 10.0.101.0/24 |
public-subnet-c | ap-northeast-1c | 10.0.102.0/24 |
- 「Auto-assign public IPv4 address」 → 「Enable」 にチェックを入れます
1-3. Internet Gatewayの作成・VPCへのアタッチ
- 左メニューから 「Internet Gateways」 → 「Create internet gateway」 をクリック
- Name tag:
eventbridge-lattice-igwと入力して 「Create internet gateway」 - 作成後、「Actions」 → 「Attach to VPC」 をクリック
eventbridge-lattice-vpcを選択して 「Attach internet gateway」
1-4. NAT Gatewayの作成
NAT GatewayはプライベートサブネットのFargateタスクがECRからイメージをpullするために必要です。
- 左メニューから 「NAT Gateways」 → 「Create NAT gateway」 をクリック
- 以下の設定を入力します
| 項目 | 値 |
|---|---|
| Name | eventbridge-lattice-nat-a |
| Subnet | public-subnet-a |
| Connectivity type | Public |
| Elastic IP allocation ID | 「Allocate Elastic IP」 をクリックして新規取得 |
- 「Create NAT gateway」 をクリック
NAT GatewayはEIPの確保時点から時間課金(約$0.062/時間)が発生します。ハンズオン終了後はNAT Gatewayを削除し、EIPも解放してください。
1-5. ルートテーブルの設定
パブリックサブネット用ルートテーブル
- 左メニューから 「Route Tables」 → 「Create route table」
- Name:
public-rtb、VPC:eventbridge-lattice-vpcを選択して作成 - 作成したルートテーブルを選択 → 「Routes」 タブ → 「Edit routes」
- 「Add route」 をクリックし以下を追加
| Destination | Target |
|---|---|
0.0.0.0/0 | Internet Gateway (eventbridge-lattice-igw) |
- 「Save changes」 → 「Subnet associations」 タブ → 「Edit subnet associations」
public-subnet-a、public-subnet-cを選択して 「Save associations」
プライベートサブネット用ルートテーブル
- 同様に 「Create route table」 でルートテーブルを作成
- Name:
private-rtb、VPC:eventbridge-lattice-vpc - 「Routes」 → 「Edit routes」 → 「Add route」
| Destination | Target |
|---|---|
0.0.0.0/0 | NAT Gateway (eventbridge-lattice-nat-a) |
- 「Subnet associations」 で
private-subnet-a、private-subnet-cを関連付け
1-6. セキュリティグループの作成
ECS Fargateコンテナと、VPC Lattice Resource Gatewayのそれぞれに専用のセキュリティグループを作成します。
sg-fargate(ECS Fargateコンテナ用)
- 左メニューから 「Security Groups」 → 「Create security group」
- 以下の設定を入力します
| 項目 | 値 |
|---|---|
| Security group name | sg-fargate |
| Description | ECS Fargate container SG |
| VPC | eventbridge-lattice-vpc |
- Inbound rules に以下を追加
| Type | Protocol | Port range | Source |
|---|---|---|---|
| Custom TCP | TCP | 80 | Custom — sg-lattice-rg のSG ID(後で設定) |
- Outbound rules はデフォルト(全トラフィック許可)のまま
- 「Create security group」
sg-lattice-rg(VPC Lattice Resource Gateway用)
- 同様に 「Create security group」
| 項目 | 値 |
|---|---|
| Security group name | sg-lattice-rg |
| Description | VPC Lattice Resource Gateway SG |
| VPC | eventbridge-lattice-vpc |
- Inbound rules
| Type | Protocol | Port range | Source |
|---|---|---|---|
| HTTPS | TCP | 443 | Anywhere-IPv4 (0.0.0.0/0) |
- Outbound rules
| Type | Protocol | Port range | Destination |
|---|---|---|---|
| Custom TCP | TCP | 80 | Custom — sg-fargate のSG ID |
- 「Create security group」
作成後、sg-fargate のインバウンドルールに戻り、ソースを sg-lattice-rg のSG IDに更新してください(「Edit inbound rules」 → ソースにSG IDを入力)。
sg-fargate のインバウンドは sg-lattice-rg からのTCP:80のみ許可します。これにより、Resource Gateway経由でのみFargateコンテナへのアクセスを許可し、直接アクセスを防ぎます。AWS公式ドキュメントでは、VPC Latticeのヘルスチェックが正常に動作するよう、
Fargate SGのインバウンドに
com.amazonaws.ap-northeast-1.vpc-latticeマネージドプレフィックスリストも追加することが推奨されています。
「Edit inbound rules」→ 「Add rule」→ Type: Custom TCP, Port: 80,
Source: Prefix list で
vpc-lattice を検索して選択してください。コンソールハンズオン Phase 2: Fargate用APIコンテナの準備とECS構築
2-1. サンプルAPIアプリケーションの準備
EventBridgeからのイベントを受け取るシンプルなFlask APIを作成します。以下のファイルをローカル環境に用意してください。
# app.py
from flask import Flask, request, jsonify
import logging, json
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/process', methods=['POST'])
def process():
body = request.get_json(silent=True) or {}
app.logger.info(f"Received event: {json.dumps(body)}")
return jsonify({"status": "ok", "received": body}), 200
@app.route('/health', methods=['GET'])
def health():
return jsonify({"status": "healthy"}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
RUN pip install flask gunicorn
COPY app.py .
EXPOSE 80
CMD ["gunicorn", "-b", "0.0.0.0:80", "app:app"]
ECRリポジトリの作成とDockerイメージのpush
- AWSマネジメントコンソールで 「Elastic Container Registry」 を開く
- 「Create repository」 をクリック
- Repository name:
eventbridge-lattice-api、Visibility: Private で作成
コンテナイメージのビルドとpushはCLIで実行します。
# ECRリポジトリ作成(CLIで行う場合)
aws ecr create-repository --repository-name eventbridge-lattice-api --region ap-northeast-1
# Docker ログイン
aws ecr get-login-password --region ap-northeast-1 | \
docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com
# ビルド & プッシュ
docker build -t eventbridge-lattice-api .
docker tag eventbridge-lattice-api:latest \
<ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/eventbridge-lattice-api:latest
docker push <ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/eventbridge-lattice-api:latest
<ACCOUNT_ID> は自身のAWSアカウントIDに置き換えてください。ECRコンソールの 「View push commands」 ボタンからも同様のコマンドが確認できます。
2-2. ECSタスク実行ロールの作成
ECSがECRからイメージをpullし、CloudWatch Logsにログを書き込むためのIAMロールを作成します。
- AWSマネジメントコンソールで 「IAM」 → 「Roles」 → 「Create role」 をクリック
- 「Trusted entity type」: AWS service → 「Elastic Container Service」
- 「Use case」: 「Elastic Container Service Task」 を選択 → 「Next」
- Permissions policies で以下を検索して追加
| ポリシー名 |
|---|
AmazonECSTaskExecutionRolePolicy |
- Role name:
ecsTaskExecutionRole→ 「Create role」
2-3. ECSクラスターの作成
- AWSマネジメントコンソールで 「Elastic Container Service」 を開く
- 左メニューから 「Clusters」 → 「Create cluster」
- 以下の設定を入力
| 項目 | 値 |
|---|---|
| Cluster name | eventbridge-lattice-cluster |
| Infrastructure | AWS Fargate (serverless) |
- 「Create」 をクリック
2-4. ECSタスク定義の作成
- 左メニューから 「Task definitions」 → 「Create new task definition」
- Task definition family:
eventbridge-lattice-api - Launch type: FARGATE
- Operating system/Architecture: Linux/X86_64
- CPU:
0.25 vCPU(256)、Memory:0.5 GB(512) - Task execution role:
ecsTaskExecutionRole
コンテナの設定
「Add container」 で以下を設定します。
| 項目 | 値 |
|---|---|
| Name | api |
| Image URI | <ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/eventbridge-lattice-api:latest |
| Container port | 80 / Protocol: TCP |
| Port name | api-port |
Log collection セクション:
– 「Use log collection」 を有効化
– Log driver: awslogs
– Log group: /ecs/eventbridge-lattice-api(自動作成される)
– Region: ap-northeast-1
– Stream prefix: ecs
- 「Create」 をクリック
2-5. ECSサービスの作成(初回・VPC Lattice設定前)
この時点ではVPC Lattice統合なしでECSサービスを作成します。VPC Lattice連携(vpc_lattice_configurationsの設定)はPhase 3で行います。
- 「Clusters」 →
eventbridge-lattice-clusterを選択 → 「Services」 タブ → 「Create」 - 以下の設定を入力します
| 項目 | 値 |
|---|---|
| Launch type | FARGATE |
| Task definition | eventbridge-lattice-api(最新リビジョン) |
| Service name | eventbridge-lattice-api-svc |
| Desired tasks | 2 |
- 「Networking」 セクション
| 項目 | 値 |
|---|---|
| VPC | eventbridge-lattice-vpc |
| Subnets | private-subnet-a、private-subnet-c を選択 |
| Security groups | sg-fargate を選択(デフォルトは削除) |
| Public IP | TURNED OFF(プライベートサブネットのため) |
- Load balancing は 「None」 のまま(ALBは使用しない)
- 「Create」 をクリック
ECSサービスの「VPC Lattice configurations」はサービス作成後に更新で追加できます。Phase 3でVPC LatticeのTarget Groupを作成してから、ECSサービスを更新して統合を設定します。今の時点では省略してOKです。
しばらく待つと、ECSサービスが 2/2 tasks running の状態になります。このタスクはプライベートサブネット内で起動しており、NAT Gateway経由でECRからイメージをpullしています。ALBがないためこの時点では外部からの疎通確認はできません。動作確認はPhase 6で、VPC Lattice経由で実施します。
コンソールハンズオン Phase 3: VPC Lattice 構成
このPhaseでは、ECS Fargateサービスへのトラフィックをルーティングする VPC Lattice のコンポーネント(Target Group・Service・Listener・Service Network)を作成し、ECSサービスと統合します。完了後、VPC Lattice Service の一意なFQDNが払い出され、EventBridgeからの呼び出しが可能になる準備が整います。
| ステップ | 内容 |
|---|---|
| 3-1 | VPC Lattice Service 作成(FQDN払い出し) |
| 3-2 | VPC Lattice Service Network 作成 |
| 3-3 | Service Network ↔ Service 関連付け |
| 3-4 | Service Network ↔ VPC 関連付け |
| 3-5 | ECSサービス更新: VPC Lattice有効化 → Target Group自動作成 |
| 3-6 | VPC Lattice Listener 作成(HTTP:80) |
| 3-7 | Target Group のターゲット登録確認 |
3-1. VPC Lattice Service 作成
VPC Lattice Service は、ルーティングのエントリーポイントとなるコンポーネントです。作成時に一意のFQDNが自動生成され、EventBridgeのAPI Destinationの呼び出し先として使用します。
AWSコンソール → VPC → 左ペイン「VPC Lattice」→「Services」→「Create service」
基本設定
| 項目 | 設定値 |
|---|---|
| Name | eventbridge-lattice-service |
| Auth type | None(デモ用。本番環境ではAWS IAMを推奨) |
Custom domain name: 設定しない(デフォルトのまま)
Monitoring: デフォルトのまま(CloudWatch メトリクスは自動有効化)
「Next」→ Listener 設定画面はスキップし(3-6で別途追加)、「Create service」をクリック。
作成完了後、サービス詳細画面の「Summary」タブで FQDN を確認・コピーしてください。
形式: {service-id}.{hash}.vpc-lattice-svcs.ap-northeast-1.on.aws
例: svc-01abc23def456789.abc123def456.vpc-lattice-svcs.ap-northeast-1.on.aws
この FQDN は後続の Phase 4(Resource Configuration)および Phase 5(EventBridge API Destination)で使用します。メモ帳やターミナルに貼り付けておいてください。
3-2. VPC Lattice Service Network 作成
Service Network は、複数のサービスとVPCを論理的にグループ化する仮想ネットワークです。Service Network にサービスとVPCを関連付けることで、そのVPC内のリソース(ECSタスク、Lambda等)からサービスへのアクセスが可能になります。
AWSコンソール → VPC → 左ペイン「VPC Lattice」→「Service networks」→「Create service network」
| 項目 | 設定値 |
|---|---|
| Name | eventbridge-lattice-sn |
| Auth policy | None(デモ用。本番環境ではAWS IAMを推奨) |
「Create service network」をクリック。
3-3. Service Network ↔ Service 関連付け
作成した Service Network に、3-1で作成したサービスを関連付けます。
VPC Lattice コンソール → 「Service networks」→「eventbridge-lattice-sn」をクリック → 「Services」タブ → 「Associate services」
| 項目 | 設定値 |
|---|---|
| Service | eventbridge-lattice-service(リストから選択) |
「Associate」をクリック。
ステータスが「Active」になるまで数秒〜1分ほど待ちます。
3-4. Service Network ↔ VPC 関連付け
VPC を Service Network に関連付けることで、VPC 内のリソースから VPC Lattice サービスへのアクセスが可能になります。セキュリティグループによりアクセス範囲を制御します。
VPC Lattice コンソール → 「Service networks」→「eventbridge-lattice-sn」→「VPC associations」タブ → 「Associate VPC」
| 項目 | 設定値 |
|---|---|
| VPC | Phase 1 で作成した VPC を選択 |
| Security groups | Phase 1 で作成した sg-lattice-vpc-assoc(またはLattice用SG)を選択 |
「Associate」をクリック。
VPC関連付けに指定するセキュリティグループは、VPC内からVPC Lattice Serviceへのアクセスを制御します。Resource Gateway からのトラフィックはVPC内経由で送られるため、ECSタスクやResource GatewayのSGからHTTP(ポート80)のインバウンドを適切に許可してください。
最小限の設定例:インバウンドでECS FargateのSGからポート80を許可、アウトバウンドはすべて許可。
3-5. ECSサービス更新: VPC Lattice有効化とTarget Group自動作成
ECSサービスに VPC Lattice Configurations を追加することで、タスク起動時にプライベートIPアドレスが自動的にTarget Groupに登録されます。この設定にはECS Infrastructure Role(専用IAMロール)が必要です。
事前準備: ECS Infrastructure Role の作成
AWSコンソール → IAM → 「ロール」→「ロールを作成」
ステップ 1: 信頼されたエンティティの選択
| 項目 | 設定値 |
|---|---|
| 信頼されたエンティティタイプ | AWS のサービス |
| サービス | Elastic Container Service |
| ユースケース | Elastic Container Service |
「次へ」をクリック。
ステップ 2: 許可ポリシーの追加
検索ボックスに「vpc-lattice」と入力→「インラインポリシーを作成」を選択し、以下のJSONを入力:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"vpc-lattice:RegisterTargets",
"vpc-lattice:DeregisterTargets",
"vpc-lattice:GetTargetGroup"
],
"Resource": "*"
}
]
}
ポリシー名: ECSVpcLatticeIntegrationPolicy
「次へ」→ ロール名: ecsInfrastructureRole → 「ロールを作成」
このロールは ECS コントロールプレーンが使用します。ECSサービスのvpc_lattice_configurations設定により、タスクの起動・停止イベントに連動して VPC Lattice Target Group へのRegisterTargets/DeregisterTargets API を自動的に呼び出します。タスクロールやタスク実行ロールとは別物です。
ECSサービスの更新
AWSコンソール → Amazon ECS → 「クラスター」→ Phase 2 で作成したクラスター(例: eventbridge-lattice-cluster)→ 「Services」タブ → eventbridge-lattice-service → 「更新」
「VPC Lattice integration」セクションまでスクロールし、「Turn on VPC Lattice」を有効化してください。
| 項目 | 設定値 |
|---|---|
| Infrastructure role | ecsInfrastructureRole(作成したロールを選択) |
| Target group name | eventbridge-lattice-tg(ECSが自動作成する名前を入力) |
| Port name | api-port(タスク定義の portMappings.name と一致させる) |
| Protocol | HTTP |
| Port | 80 |
「更新」をクリック → ECSが VPC Lattice Target Group eventbridge-lattice-tg を自動作成します。
VPC Latticeコンソールで事前にTarget Groupを独立作成しても、ECSコンソールの「VPC Lattice integration」画面では既存のTarget Groupを選択できません。ECSコンソールは新しいTarget Group名を入力してECSに自動作成させる仕様です。
Target group name に作成したいTG名を入力すると、ECSがVPC Lattice APIを使って自動的にIPタイプのTarget Groupを作成します。
ECSサービスの更新が完了すると、新しいタスクが起動し始めます。タスクが起動するまで数分かかります。
ヘルスチェック設定(path: /health, interval: 30秒)はTarget Group自動作成後にVPC Latticeコンソールで確認・調整してください。
3-6. VPC Lattice Listener 作成
Listener は、Service に到着したリクエストをどのTarget Groupに転送するかを定義します。HTTP:80 で受け付け、3-5でECSが自動作成した Target Group に転送するルールを設定します。
VPC Lattice コンソール → 「Services」→「eventbridge-lattice-service」をクリック → 「Listeners」タブ → 「Add listener」
| 項目 | 設定値 |
|---|---|
| Protocol | HTTP |
| Port | 80 |
| Default action | Forward to target group |
| Target group | eventbridge-lattice-tg(ドロップダウンから選択) |
| Weight | 100(デフォルト) |
「Save changes」をクリック。
3-7. Target Group のターゲット登録確認
ECSタスクが起動した後、Target Group にタスクのプライベートIPが自動登録されていることを確認します。
VPC Lattice コンソール → 「Target groups」→「eventbridge-lattice-tg」→「Targets」タブ
| 確認項目 | 期待値 |
|---|---|
| ターゲット(IPアドレス) | ECSタスクのプライベートIP(例: 10.0.x.x)が表示される |
| ポート | 80 |
| ステータス | Healthy |
ECSタスクが起動してからTarget GroupのステータスがHealthyになるまで、ヘルスチェック設定(インターバル30秒 × Healthy threshold 3回)の関係で 最大1〜2分 かかります。しばらく待ってからページを更新してください。
もしUnhealthyが続く場合は、FargateタスクのSGがポート80のインバウンドを許可しているか、アプリが /health エンドポイントで200を返しているかを確認してください。
VPC Lattice Service FQDN の最終確認
VPC Lattice コンソール → 「Services」→「eventbridge-lattice-service」→「Summary」タブ → 「DNS name」の値をメモ
これで Phase 3 が完了です。ECS Fargate タスクが VPC Lattice 経由でアクセス可能な状態になりました。
コンソールハンズオン Phase 4: VPC Lattice Resource Gateway 構成
このPhaseでは、EventBridgeがプライベートVPC内のAPI(VPC Lattice Service)へアクセスするための入口となる Resource Gateway と Resource Configuration を作成します。
EventBridge Connection は Resource Configuration の ARN を参照することで、パブリックインターネットを経由せずに VPC Lattice Service FQDN を呼び出せるようになります。
| ステップ | 内容 |
|---|---|
| 4-1 | Resource Gateway 作成(VPCへのエントリーポイント) |
| 4-2 | Resource Configuration 作成(VPC Lattice Service FQDN を登録) |
4-1. Resource Gateway 作成
Resource Gateway は VPC 内に配置されるネットワークエンドポイントで、EventBridge からの HTTPS トラフィックを受け入れます。プライベートサブネットに配置することで、インターネットから直接アクセスできない安全な構成になります。
AWSコンソール → VPC → 左ペイン「VPC Lattice」→「Resource gateways」→「Create resource gateway」
| 項目 | 設定値 |
|---|---|
| Name | eventbridge-lattice-rg |
| VPC | Phase 1 で作成した VPC を選択 |
| Subnets | プライベートサブネット × 2(AZ-a, AZ-c)を選択 |
| Security groups | sg-lattice-rg(Phase 1 で作成したResource Gateway用SG)を選択 |
| IP address type | IPv4 |
「Create resource gateway」をクリック。
作成には数分かかります。ステータスが「Active」になるまで待ちます。
Resource Gateway は VPC 内のプライベートサブネットに配置されます。
EventBridge は、Resource Configuration ARN を介してこの Resource Gateway に HTTPS(ポート443)でアクセスし、Resource Gateway が VPC 内の VPC Lattice Service FQDN(HTTP:80)にプロキシします。
セキュリティグループ sg-lattice-rg では、EventBridge(AWSサービス)からのポート443インバウンドと、VPC Lattice ServiceへのHTTP(ポート80)アウトバウンドを許可しておく必要があります。
sg-lattice-rg のインバウンドルール(最小構成)
| タイプ | プロトコル | ポート | ソース |
|---|---|---|---|
| HTTPS | TCP | 443 | 0.0.0.0/0(EventBridgeマネージドプレフィックスリストが理想) |
sg-lattice-rg のアウトバウンドルール
| タイプ | プロトコル | ポート | 送信先 |
|---|---|---|---|
| HTTP | TCP | 80 | FargateのSG(sg-fargate) |
EventBridge → Resource Gateway の通信は HTTPS(ポート443)です。Resource Gateway はTLSを終端し、VPC Lattice Service へはHTTP(ポート80)で転送します。
そのため、Resource GatewayのSGのインバウンドはポート443、Fargate側SGのインバウンドはResource GatewayのSGからポート80を許可する設定が必要です。
4-2. Resource Configuration 作成
Resource Configuration は、Resource Gateway を通じてアクセスするリソース(本ハンズオンでは VPC Lattice Service FQDN)を定義します。作成後に払い出される Resource Configuration ARN は、Phase 5 の EventBridge Connection 設定で参照します。
AWSコンソール → VPC → 左ペイン「VPC Lattice」→「Resource configurations」→「Create resource configuration」
基本設定
| 項目 | 設定値 |
|---|---|
| Name | eventbridge-lattice-rc |
| Type | Single resource |
| Protocol | TCP |
Resource gateway
| 項目 | 設定値 |
|---|---|
| Resource gateway | eventbridge-lattice-rg(4-1で作成したゲートウェイ) |
ポートの設定
| 項目 | 設定値 |
|---|---|
| Port ranges | 80-80 |
リソースの設定
| 項目 | 設定値 |
|---|---|
| Domain name | 3-2で記録した VPC Lattice Service FQDN を入力 |
例:
svc-01abc23def456789.abc123def456.vpc-lattice-svcs.ap-northeast-1.on.aws
「Create resource configuration」をクリック。
作成完了後、「Resource configurations」一覧または詳細画面で ARN を確認・コピーします。
形式: arn:aws:vpc-lattice:ap-northeast-1:{account-id}:resourceconfiguration/{rc-id}
この ARN は Phase 5 の EventBridge Connection の
invocation_connectivity_parameters → resource_configuration_arn フィールドで参照されます。Phase 5 に進む前に、この ARN をメモしておいてください。
EventBridge Connection を作成すると、内部的に VPC Lattice の Resource Association が自動作成されます。この Resource Association は手動で削除できません。
ハンズオン終了時のクリーンアップでは、EventBridge Connection を先に削除することで Resource Association も自動的に削除されます。Resource Configuration や Resource Gateway を先に削除しようとすると依存関係エラーが発生するため、必ず正しい順序(EventBridge側 → VPC Lattice側)でクリーンアップしてください。
クリーンアップ手順の詳細は Phase 7 を参照してください。
Phase 3-4 完了チェックリスト
Phase 5(EventBridge構成)に進む前に、以下を確認してください。
| 確認項目 | 確認方法 | 期待値 |
|---|---|---|
| VPC Lattice Target Group | VPC Lattice > Target groups > Targets タブ | ECSタスクIPがHealthy状態で登録されている |
| VPC Lattice Service FQDN | VPC Lattice > Services > Summary タブ | FQDNが表示・コピー済み |
| VPC Lattice Listener | VPC Lattice > Services > Listeners タブ | HTTP:80 のリスナーが存在する |
| Service Network ↔ Service | VPC Lattice > Service networks > Services タブ | Activeステータスで関連付けられている |
| Service Network ↔ VPC | VPC Lattice > Service networks > VPC associations タブ | Activeステータスで関連付けられている |
| Resource Gateway | VPC Lattice > Resource gateways | Activeステータス |
| Resource Configuration ARN | VPC Lattice > Resource configurations | ARNをメモ済み |
すべての項目を確認したら、Phase 5: EventBridge 構成に進んでください。
コンソールハンズオン Phase 5: EventBridge 構成
Phase 1〜4 でネットワーク基盤・ECS Fargate・VPC Lattice(Service Mesh + Resource Gateway)を構築しました。Phase 5 では EventBridge 側の設定を行い、S3 へのファイルアップロードを起点としてプライベート API を呼び出す経路を完成させます。
5-1. S3 バケット作成 + EventBridge 通知有効化
まず、イベントのトリガーとなる S3 バケットを作成します。
バケット作成手順:
- AWS マネジメントコンソールで S3 を開く
- 「バケットを作成」をクリック
- 以下を入力する:
- バケット名:
eventbridge-demo-{ACCOUNT_ID}(グローバル一意。ACCOUNT_ID は 12 桁の AWS アカウント ID) - AWS リージョン:
アジアパシフィック (東京) ap-northeast-1 - その他の設定: デフォルトのまま(「パブリックアクセスをすべてブロック」は有効のまま)
- 「バケットを作成」をクリック
EventBridge 通知を有効化:
- 作成したバケットを開く
- 「プロパティ」タブを選択
- 「Amazon EventBridge」セクションまでスクロール
- 「編集」をクリックし、「Amazon EventBridge へのイベントの送信」を オン に切り替える
- 「変更の保存」をクリック
S3 の「Amazon EventBridge 通知」を有効化すると、S3 バケットで発生するすべてのイベント(PutObject、DeleteObject 等)が自動的に EventBridge のデフォルトイベントバスに送信されます。従来の個別イベント通知設定(SNS / SQS / Lambda への通知)とは別の仕組みです。EventBridge を経由することで、より柔軟なルーティングとフィルタリングが可能になります。
5-2. EventBridge Connection 作成
EventBridge Connection は、API Destination が呼び出す先の認証情報と、プライベート接続設定(VPC Lattice Resource Configuration への参照)を保持するリソースです。
手順:
- EventBridge コンソールを開く
- 左メニューから「API destinations」→「Connections」を選択
- 「Create connection」をクリック
- 以下を入力する:
- Connection name:
lattice-api-connection - Authorization type:
API Key(デモ用)- API key name:
x-api-key - Value:
demo-key-12345(任意の値)
- API key name:
- 「VPC connectivity」または「Invocation connectivity」セクションを展開し:
- Enable VPC connectivity: チェックを オン
- Resource configuration ARN: Phase 4 で作成した Resource Configuration の ARN を貼り付ける
- 「Create」をクリック
VPC connectivity(プライベート接続)の設定は、AWS マネジメントコンソールの画面更新によりセクション名や位置が変わることがあります。「Connectivity settings」「Invocation connectivity」「Additional settings」「Advanced」など、展開できるセクションがあれば確認してください。Resource Configuration ARN の入力欄が見つからない場合は、画面を下にスクロールするか、折りたたまれたセクションを展開してみてください。
aws_cloudwatch_event_connection リソースの invocation_connectivity_parameters ブロックは、Terraform AWS Provider v5.x 時点で対応状況が要確認です。Terraform 未対応の場合は AWS CLI で代替できます:aws events create-connection \
--name lattice-api-connection \
--authorization-type API_KEY \
--auth-parameters '{"ApiKeyAuthParameters":{"ApiKeyName":"x-api-key","ApiKeyValue":"demo-key-12345"}}' \
--invocation-connectivity-parameters \
'{"ResourceParameters":{"ResourceConfigurationArn":""}}'
5-3. EventBridge API Destination 作成
API Destination は、Connection を使って呼び出す HTTP エンドポイントを定義します。ここでは VPC Lattice Service の FQDN を指定します。
手順:
- EventBridge コンソール左メニューから「API destinations」を選択
- 「Create API destination」をクリック
- 以下を入力する:
- Name:
lattice-api-destination - API destination endpoint:
https://{VPC Lattice Service FQDN}/process
({VPC Lattice Service FQDN}は Phase 3-2 で記録した FQDN。/processパスを末尾に追加する) - HTTP method:
POST - Invocation rate limit:
10(1 秒あたりの最大呼び出し数) - Connection:
lattice-api-connection(5-2 で作成) - 「Create」をクリック
VPC Lattice Service FQDN は
{service-id}.{hash}.vpc-lattice-svcs.ap-northeast-1.on.aws 形式で自動生成されます。ポート 80 はデフォルト HTTP ポートのため URL に :80 は不要です。API Destination のエンドポイントは HTTPS で指定する必要があります(VPC Lattice Resource Gateway が TLS を終端します)。5-4. EventBridge Rule 作成(S3 PutObject イベントパターン)
S3 へのファイルアップロードイベントを検知し、API Destination に転送するルールを作成します。
手順:
- EventBridge コンソール左メニューから「Rules」を選択
- 「Create rule」をクリック
- 「Rule detail」で以下を入力する:
- Name:
s3-to-lattice-api - Event bus:
default - Rule type:
Rule with an event pattern - 「Next」をクリック
- 「Build event pattern」で以下の JSON を入力する:
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"name": ["eventbridge-demo-{ACCOUNT_ID}"]
}
}
}
- 「Next」をクリック
- 「Target 1」で以下を選択・入力する:
- Target types:
EventBridge API destination - API destination:
lattice-api-destination(5-3 で作成) - Execution role: 「Create a new role for this specific resource」を選択
(AmazonEventBridgeInvokeApiDestinationRolePolicyが自動付与される) - Configure input transformer: デモではデフォルト(変換なし)のまま省略可
- 「Next」→「Create rule」をクリック
以上で EventBridge 側の構成が完了しました。S3 バケットへのファイルアップロード → EventBridge Rule → API Destination → VPC Lattice Resource Gateway → ECS Fargate の経路が接続されました。
コンソールハンズオン Phase 6: 動作確認
構成が正しく機能しているか確認します。
6-1. S3 にファイルをアップロード
テスト用のファイルを S3 バケットにアップロードして、イベントを発生させます。
AWS CLI を使う場合:
# テスト用 JSON ファイルを作成
echo '{"test": "eventbridge-lattice-demo"}' > test-event.json
# S3 バケットにアップロード(ACCOUNT_ID を置き換えること)
aws s3 cp test-event.json s3://eventbridge-demo-{ACCOUNT_ID}/test-event.json
コンソールを使う場合:
- S3 コンソールで
eventbridge-demo-{ACCOUNT_ID}バケットを開く - 「アップロード」をクリック
- 任意のファイルを選択してアップロード
6-2. EventBridge Rule モニタリングで確認
アップロード後、EventBridge ルールが API Destination を呼び出したか確認します。
手順:
- EventBridge コンソール → 「Rules」→
s3-to-lattice-apiを選択 - 「Monitoring」タブを開く
- 以下のメトリクスが増加していることを確認:
- Invocations(呼び出し回数): 1 以上
- FailedInvocations(失敗数): 0
FailedInvocations が増加している場合は、セキュリティグループの設定または Resource Configuration ARN を再確認してください。
6-3. ECS タスクの CloudWatch Logs で確認
Fargate タスクがリクエストを受信したか、ログで確認します。
手順:
- CloudWatch コンソールを開く
- 左メニューから「Log groups」を選択
/ecs/eventbridge-lattice-apiを開く- 最新のログストリームをクリック
- 以下のようなログが出力されていることを確認:
INFO:app:Received event: {"version":"0","id":"...","source":"aws.s3","detail-type":"Object Created","detail":{"bucket":{"name":"eventbridge-demo-..."},...}}
CloudWatch Logs にリクエスト内容が記録されていれば、EventBridge → VPC Lattice Resource Gateway → ECS Fargate の全経路が正常に機能している証拠です。このログ確認が今回のハンズオンで最も重要な検証ステップです。
6-4. VPC Lattice Target Group ヘルス確認
ECS タスクが VPC Lattice Target Group に正常に登録され、ヘルシーな状態であることを確認します。
手順:
- VPC Lattice コンソールを開く
- 左メニューから「Target groups」→
eventbridge-lattice-tgを選択 - 「Targets」タブを開く
- すべてのターゲット(ECS タスクの IP アドレス)が Healthy 状態であることを確認
ターゲットが Unhealthy になっている場合、以下の順番で確認してください:
- ECS タスクのセキュリティグループのインバウンドルールに「ポート 80 を VPC Lattice Resource Gateway のセキュリティグループから許可」が設定されているか確認する
- ECS タスクが
/healthエンドポイントをポート 80 で正常に応答しているか確認する(CloudWatch Logs でエラーが出ていないか確認) - タスク定義のコンテナポートマッピングが 80 番ポートになっているか確認する
コンソールハンズオン Phase 7: クリーンアップ
ハンズオン終了後は、不要な料金発生を防ぐためにリソースを削除します。依存関係があるため、必ず以下の順番で削除してください。
依存関係のあるリソースを先に削除すると、削除エラーが発生します。特に VPC Lattice の Service Network 関連付けは、Service / VPC の関連付けを先に解除してからでないと削除できません。また、EventBridge Connection が自動作成する Resource Association は手動削除が必要な場合があります。
削除順序(上から順に実行):
- EventBridge Rule 削除
EventBridge コンソール → Rules →
s3-to-lattice-api→ DeleteEventBridge API Destination 削除
EventBridge コンソール → API destinations →
lattice-api-destination→ DeleteEventBridge Connection 削除
- EventBridge コンソール → API destinations → Connections →
lattice-api-connection→ Delete ※ Connection 削除前に VPC Lattice コンソール → Resource associations で、この Connection が自動作成した関連付けを先に手動削除が必要な場合がある
S3 バケット内のオブジェクト削除 → バケット削除
S3 コンソール →
eventbridge-demo-{ACCOUNT_ID}→ 「空にする」→「削除」ECS サービス削除
ECS コンソール → クラスター → サービス →
Desired tasks を 0に更新 → サービス削除ECS タスク定義 無効化
ECS コンソール → Task definitions → 対象タスク定義 → 「Deregister」
ECS クラスター削除
ECS コンソール → クラスター → Delete cluster
VPC Lattice Resource Configuration 削除
VPC Lattice コンソール → Resource configurations → 削除
VPC Lattice Resource Gateway 削除
VPC Lattice コンソール → Resource gateways → 削除
VPC Lattice Service Network ↔ VPC 関連付け解除
- VPC Lattice コンソール → Service networks → 対象 → VPC associations → 削除
VPC Lattice Service Network ↔ Service 関連付け解除
- VPC Lattice コンソール → Service networks → 対象 → Service associations → 削除
VPC Lattice Service 削除
- VPC Lattice コンソール → Services → 削除
VPC Lattice Target Group 削除
- VPC Lattice コンソール → Target groups → 削除
VPC Lattice Service Network 削除
- VPC Lattice コンソール → Service networks → 削除
NAT Gateway 削除 → Elastic IP 解放
- VPC コンソール → NAT gateways → 削除(削除完了まで数分かかる)
- Elastic IPs → 「Release Elastic IP address」
VPC 削除(サブネット・Internet Gateway・ルートテーブルを含む)
- VPC コンソール → VPCs → 対象 VPC → 「Delete VPC」(関連リソースが自動削除される)
IAM ロール削除
- IAM コンソール → Roles → 以下を削除:
ecsTaskExecutionRoleecsInfrastructureRole(VPC Lattice 登録用)- EventBridge 実行ロール(
AmazonEventBridgeInvokeApiDestinationRolePolicyがアタッチされたロール)
ECR リポジトリ削除(イメージを含む)
- ECR コンソール → Repositories → 対象リポジトリ → 「Delete」
NAT Gateway は起動しているだけで時間課金($0.045/時間)が発生します。また、Elastic IP は EC2 リソースに関連付けられていない場合に課金されます。ハンズオン終了後は必ず削除してください。削除順序は NAT Gateway を先に削除してから Elastic IP を解放します(順序が逆だと解放できません)。
Terraform を使用した場合:
Terraform でリソースを作成した場合は、以下のコマンドで一括削除できます:
terraform destroy
ただし、EventBridge Connection が自動作成した Resource Association は Terraform の管理外のため、terraform destroy 後に手動で確認・削除が必要な場合があります。
TerraformでEventBridge × VPC Lattice × Fargate構成を構築する
Section 3のコンソールハンズオンで構築した同等構成を、Terraformでコード化します。全22リソースを7つのファイルに整理し、terraform apply 一発で再現可能なIaCを実現します。
コンソールハンズオン(Section 3)を先に読んでおくと、各リソースの役割を理解しやすくなります。Terraform 1.3以上・AWS CLI設定済み・必要なIAM権限(VPC/ECS/VPC Lattice/EventBridge/S3/IAM の作成・管理権限)が必要です。
5-1. ディレクトリ構成
プロジェクトディレクトリ eventbridge-lattice-fargate/ を作成し、以下の構成にします。
eventbridge-lattice-fargate/
├── main.tf # Provider設定
├── variables.tf # 変数定義
├── outputs.tf # 出力定義
├── vpc.tf # ネットワーク基盤(VPC/サブネット/NAT/SG)
├── iam.tf # IAMロール×4
├── ecs.tf # ECS Fargate(ECR/クラスター/タスク定義/サービス)
├── lattice.tf # VPC Lattice(Service/Target Group/Resource Gateway等)
└── eventbridge.tf# EventBridge(Connection/API Destination/Rule/Target)
mkdir eventbridge-lattice-fargate
cd eventbridge-lattice-fargate
5-2. variables.tf — 変数定義
variable "aws_region" {
description = "AWSリージョン"
default = "ap-northeast-1"
}
variable "project_name" {
description = "プロジェクト名(リソース名のプレフィックスに使用)"
default = "eventbridge-lattice"
}
variable "vpc_cidr" {
description = "VPCのCIDRブロック"
default = "10.0.0.0/16"
}
variable "container_image" {
description = "ECSタスクで使用するECRイメージURI"
type = string
}
variable "account_id" {
description = "AWSアカウントID(S3バケット名のユニーク化に使用)"
type = string
}
5-3. main.tf — Provider設定
terraform {
required_version = ">= 1.3"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
# アベイラビリティゾーンの動的取得
data "aws_availability_zones" "available" {
state = "available"
}
5-4. vpc.tf — ネットワーク基盤
VPC・サブネット(パブリック×2/プライベート×2)・NAT Gateway・セキュリティグループを定義します。
# ─────────────────────────────────────────
# VPC
# ─────────────────────────────────────────
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support= true
tags = {
Name = "${var.project_name}-vpc"
}
}
# ─────────────────────────────────────────
# プライベートサブネット × 2
# (ECS Fargate / Resource Gateway 配置用)
# ─────────────────────────────────────────
resource "aws_subnet" "private" {
count = 2
vpc_id= aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = false
tags = {
Name = "${var.project_name}-private-${count.index + 1}"
}
}
# ─────────────────────────────────────────
# パブリックサブネット × 2
# (NAT Gateway 配置用。FargateのECRイメージpull等の外部通信に使用)
# ─────────────────────────────────────────
resource "aws_subnet" "public" {
count = 2
vpc_id= aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index + 10)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.project_name}-public-${count.index + 1}"
}
}
# ─────────────────────────────────────────
# Internet Gateway
# ─────────────────────────────────────────
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.project_name}-igw"
}
}
# ─────────────────────────────────────────
# Elastic IP / NAT Gateway
# (プライベートサブネットからの外部通信用)
# ─────────────────────────────────────────
resource "aws_eip" "nat" {
domain = "vpc"
tags = {
Name = "${var.project_name}-nat-eip"
}
}
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public[0].id
tags = {
Name = "${var.project_name}-nat"
}
depends_on = [aws_internet_gateway.main]
}
# ─────────────────────────────────────────
# ルートテーブル — パブリック
# ─────────────────────────────────────────
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "${var.project_name}-public-rt"
}
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id= aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# ─────────────────────────────────────────
# ルートテーブル — プライベート
# ─────────────────────────────────────────
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main.id
}
tags = {
Name = "${var.project_name}-private-rt"
}
}
resource "aws_route_table_association" "private" {
count = 2
subnet_id= aws_subnet.private[count.index].id
route_table_id = aws_route_table.private.id
}
data "aws_ec2_managed_prefix_list" "vpc_lattice" {
name = "com.amazonaws.ap-northeast-1.vpc-lattice"
}
# ─────────────────────────────────────────
# セキュリティグループ — ECS Fargate
# ─────────────────────────────────────────
resource "aws_security_group" "fargate" {
name = "${var.project_name}-fargate-sg"
description = "ECS Fargate: port 80 from VPC Lattice Resource Gateway SG"
vpc_id= aws_vpc.main.id
ingress {
description = "HTTP from VPC Lattice Resource Gateway"
from_port = 80
to_port= 80
protocol = "tcp"
security_groups = [aws_security_group.lattice_rg.id]
}
# VPC Lattice ヘルスチェック用(推奨)
ingress {
from_port = 80
to_port= 80
protocol = "tcp"
prefix_list_ids = [data.aws_ec2_managed_prefix_list.vpc_lattice.id]
description = "Allow VPC Lattice health checks"
}
egress {
from_port= 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.project_name}-fargate-sg"
}
}
# ─────────────────────────────────────────
# セキュリティグループ — VPC Lattice Resource Gateway
# ─────────────────────────────────────────
resource "aws_security_group" "lattice_rg" {
name = "${var.project_name}-lattice-rg-sg"
description = "VPC Lattice Resource Gateway: port 443 inbound from EventBridge"
vpc_id= aws_vpc.main.id
# EventBridgeのIPは動的なため、CIDR全開放。
# 本番環境ではAWS EventBridgeのIPプレフィックスリストを利用することを推奨。
ingress {
description = "HTTPS from EventBridge (dynamic IP)"
from_port= 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
description = "HTTP to ECS Fargate"
from_port = 80
to_port= 80
protocol = "tcp"
security_groups = [aws_security_group.fargate.id]
}
tags = {
Name = "${var.project_name}-lattice-rg-sg"
}
}
fargate SGが lattice_rg SGを参照し、lattice_rg SGが fargate SGを参照しています。Terraformはこの双方向SGルールを正しく処理しますが、aws_security_group_rule リソースに分割して定義する方法もあります。
5-5. iam.tf — IAMロール(4種)
ECS・VPC Lattice・EventBridgeの各サービスに必要な4つのIAMロールを定義します。
# ─────────────────────────────────────────
# ECS Task Execution Role
# (ECRイメージpull・CloudWatch Logs書き込みに使用)
# ─────────────────────────────────────────
resource "aws_iam_role" "ecs_task_execution" {
name = "${var.project_name}-ecs-task-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ecs-tasks.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
tags = {
Name = "${var.project_name}-ecs-task-execution-role"
}
}
resource "aws_iam_role_policy_attachment" "ecs_task_execution" {
role = aws_iam_role.ecs_task_execution.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
# ─────────────────────────────────────────
# ECS Task Role
# (コンテナアプリケーション固有の権限。デモでは最小限)
# ─────────────────────────────────────────
resource "aws_iam_role" "ecs_task" {
name = "${var.project_name}-ecs-task-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ecs-tasks.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
tags = {
Name = "${var.project_name}-ecs-task-role"
}
}
# ─────────────────────────────────────────
# ECS Infrastructure Role
# (ECS ServiceがVPC Lattice Target GroupにタスクIPを自動登録するために使用)
# vpc_lattice_configurations の role_arn に指定する。
# ─────────────────────────────────────────
resource "aws_iam_role" "ecs_infrastructure" {
name = "${var.project_name}-ecs-infrastructure-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ecs.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
tags = {
Name = "${var.project_name}-ecs-infrastructure-role"
}
}
resource "aws_iam_role_policy" "ecs_infrastructure_lattice" {
name = "${var.project_name}-ecs-infrastructure-lattice-policy"
role = aws_iam_role.ecs_infrastructure.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"vpc-lattice:RegisterTargets",
"vpc-lattice:DeregisterTargets",
"vpc-lattice:GetTargetGroup"
]
Resource = "*"
}]
})
}
# ─────────────────────────────────────────
# EventBridge Invoke Role
# (EventBridge RuleがAPI Destinationを呼び出し、
#VPC Lattice Resource Configurationにアクセスするために使用)
# ─────────────────────────────────────────
resource "aws_iam_role" "eventbridge_invoke" {
name = "${var.project_name}-eventbridge-invoke-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "events.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
tags = {
Name = "${var.project_name}-eventbridge-invoke-role"
}
}
resource "aws_iam_role_policy" "eventbridge_invoke" {
name = "${var.project_name}-eventbridge-invoke-policy"
role = aws_iam_role.eventbridge_invoke.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect= "Allow"
Action= ["events:InvokeApiDestination"]
Resource = "*"
},
{
# EventBridge ConnectionがVPC Lattice Resource Configurationにアクセスするために必要
Effect = "Allow"
Action = [
"vpc-lattice:CreateServiceNetworkResourceAssociation",
"vpc-lattice:GetResourceConfiguration",
"vpc-lattice:AssociateViaAWSService-EventsAndStates"
]
Resource = "*"
}
]
})
}
5-6. ecs.tf — ECS Fargate
ECRリポジトリ・ECSクラスター・タスク定義・ECSサービスを定義します。サービスの vpc_lattice_configurations ブロックが、VPC Lattice Target GroupへのFargateタスク自動登録のポイントです。
# ─────────────────────────────────────────
# ECRリポジトリ
# ─────────────────────────────────────────
resource "aws_ecr_repository" "api" {
name = "${var.project_name}-api"
image_tag_mutability = "MUTABLE"
image_scanning_configuration {
scan_on_push = true
}
tags = {
Name = "${var.project_name}-api"
}
}
# ─────────────────────────────────────────
# CloudWatch Logs グループ
# ─────────────────────────────────────────
resource "aws_cloudwatch_log_group" "ecs_api" {
name = "/ecs/${var.project_name}-api"
retention_in_days = 7
tags = {
Name = "${var.project_name}-ecs-api-logs"
}
}
# ─────────────────────────────────────────
# ECS クラスター
# ─────────────────────────────────────────
resource "aws_ecs_cluster" "main" {
name = "${var.project_name}-cluster"
tags = {
Name = "${var.project_name}-cluster"
}
}
# ─────────────────────────────────────────
# ECS タスク定義
# (シンプルHTTP API: ポート80で待機)
# ─────────────────────────────────────────
resource "aws_ecs_task_definition" "api" {
family = "${var.project_name}-api"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = 256
memory = 512
execution_role_arn = aws_iam_role.ecs_task_execution.arn
task_role_arn= aws_iam_role.ecs_task.arn
container_definitions = jsonencode([{
name = "api"
image = var.container_image
portMappings = [{
containerPort = 80
protocol= "tcp"
name = "api-port"
}]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group"= "/ecs/${var.project_name}-api"
"awslogs-region" = var.aws_region
"awslogs-stream-prefix" = "ecs"
}
}
}])
tags = {
Name = "${var.project_name}-task-def"
}
}
# ─────────────────────────────────────────
# ECS サービス
# vpc_lattice_configurations でTarget Groupへ自動登録
# ─────────────────────────────────────────
resource "aws_ecs_service" "api" {
name= "${var.project_name}-api"
cluster= aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.api.arn
desired_count= 2
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.private[*].id
security_groups = [aws_security_group.fargate.id]
assign_public_ip = false
}
# VPC Lattice Target GroupにFargateタスクIPを自動登録する
vpc_lattice_configurations {
role_arn= aws_iam_role.ecs_infrastructure.arn
target_group_arn = aws_vpclattice_target_group.api.arn
port_name = "api-port"
}
depends_on = [
aws_iam_role_policy_attachment.ecs_task_execution,
aws_iam_role_policy.ecs_infrastructure_lattice
]
tags = {
Name = "${var.project_name}-api-service"
}
}
vpc_lattice_configurations 削除時の既知バグ(issue #41600)aws_ecs_service の vpc_lattice_configurations ブロックを後から削除すると、perpetual diff(差分が解消されない状態) が発生するバグが報告されています。
回避策は2つあります:
1. lifecycle ブロックで変更を無視する(完全な削除は不可):
lifecycle {
ignore_changes = [vpc_lattice_configurations]
}2. ECS サービスを再作成する: 削除が必要な場合はサービス全体を terraform destroy → terraform apply する。
ハンズオン終了後のクリーンアップは terraform destroy で行えば問題ありません。
5-7. lattice.tf — VPC Lattice構成
VPC Lattice Service Network・Service・Target Group・Listener・Service Network関連付け・Resource Gateway・Resource Configuration を定義します。
# ─────────────────────────────────────────
# Target Group(IPタイプ)
# ECS FargateタスクのIPを直接ターゲットとして受け付ける
# ─────────────────────────────────────────
resource "aws_vpclattice_target_group" "api" {
name = "${var.project_name}-tg"
type = "IP"
config {
port= 80
protocol = "HTTP"
vpc_identifier = aws_vpc.main.id
ip_address_type = "IPV4"
health_check {
enabled = true
healthy_threshold= 2
unhealthy_threshold = 2
interval_seconds = 30
path = "/health"
port = 80
protocol= "HTTP"
protocol_version = "HTTP1"
}
}
tags = {
Name = "${var.project_name}-tg"
}
}
# ─────────────────────────────────────────
# VPC Lattice Service
# FargateへのルーティングをFQDNで提供する
# ─────────────────────────────────────────
resource "aws_vpclattice_service" "api" {
name= "${var.project_name}-service"
auth_type = "NONE"
tags = {
Name = "${var.project_name}-service"
}
}
# ─────────────────────────────────────────
# Listener(HTTP:80 → Target Group転送)
# ─────────────────────────────────────────
resource "aws_vpclattice_listener" "http" {
name= "${var.project_name}-listener"
protocol = "HTTP"
port= 80
service_identifier = aws_vpclattice_service.api.id
default_action {
forward {
target_groups {
target_group_identifier = aws_vpclattice_target_group.api.id
weight= 100
}
}
}
tags = {
Name = "${var.project_name}-listener"
}
}
# ─────────────────────────────────────────
# Service Network
# ServiceとVPCを論理的にグループ化する
# ─────────────────────────────────────────
resource "aws_vpclattice_service_network" "main" {
name= "${var.project_name}-sn"
auth_type = "NONE"
tags = {
Name = "${var.project_name}-service-network"
}
}
# Service Network ↔ Service 関連付け
resource "aws_vpclattice_service_network_service_association" "api" {
service_network_identifier = aws_vpclattice_service_network.main.id
service_identifier= aws_vpclattice_service.api.id
}
# Service Network ↔ VPC 関連付け
# (Resource GatewayのSGを指定して通信制御)
resource "aws_vpclattice_service_network_vpc_association" "main" {
service_network_identifier = aws_vpclattice_service_network.main.id
vpc_identifier = aws_vpc.main.id
security_group_ids= [aws_security_group.lattice_rg.id]
}
# ─────────────────────────────────────────
# Resource Gateway
# VPC内に配置されるネットワークエントリーポイント。
# EventBridgeからの通信(ポート443)を受け付け、
# Fargate APIへの橋渡しをする。
# ─────────────────────────────────────────
resource "aws_vpclattice_resource_gateway" "main" {
name= "${var.project_name}-rg"
ip_address_type = "IPV4"
vpc_identifier = aws_vpc.main.id
subnet_ids= aws_subnet.private[*].id
security_group_ids = [aws_security_group.lattice_rg.id]
tags = {
Name = "${var.project_name}-resource-gateway"
}
}
# ─────────────────────────────────────────
# Resource Configuration
# EventBridge ConnectionからARNで参照される。
# VPC Lattice Service FQDNをDNSリソースとして指定。
# ─────────────────────────────────────────
resource "aws_vpclattice_resource_configuration" "api" {
name= "${var.project_name}-rc"
type= "SINGLE"
resource_gateway_identifier = aws_vpclattice_resource_gateway.main.id
port_ranges = ["80-80"]
resource_configuration_definition {
dns_resource {
domain_name = aws_vpclattice_service.api.dns_entry[0].domain_name
ip_address_type = "IPV4"
}
}
tags = {
Name = "${var.project_name}-resource-configuration"
}
}
aws_vpclattice_resource_gateway の作成には10〜15分程度かかることがあります。terraform apply 実行中に長時間待機状態になっても正常です。タイムアウトが懸念される場合は、timeouts ブロックで延長してください。
5-8. eventbridge.tf — EventBridge構成
aws_cloudwatch_event_connection の private connectivity 対応状況invocation_connectivity_parameters(VPC Lattice Resource ConfigurationのARNを指定するブロック)の Terraform AWS Provider v5.x での対応状況は 要検証 です。
このブロックが未対応の場合、Terraform でConnectionを作成した後、AWS CLIで update-connection を実行してprivate connectivityを追加する必要があります(後述のCLI代替手順を参照)。
# ─────────────────────────────────────────
# S3 バケット(デモ用イベントソース)
# ─────────────────────────────────────────
resource "aws_s3_bucket" "demo" {
bucket = "${var.project_name}-demo-${var.account_id}"
tags = {
Name = "${var.project_name}-demo-bucket"
}
}
# S3 → EventBridge 通知を有効化
resource "aws_s3_bucket_notification" "eventbridge" {
bucket= aws_s3_bucket.demo.id
eventbridge = true
}
# ─────────────────────────────────────────
# EventBridge Connection
# VPC Lattice Resource Configurationを参照し、
# プライベートAPIへの接続を確立する
# ─────────────────────────────────────────
resource "aws_cloudwatch_event_connection" "lattice" {
name= "${var.project_name}-connection"
authorization_type = "API_KEY"
auth_parameters {
api_key {
key= "x-api-key"
value = "demo-key-12345"
}
}
# ─────────────────────────────────────────────────────────────
# ⚠️ 以下のブロックは Terraform AWS Provider v5.x での対応が
# 未確認のため、コメントアウトしています。
#
# 対応確認方法:
#terraform init && terraform plan
#で "An argument named invocation_connectivity_parameters is
#not expected here" エラーが出た場合は未対応。
#下記のCLI代替手順を使用してください。
# ─────────────────────────────────────────────────────────────
# invocation_connectivity_parameters {
#resource_parameters {
# resource_configuration_arn = aws_vpclattice_resource_configuration.api.arn
#}
# }
}
# ─────────────────────────────────────────
# EventBridge API Destination
# Connection経由でVPC Lattice Service FQDNを呼び出す
# ─────────────────────────────────────────
resource "aws_cloudwatch_event_api_destination" "lattice" {
name = "${var.project_name}-api-destination"
connection_arn = aws_cloudwatch_event_connection.lattice.arn
invocation_endpoint = "https://${aws_vpclattice_service.api.dns_entry[0].domain_name}/process"
http_method = "POST"
invocation_rate_limit_per_second = 10
}
# ─────────────────────────────────────────
# EventBridge Rule
# S3 PutObject イベントをフィルタリング
# ─────────────────────────────────────────
resource "aws_cloudwatch_event_rule" "s3_put" {
name = "${var.project_name}-s3-to-lattice"
description = "S3 PutObject イベントをVPC Lattice経由でFargate APIに転送"
event_pattern = jsonencode({
source= ["aws.s3"]
detail-type = ["Object Created"]
detail = {
bucket = {
name = [aws_s3_bucket.demo.id]
}
}
})
tags = {
Name = "${var.project_name}-s3-rule"
}
}
# ─────────────────────────────────────────
# EventBridge Target
# RuleをAPI Destinationに接続
# ─────────────────────────────────────────
resource "aws_cloudwatch_event_target" "lattice_api" {
rule = aws_cloudwatch_event_rule.s3_put.name
arn= aws_cloudwatch_event_api_destination.lattice.arn
role_arn = aws_iam_role.eventbridge_invoke.arn
http_target {
path_parameter_values = []
}
}
invocation_connectivity_parameters が Terraform 未対応の場合、Connection作成後に以下のAWS CLIコマンドで private connectivity を設定します。
# ConnectionのARNをterraform outputから取得
CONN_ARN=$(terraform output -raw connection_arn)
# Resource Configuration ARNをterraform outputから取得
RC_ARN=$(terraform output -raw resource_configuration_arn)
# CLIでprivate connectivityを追加
aws events update-connection \
--name "${var.project_name}-connection" \
--invocation-connectivity-parameters \
"{\"ResourceParameters\":{\"ResourceConfigurationArn\":\"${RC_ARN}\"}}"
CLIコマンド実行後、AWSコンソールのEventBridge > Connections から private connectivity が設定されていることを確認してください。
5-9. outputs.tf — 出力値
output "vpc_lattice_service_fqdn" {
description = "VPC Lattice ServiceのFQDN(API Destinationのエンドポイントに使用)"
value = aws_vpclattice_service.api.dns_entry[0].domain_name
}
output "resource_configuration_arn" {
description = "VPC Lattice Resource ConfigurationのARN(EventBridge Connectionの設定に使用)"
value = aws_vpclattice_resource_configuration.api.arn
}
output "connection_arn" {
description = "EventBridge ConnectionのARN(CLI代替手順で使用)"
value = aws_cloudwatch_event_connection.lattice.arn
}
output "s3_bucket_name" {
description = "デモ用S3バケット名(動作確認でファイルアップロードに使用)"
value = aws_s3_bucket.demo.id
}
output "ecr_repository_url" {
description = "ECRリポジトリURL(container_image変数に指定するURI)"
value = aws_ecr_repository.api.repository_url
}
5-10. デプロイ手順
Step 1: 初期化
cd eventbridge-lattice-fargate
terraform init
Step 2: ECRリポジトリ作成・イメージのpush
terraform apply 前にECRリポジトリだけ先に作成し、コンテナイメージをpushします。
# ECRリポジトリのみ先にapply
terraform apply \
-target=aws_ecr_repository.api \
-var="container_image=dummy" \
-var="account_id=$(aws sts get-caller-identity --query Account --output text)"
# ECRリポジトリURLを取得
ECR_URL=$(terraform output -raw ecr_repository_url)
AWS_REGION="ap-northeast-1"
# Dockerイメージをビルド・タグ付け・push
aws ecr get-login-password --region ${AWS_REGION} | \
docker login --username AWS --password-stdin ${ECR_URL}
docker build -t ${ECR_URL}:latest .
docker push ${ECR_URL}:latest
Step 3: 全リソースのapply
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
terraform plan \
-var="container_image=${ECR_URL}:latest" \
-var="account_id=${ACCOUNT_ID}"
terraform apply \
-var="container_image=${ECR_URL}:latest" \
-var="account_id=${ACCOUNT_ID}"
VPC Lattice Resource Gatewayのプロビジョニングに時間がかかるため、aws_vpclattice_resource_gateway.main: Still creating... が数分続きますが正常です。
Step 4: private connectivity の設定(CLI代替手順)
invocation_connectivity_parameters が Terraform 未対応の場合のみ実行します。
CONN_ARN=$(terraform output -raw connection_arn)
RC_ARN=$(terraform output -raw resource_configuration_arn)
CONN_NAME="${var.project_name}-connection" # 実際の値: eventbridge-lattice-connection
aws events update-connection \
--name "eventbridge-lattice-connection" \
--invocation-connectivity-parameters \
"{\"ResourceParameters\":{\"ResourceConfigurationArn\":\"${RC_ARN}\"}}"
Step 5: 動作確認
S3_BUCKET=$(terraform output -raw s3_bucket_name)
# S3バケットにファイルをアップロードしてEventBridgeをトリガー
aws s3 cp README.md s3://${S3_BUCKET}/test-$(date +%s).md
# EventBridgeのルール実行状況を確認(約30秒後)
aws events describe-rule \
--name "eventbridge-lattice-s3-to-lattice" \
--query "{Name:Name, State:State}"
# ECS FargateタスクのCloudWatch Logsでリクエスト受信を確認
aws logs tail "/ecs/eventbridge-lattice-api" --follow
クリーンアップ
# S3バケットを空にしてからdestroy
aws s3 rm s3://${S3_BUCKET} --recursive
terraform destroy \
-var="container_image=${ECR_URL}:latest" \
-var="account_id=${ACCOUNT_ID}"
EventBridge Connectionを作成すると、VPC Lattice側に Resource Association が自動生成されます。このリソースはAWSコンソールや terraform destroy で直接削除できない場合があります。terraform destroy でエラーが出た場合は、AWS CLIで aws vpc-lattice delete-service-network-resource-association を実行してから再度 destroy してください。
まとめ
本記事で実現できたこと
- EventBridge → VPC Lattice → ECS Fargate の直接連携を、中継Lambdaなしで構築
- VPC Lattice Resource Gateway/Configuration を使ったプライベートAPIへのセキュアなアクセスパターンを習得
- ECS Serviceの
vpc_lattice_configurationsパラメータによるFargateタスクの自動ターゲット登録 - S3イベントをトリガーにしてFargate APIを非同期呼び出しするイベント駆動アーキテクチャの実装
- Terraform(全22リソース) でコンソール手順と同等の構成を完全コード化
EventBridge API Destination + VPC Lattice Resource Gatewayパターンの利点
| 観点 | 利点 |
|---|---|
| セキュリティ | FargateタスクにパブリックIPなし。EventBridgeからResource Gateway経由でのみアクセス可能 |
| スケーラビリティ | ECS Serviceのスケールアウト時にFargateタスクIPがTarget Groupに自動登録・自動解除 |
| シンプルな構成 | Lambda Proxyパターン不要。EventBridge → VPC Lattice → Fargateの直接経路 |
| コスト効率 | Lambda不要のためコールドスタートなし。常時稼働のFargate Serviceへ直接ルーティング |
| 運用性 | VPC Lattice Service FQDNを変えずにバックエンドを入れ替え可能(Blue/Green的な切り替えが可能) |
応用例
マルチサービス構成:
複数のFargate Serviceを同一のVPC Lattice Service Networkに接続し、EventBridge Ruleのイベントパターンでルーティング先を切り替える構成が可能です。サービスごとに別のAPI Destinationを定義し、Ruleのターゲットを複数設定するだけで実現できます。
クロスアカウント共有:
VPC Lattice Service NetworkはAWS Resource Access Manager(RAM)でクロスアカウント共有が可能です。EventBridgeは別アカウントに置き、VPC LatticeとFargateは共有サービスアカウントに集約するマルチアカウント構成に発展させられます。
Webhook受信パターン:
S3イベント以外にも、API GatewayやEventBridge APIのPutEventsでイベントを生成し、同じVPC Lattice経由でFargateにルーティングするWebhook受信アーキテクチャにも応用できます。
参考リンク
AWS公式ドキュメント
- EventBridge Connections with private connectivity — Resource Configuration ARNを使ったプライベートConnectの設定方法
- Amazon VPC Lattice User Guide — Resource Gateways — Resource GatewayとResource Configurationの概念と操作方法
- Amazon ECS — VPC Lattice integration —
vpc_lattice_configurationsパラメータによるECSとVPC Latticeの統合 - Securely share AWS resources across VPC and account boundaries — 2024年11月発表のEventBridge × VPC Lattice連携に関するAWSブログ
Terraform Registry
- aws_vpclattice_resource_gateway — Resource Gatewayリソースの引数・属性リファレンス
- aws_vpclattice_resource_configuration — Resource Configurationリソースの引数・属性リファレンス
- aws_vpclattice_target_group — IPタイプTarget Groupの設定方法
- aws_ecs_service —
vpc_lattice_configurationsブロックの引数リファレンス - aws_cloudwatch_event_connection — EventBridge Connection(API Destination用)のリファレンス
GitHub Issues(既知のバグ・制限)
- terraform-provider-aws #41600 —
vpc_lattice_configurations削除時のperpetual diffバグ - terraform-provider-aws #40176 — VPC Lattice Resource Gateway 関連
- terraform-provider-aws #40669 — VPC Lattice Resource Configuration 関連