ECSを利用したコンテナ環境構築ハンズオン
はじめに
社内で Amazon ECS (Elastic Container Service) のハンズオンを予定しており、その手順の整理もかねて執筆しました。
この記事では、ECS環境の基本的な構築手順を、インフラの土台となるVPCからALB (Application Load Balancer) まで、すべてステップバイステップで解説します。
※VPCやサブネットについての詳しい説明は省略しております。
構成のゴール
最終的に、ECSを活用した以下の図のような高可用性とセキュリティを考慮した構成をAWS上に構築します。

- VPC: ネットワークの隔離
- Public Subnet: ALBとNAT Gatewayを配置。インターネットとの通信を担当
- Private Subnet: ECS Fargateのタスク(コンテナ)を配置。外部からのアクセスはALB経由のみ
- IGW/NAT-GW: Private SubnetのECSタスクが安全に外部(ECRなど)へアクセスするための経路を提供
- ALB: 外部からのトラフィックを受け付け、Private SubnetのECSタスクへ振り分け
ECSの基本概念
ハンズオンを進める前に、AWS ECSでコンテナを動かすための主要なコンポーネントとその関係を整理しておきましょう。
Amazon ECSを構成する主要な要素は、クラスター、タスク定義、タスク、サービス の4つです。
| コンポーネント | 役割 |
|---|---|
| ECS クラスター | コンテナの実行環境全体 |
| ECS タスク定義 | コンテナの設計図 |
| ECS タスク | 設計図に基づいて起動したコンテナ |
| ECS サービス | タスクの実行と維持 |
関係性のイメージ:
- ECS クラスター(実行場所)を作成
- 実行したいコンテナの仕様をECS タスク定義(設計図)で設計
- ECS サービス(管理者)が、このタスク定義を使って、クラスター内で指定された数のECS タスク(実行中のコンテナ)を起動
ただし、ECSサービスは必ずしも必須のものではなく、ECSサービスがなくてもECSタスクを起動できます。
APIとしてアプリケーションを使用したいときは、ECSサービスは必要になります。
注意
今回のハンズオンで作成する構築は料金が発生します。
🛠️ Step 1: 事前準備 (AWS CLIの設定)
AWS CLIを使用し、設定の確認やECRへのイメージプッシュを簡単に行えるようにします。
1-1. AWS CLIの認証設定確認
AWS CLIがインストールされ、認証情報が設定済みであることを確認します。
以下を実行して、自分のIAMの情報がリストで表示されればOKです。
aws iam list-users --output table
インストールがまだの方は、以下のAWS公式のページからインストールを行ってください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
🏗️ Step 2: ネットワーク環境 (VPC) の構築
ECSを稼働させるための基盤となるVPCを構築します。
2-1. VPCとサブネットの作成
| Name | AZ | IPv4 CIDR | 役割 |
|---|---|---|---|
| VPC (名前タグ: ecs-hands-on) | - | 10.0.0.0/16 | ネットワーク全体 |
| public-subnet-1a | ap-northeast-1a | 10.0.0.0/20 | ALB配置用 |
| public-subnet-1c | ap-northeast-1c | 10.0.16.0/20 | ALB配置用 |
| private-subnet-1a | ap-northeast-1a | 10.0.32.0/20 | ECSタスク配置用 |
| private-subnet-1c | ap-northeast-1c | 10.0.48.0/20 | ECSタスク配置用 |
ポイント: 冗長性を確保するため、2つのAZ (
1aと1c) に Public/Private のサブネットを作成します。
2-2. インターネット接続の確保 (IGW & NAT-GW)
a. インターネットゲートウェイ (IGW) の作成
- 名前:
ecs-hands-on-igw - 作成後、VPC (
ecs-hands-on) にアタッチします
b. NATゲートウェイ (NAT-GW) の作成
- 名前:
ecs-hands-on-nat-1a - ゾーナル
- サブネット: public-subnet-1a
- Elastic IPを新規に割り当てます
2-3. ルートテーブルの設定
| 名前 | 関連付けられたサブネット | ルート (0.0.0.0/0) | 備考 |
|---|---|---|---|
ecs-hands-on-rtb-public |
Public Subnet | ecs-hands-on-igw | インターネット直結 |
ecs-hands-on-rtb-private |
Private Subnet | ecs-hands-on-nat-1a | NAT-GW経由で外部アクセス |
🖼️ Step 3: コンテナイメージの準備
3-1. ECR (Elastic Container Registry) の作成
コンテナイメージを格納するリポジトリを作成します。
- 名前: ecs-hands-on
- イミュータブル、暗号化はAES-256を選択
3-2. コンテナイメージのビルドとプッシュ
アプリケーションのDockerfileを用意し、ECRにイメージをプッシュします。
AWS_ACCOUNT_ID=<自身のID>
AWS_REGION=ap-northeast-1
IMAGE_REPOSITORY_BASE=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
IMAGE_REPOSITORY_URI=${IMAGE_REPOSITORY_BASE}/ecs-hands-on
# ECRへのログイン
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${IMAGE_REPOSITORY_URI}
# イメージのビルド
# Dockerfileは事前に用意し、`8080`ポートで/healthzエンドポイントを用意してください。
docker build --platform=linux/amd64 -t ${IMAGE_REPOSITORY_URI}:0.0.1 -f Dockerfile .
# ECRへプッシュ
docker push ${IMAGE_REPOSITORY_URI}:0.0.1
⚙️ Step 4: ECSクラスターとタスク定義の設定
4-1. ECSクラスターの作成
- クラスター名: ecs-hands-on-backend
- ネットワーキング専用のクラスターを選択
4-2. ECSタスク実行ロールの作成 (IAM)
ECSタスクがイメージのプルやSecret Managerへのアクセスを行うための権限を定義します。
- IAM > ロール > AWSのサービス > Elastic Container Service Taskを選択
- 許可ポリシーをアタッチ:
AmazonECSTaskExecutionRolePolicy
- ロール名: ecs-task-execution
4-3. ECSタスク定義の作成
- タスク定義ファミリー: ecs-hands-on-api
- 起動タイプ: AWS Fargate
- リソース: CPU .25vCPU / メモリ .5GB
- タスク実行ロール: ecs-task-execution
コンテナ設定
| 設定項目 | 値 | 備考 |
|---|---|---|
| 名前 | api |
|
| イメージURI | ECRでプッシュしたURI | |
| コンテナポート | 8080 (TCP) | アプリのポートを8080で設定する想定 |
| HealthCheck | CMD-SHELL,curl -f http://localhost:8080/healthz |
🛡️ Step 5: セキュリティグループの作成
5-1. ALB用セキュリティグループ
- 名前: ecs-hands-on-alb
- インバウンドルール: HTTP (80) / Anywhere-IPv4 (0.0.0.0/0)
-
アウトバウンドルール:
- タイプ: すべてのトラフィック
- 送信タイプ: カスタム
- 送信先: 0.0.0.0/0
- タグ
- Name: ecs-hands-on-alb
5-2. ECSタスク用セキュリティグループ
- 名前: ecs-hands-on-backend
-
インバウンドルール:
- タイプ: カスタムTCP
- ポート範囲: 8080
- ソース: ecs-hands-on-alb のセキュリティグループID
-
アウトバウンドルール:
- タイプ: すべてのトラフィック
- 送信タイプ: カスタム
- 送信先: 0.0.0.0/0
- タグ
- Name: ecs-hands-on-backend
ポイント: ALBからのトラフィック(ポート8080)のみを許可します。
🌐 Step 6: ロードバランサー (ALB) とターゲットグループの設定
6-1. ターゲットグループの作成 (EC2 > ターゲットグループ)
- ターゲットの種類: IPアドレス
- ターゲットグループ名: ecs-hands-on-api
- プロトコル/ポート: HTTP / 8080
- VPC:
ecs-hands-on - ヘルスチェックパス: /healthz
- ヘルスチェックの詳細設定: 3/2/5/10 (推奨値)
6-2. ALBの作成 (EC2 > ロードバランサー)
- 名前: ecs-hands-on-alb
- スキーム: インターネット向け
- VPC:
ecs-hands-on - AZとサブネット: public-subnet-1a と public-subnet-1c の両方を指定
- セキュリティグループ: ecs-hands-on-alb を選択
リスナー設定
- プロトコル: HTTP / ポート: 80
- デフォルトアクション: ターゲットグループ ecs-hands-on-api へ転送
🚀 Step 7: ECSサービスの作成と結合
7-1. ECSサービスの作成
- タスク定義ファミリー:
ecs-hands-on-api/ リビジョン: 最新 - サービス名: ecs-hands-on-api
- 必要なタスク: 1
- 起動タイプ: Fargate
ネットワーキング設定
- VPC: ecs-hands-on
- サブネット: private-subnet-1a と private-subnet-1c を選択
- セキュリティグループ: ecs-hands-on-backend を選択 (デフォルトは外す)
- パブリックIP: オフ
7-2. ロードバランシングの設定
- ロードバランサー名: ecs-hands-on-alb
- Application Load Balancer: 既存のロードバランサーを使用
- 既存リスナー: HTTP:80
- ターゲットグループ: ecs-hands-on-api を選択し、本番リスナーとして登録
✅ Step 8: 動作確認
ALBのDNS名を取得し、アプリケーションにアクセスできるか確認します。

トラブルシューティングのヒント
-
タスクがPending/Stoppedになる:
ecs-task-executionロールに、ECRのアクセス権限が正しく付与されているか確認してください - ALBが503を返す: ターゲットグループのヘルスチェックが成功しているか確認してください。ECSタスクのセキュリティグループがALBからのポート8080を許可しているかも重要です
- ECSタスクがECRからイメージをPullできない ECSのセキュリティグループのアウトバウンドが正しく設定されているか確認してください。
これで、AWS Fargate/ECS/ALBを使用したセキュアでスケーラブルなコンテナ実行環境の構築が完了です!お疲れ様でした。