はじめに
クラウド上でアプリケーションを効率よく動かす仕組みとして「コンテナ」が一般的になり、AWSでも数多くのサービスが提供されています。その中でも Amazon ECS(Elastic Container Service) は、コンテナを簡単に実行・管理できるマネージドサービスとして多くの現場で使われています。
しかし、初めて学ぶ方にとっては「タスク定義」「サービス」「Fargate」「ALB」「CloudWatch」など聞き慣れない言葉が多く、全体像をつかみにくいのも事実です。
そこで本記事では、以下の流れで ECSを実際に触りながら学べる入門ハンズオン を紹介します。
- ECSの全体像を理解(タスク定義とサービスの役割)
- DockerイメージをECRにpushし、Fargateでデプロイ
- パブリックIPやALBで公開し、実際にアクセス確認
- CloudWatchを使ったログ・メトリクス監視とオートスケーリング
ただ動かすだけでなく、運用監視までを体験することで、ECSを本番環境で活用するイメージが持てるようになるのがゴールです。
ECSタスク定義を理解する
タスク定義とは
ECSでコンテナを動かす際の“設計図”にあたるのが タスク定義 です。
ここで指定した内容をもとに、ECSは実際のタスク(コンテナ群)を起動します。
設定できる主な項目
タスク定義で設定できる主な項目は次のとおりです。
区分 | 項目 | 説明 / ポイント |
---|---|---|
基本情報 | タスク定義ファミリー | タスク定義の名前(設計図のグループ名)。1つのファミリー名に対してバージョン番号が付与される(例: myapp:1 → myapp:2 )。 |
インフラ要件 | 起動タイプ | Fargate:サーバーレス、運用不要、学習〜中規模向け。EC2:自分でEC2管理、柔軟性ありだが運用コスト増。 |
OS / アーキテクチャ | 一般的には Linux/x86_64。Gravitonなどを使う場合は arm64。 | |
ネットワークモード | awsvpc(Fargate必須)。タスクごとに専用のENIを割り当て、パブリックIPやSGを直接設定可能。 | |
タスクサイズ | CPU / メモリ | タスク全体に割り当てるリソース。例:1 vCPU / 3 GB 。複数コンテナはこの枠を分け合う。 |
IAMロール | タスクロール(任意) | コンテナがAWS APIを直接利用する場合に必要。例:S3に保存する場合はS3権限を付与。 |
タスク実行ロール(必須) | コンテナエージェントが利用するロール。ECRからイメージ取得、CloudWatchログ送信に使用。通常は ecsTaskExecutionRole 。 | |
コンテナ定義 | 名前 | コンテナ識別名。複数コンテナを使う場合に必須。 |
イメージURI | 実行するコンテナイメージを指定。例:ECR xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest 、DockerHub nginx:latest 。 | |
ポートマッピング | 外部に公開するポートを指定。例:80/TCP 。アプリのLISTENポートと一致させる必要あり。 | |
環境変数 | アプリに渡す設定。例:ENV=production , DB_HOST=xxx 。Secrets ManagerやS3環境ファイルも利用可能。 | |
リソース制限(コンテナ単位) | CPU、メモリのハード/ソフト制限を設定可能。枠を超えるとコンテナは終了。 | |
読み取り専用ルートFS | / を読み取り専用にしてセキュリティ強化。 | |
ログ設定 | awslogs | CloudWatch Logs に標準出力を送信。主なキー:awslogs-group=/ecs/myapp awslogs-region=ap-northeast-1 awslogs-stream-prefix=ecs |
高度なオプション | 再起動ポリシー | コンテナが失敗したときに再起動するかどうか。 |
HealthCheck | コンテナの正常性チェック(例:HTTP 200 応答)。 | |
起動順序制御 | 複数コンテナの依存関係を設定。 | |
エフェメラルストレージ | 一時ストレージ容量。デフォルト20GB、最大200GBまで拡張可能。 | |
ボリューム | コンテナ間で共有するデータ領域を定義。 | |
モニタリング統合 | OpenTelemetry | AWS Distro for OpenTelemetry を使い、アプリのトレース・メトリクス収集が可能。 |
タグ | タグ | リソース整理用のメタデータ。例:env=dev , project=planit 。 |
つまりタスク定義とは、「どんなイメージを、どのリソースで、どんな設定で動かすか」をまとめた設計図 であり、ECSを使ううえで最も基本となる要素です。
サービスを理解する
サービスとは
ECSの サービス(Service) は、タスクを「安定して動かし続ける」ための仕組みです。
単発でタスクを実行するだけでは、停止するとそこで終わってしまいます。サービスを利用すると、以下のような運用が自動化されます。
- 常時稼働:指定した数のタスクを常に維持。万一タスクが落ちても自動で再起動。
- オートスケーリング:CPUやメモリ使用率に応じて、タスク数を自動で増減。
- ロードバランサー連携:ALB(Application Load Balancer)と組み合わせ、複数のタスクにトラフィックを分散。
つまりサービスは、単なる「タスク実行」から一歩進んで、本番環境向けにアプリを継続稼働させる仕組み だと理解すると分かりやすいです。
設定できる主な項目
区分 | 項目 | 説明 / ポイント |
---|---|---|
サービスの詳細 | タスク定義ファミリー | 既存のタスク定義ファミリーを選択。新規作成は「タスク定義」から行う。 |
タスク定義リビジョン | 最新の100件から選択可能。空欄なら最新リビジョンを使用。 | |
サービス名 | クラスター内で一意の名前。最大255文字。英数字、アンダースコア、ハイフンが利用可。 | |
環境 | 起動タイプに応じた環境を指定。例:Fargate。 | |
クラスター | デプロイ先のクラスターを指定。 | |
コンピューティング設定 | コンピューティングオプション | タスク配置方法を設定。基本は「起動タイプ」を指定。 |
キャパシティープロバイダー戦略 | 複数のプロバイダー(例:FARGATE / FARGATE_SPOT)を分散利用可能。ウェイトやベース値を調整可能。 | |
プラットフォームバージョン | Fargateのプラットフォームバージョン。通常は LATEST を推奨。 | |
デプロイ設定 | スケジューリング戦略 | レプリカ:指定数のタスクを維持。デーモン:各インスタンスに1つずつタスクを配置。 |
必要なタスク数 | 起動するタスクの数(例:1)。 | |
AZ再調整 | アベイラビリティゾーン間でタスク数を自動で均等化。 | |
ヘルスチェック猶予期間 | タスク起動直後にヘルスチェックを待機する秒数。 | |
ネットワーキング | Service Connect | サービス間通信を短縮名+標準ポートで自動検出可能にする機能。 |
サービス検出 | Route 53 のネームスペースを利用してサービスをDNS経由で検出可能に。 | |
ロードバランシング | ELB (ALB/NLB) を利用し、正常なタスクにトラフィックを分散。 | |
VPC Lattice | マルチアカウントや複数VPCにまたがるアプリ通信を統合管理するサービス(追加コストあり)。 | |
スケーリング | サービスの自動スケーリング | CloudWatch アラームをトリガーに、必要タスク数を自動調整。 |
ストレージ | ボリューム | タスク内のコンテナに追加ストレージを提供。 |
タグ | タグ | リソースを整理するためのメタデータ。例:env=dev , project=planit 。 |
ECSでアプリを公開する
まずは、ECSで動かすための サンプルアプリ を用意しましょう。
本格的なアプリでなくても大丈夫です。ここではシンプルなWebアプリを例にします。
サンプルアプリ開発
ファイル構成
以下のようなシンプルな構成にします。
ecs-sample/
├── app.js # アプリ本体
├── package.json # Node.js の依存関係定義
└── Dockerfile # コンテナ化するための設定
Node.js で簡単なWebサーバーを作成
app.js
const http = require("http");
const port = 3000;
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello ECS!");
});
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
package.json
依存関係を管理する設定ファイルを作成します。
{
"name": "ecs-sample",
"version": "1.0.0",
"main": "app.js"
}
Dockerfile を作成
このアプリをコンテナ化するために Dockerfile を用意します。
FROM node:22-alpine
USER node
WORKDIR /usr/src/app
COPY --chown=node:node package*.json ./
ENV NODE_ENV=production
RUN npm ci --omit=dev || npm install --omit=dev || true
COPY --chown=node:node . .
EXPOSE 3000
CMD ["node", "app.js"]
ローカルでの動作確認
- Dockerイメージをビルド
- コンテナを起動
- ブラウザまたは curl で確認
→Hello ECS!
と表示されれば成功です。
docker build -t ecs-sample .
docker run -d -p 3000:3000 ecs-sample
curl http://localhost:3000
ECRにPushする
ECRとは
ECR(Elastic Container Registry) は、AWSが提供するコンテナイメージの専用リポジトリサービスです。
GitHubでソースコードを管理するように、ECRではDockerイメージを安全に保存・管理できます。
Push手順
- ECRリポジトリを作成
- AWSマネジメントコンソール → 「ECR」 → 「リポジトリ作成」
- 設定内容はの意味は下記です。
項目 | 内容 | 設定内容 |
---|---|---|
リポジトリ名 | イメージを保存するリポジトリの名前 | myapp |
イメージタグのミュータビリティ | タグを上書きできるかどうか – Mutable: 上書き可能。開発や検証向き。 – Immutable: 上書き不可。リリース用に推奨。 | 今回はMutable |
変更可能なタグ除外(フィルター) | 特定のタグだけImmutableにする設定 | 今回は未設定 |


- AWS CLIでログイン
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 myapp .
docker build --provenance=false -t myapp . # macの場合はこちら
- ECR用にタグ付け
docker tag myapp:latest <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
- Push実行
docker push <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
これらのコマンドはECR内のプッシュコマンドを表示を押下すると確認できます。
そこからコピペで実行するのが早いです。
VPC作成
ECSを配置するための仮想ネットワーク「VPC(Virtual Private Cloud)」を作成します。
VPCはクラウド上に構築する自分専用のネットワーク空間で、IPアドレスの範囲や通信ルールを自由に設計できます。
作成手順(マネジメントコンソール)
- AWSマネジメントコンソールにログイン
- 「VPC」サービスに移動
- 左メニューの「VPC」→「VPCを作成」をクリック
- 以下を入力して作成
- 名前タグ:
sample-vpc
- 名前タグ:
- IPv4 CIDR ブロック:
10.0.0.0/16
- その他の設定はデフォルトのままでOK
- 「VPCを作成」ボタンをクリックして完了

設定値の意味
項目 | 設定例 | 説明 |
---|---|---|
名前タグ | sample-vpc | VPCの識別用の名前。わかりやすい名前をつけましょう。 |
IPv4 CIDR ブロック | 10.0.0.0/16 | VPC内で利用するプライベートIPアドレスの範囲を指定します。/16 だと最大65,536個のIPが使えます。 |
IPv6 CIDR ブロック | 無効または割り当てなし | 今回は使用しません(必要に応じて後から追加可能です)。 |
テナンシー | デフォルト | 「専有」ではなく「共有」ハードウェア上にインスタンスを配置する設定です(コスト面で一般的)。 |
これでどうなるか
このVPCは、今後作成するサブネットやインターネットゲートウェイ、ルートテーブルなどの土台になります。
この時点ではまだ通信はできませんが、次のステップでそれを可能にしていきます。
パブリックサブネット作成
VPC内にサブネット(Subnet) を作成します。
サブネットとは、VPC内でIPアドレスの範囲を区切るネットワークの一部であり、ECSを実際に配置する場所です。
今回は、インターネットに接続できる パブリックサブネット を作成します。
作成手順(マネジメントコンソール)
- 「VPC」サービスにアクセス
- 左メニューから「サブネット」→「サブネットを作成」をクリック
- 以下を入力:
- 名前タグ:
sample-vpc-1a
- VPC:
sample-vpc
- アベイラビリティゾーン:任意(例:
ap-northeast-1a
) - IPv4 CIDRブロック:
10.0.1.0/24
- 名前タグ:
- 下部オプションの「パブリック IPv4 アドレスの自動割り当て」に✔を入れる
- 「サブネットを作成」をクリック


設定値の意味
項目 | 設定例 | 説明 |
---|---|---|
名前タグ | sample-vpc- 1a | わかりやすい名称を付けましょう。 |
VPC | samole-vpc | 作成済みのVPCを指定します。 |
アベイラビリティゾーン(AZ) | ap-northeast-1a など | 任意のAZを選びます。同じリージョン内であればどれでも可。 |
IPv4 CIDR ブロック | 10.0.1.0/24 | このサブネットに割り当てるIPアドレス範囲。VPCのCIDRブロック内で重複しない範囲を指定します。 |
パブリック IPv4 アドレスの自動割り当て | 有効(✔ チェック) | インスタンス起動時に自動的にパブリックIPを割り当てる設定。パブリックサブネットに必須です。 |
これでどうなるか
インターネットに出られる準備が整ったサブネットが完成します。
- このサブネットに配置されるECSには、自動でパブリックIPアドレスが割り当てられます。
- ただし、まだ ルートテーブルでインターネットへの経路(IGW)を設定していないため、通信はできません。
インターネットゲートウェイの作成とアタッチ
何をするか
作成したVPCからインターネットにアクセスできるようにするために、インターネットゲートウェイ(IGW: Internet Gateway) を作成し、VPCに接続(アタッチ)します。
これにより、ECSが外部と通信できるようになります(例:Webアクセスやパッケージのインストールなど)。
IGWの作成手順
- AWSマネジメントコンソールで「VPC」サービスにアクセス
- 左メニューから「インターネットゲートウェイ」を選択
- 「インターネットゲートウェイを作成」をクリック
- 名前タグにsample-igwと入力
- 「インターネットゲートウェイを作成」をクリック

アタッチ手順
- 作成したIGWを選択
- 「アクション」→「VPCにアタッチ」をクリック
- 接続先VPCとして
を選択sample-vpc
- 「アタッチ」をクリック

これでどうなるか
- VPCにインターネットの出入口が接続されました。
- ただしこの時点ではまだルートテーブルの設定がされていないため、実際の通信はできません。
- 次のステップ(ルートテーブル作成)で、インターネット経路を明示的に指定します。
ルートテーブル設定
何をするか
ルートテーブル(Route Table) は、VPC内の通信ルート(経路)を定義するものです。
ここでは、パブリックサブネットからインターネットにアクセスできるようにするためのルートを設定します。
具体的には下記を行います。
0.0.0.0/0
(すべての外部アドレス)宛のトラフィックを インターネットゲートウェイ(IGW) に転送するルートを追加- そのルートテーブルをパブリックサブネットに関連付ける
作成手順(ルートテーブル)
- 「VPC」サービスにアクセス
- 左メニューから「ルートテーブル」→「ルートテーブルを作成」をクリック
- 以下を入力:
- 名前タグ:
sample-rt
- VPC:
sample-vpc
- 名前タグ:
- 「ルートテーブルを作成」をクリックして完了

ルートの追加手順
- 作成したルートテーブルを選択
- 「ルート」タブ → 「ルートを編集」をクリック
- 「ルートの追加」を押し、以下を入力:
- 送信先:
0.0.0.0/0
- ターゲット:作成済みの インターネットゲートウェイ(igw-xxxxxxx)
- 送信先:
- 「変更を保存」をクリック

サブネットとの関連付け手順
- 同じルートテーブル画面の「サブネットの関連付け」タブを開く
- 「サブネットの関連付けを編集」をクリック
sample-vpc-1a
を選択して「保存」

役割と設定内容
項目 | 設定例・内容 | 説明 |
---|---|---|
名前タグ | sample-rt | わかりやすい名前を設定 |
VPC |
| 作成済みのVPCを指定 |
ルートの送信先 | 0.0.0.0/0 | すべてのIPv4トラフィックを意味します |
ターゲット | igw-xxxxxxx (作成済みのIGW) | インターネットゲートウェイを指定します |
サブネットの関連付け | sample-vpc- 1a | 作成済みのサブネットと紐付けることで、このルートテーブルが適用されます |
これでどうなるか
対象のサブネット(=パブリックサブネット)からインターネットへ通信できる経路が確立されます。
0.0.0.0/0
のルートは、「すべての外部宛の通信」を意味し、- それを インターネットゲートウェイ(IGW)に向けることで、ECSから外部ネットワーク(インターネット)への送信が可能になります。
ただし、この時点ではまだECSへの外部からのアクセスはできません。
- なぜなら、セキュリティグループ(ファイアウォール)の設定がまだ行われていないためです。
- セキュリティグループで必要なポート(SSH:22、HTTP:80など)を開放しない限り、外部からの通信は遮断されたままとなります。
セキュリティグループ設定
何をするか
セキュリティグループ(Security Group) は、ECSの 仮想ファイアウォール です。
ここでは、外部からWebブラウザでECSにアクセスしたりするために必要な通信ポートを開放します。
作成手順
- 「EC2」サービスにアクセス
- 左メニューから「セキュリティグループ」→「セキュリティグループを作成」
- 以下を入力:
- 名前:
sample-sg
- 説明:サンプル用セキュリティグループ
- VPC:
sample-vpc
(作成済みのVPCを選択)
- 「インバウンドルールを追加」をクリックし、以下を追加
タイプ | プロトコル | ポート | ソース |
---|---|---|---|
HTTP | TCP | 80 | 0.0.0.0/0 |
HTTPS | TCP | 443 | 0.0.0.0/0 |
カスタム TCP | TCP | 3000 | 0.0.0.0/0 |


これでどうなるか
このセキュリティグループをECSに適用することで、次のような通信が許可されます
- httpを利用し3000番ポートにアクセス
クラスターを作成する
まずは、ECSでアプリを動かすための「クラスター」を作成します。クラスターは、コンテナを実行する基盤となるリソースのまとまりです。
- ECSコンソール → 左メニューから「クラスター」 → 「クラスターの作成」

- 設定
- クラスター名:わかりやすい名前を入力(例:
my-ecs-cluster
)
インフラストラクチャー:ここではシンプルに Fargate を選択
(EC2モードを使う場合は、後でEC2インスタンスの準備が必要になります)
- クラスター名:わかりやすい名前を入力(例:
- 作成 → 数十秒でクラスターができあがります。
タスク定義を作成する
タスク定義は「コンテナの設計図」です。
- ECSコンソールに移動
左メニューから「タスク定義」 → 「新しいタスク定義を作成」

- タスク定義ファミリー名
- 名前:
myapp-task
(自由でOK)
- 名前:

- 起動タイプ
Fargate
を選択(インフラ管理不要で初心者に最適)

- タスクサイズ
- CPU:1 vCPU
- メモリ:2 GB 〜 3 GB

- コンテナ定義を追加
- 名前:
myapp-container
- イメージURI:
<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
- ポートマッピング:80、3000
- 名前:


- ログ出力
- グループ名:
/ecs/myapp
-task - リージョン:
ap-northeast-1
- グループ名:

サービスを作成する
サービスは「タスクを安定して動かす仕組み」です。
- ECSコンソール → クラスター
- 事前に作った
my-ecs-cluster
を選択 - 「サービス」タブ → 「作成」
- 事前に作った
- 基本設定
- タスク定義:
先ほど作成したmyapp-task
- タスク定義のリビジョン
:1
- 起動タイプ:
Fargate
- サービス名:
myapp-service
- タスク数:1(最初は1でOK)
- タスク定義:

- ネットワーク設定
- VPC:先ほど作成したVPC
- サブネット:先ほど作成した、パブリックサブネットを選択
- セキュリティグループ:先ほど作成したセキュリティグループを選択
- パブリックIP割り当て:有効化(ONにするのを忘れない!)
実行〜動作確認
タスクの実行状態を確認する
- ECS コンソールにアクセスし、対象のクラスター → サービス → タスクを開きます。
- ステータスが実行中 になっていることを確認します。

アプリにアクセスできるか確認する
- タスク詳細画面に表示される Public IPv4 address をコピーします。
- ブラウザまたはターミナルから以下のようにアクセスします。
http://{パブリックIP}:3000

まとめ
ECSでは、タスク定義がコンテナ実行の設計図となり、サービスが安定稼働を担います。
ECRにイメージをPushしてFargateで実行すれば、パブリックIPから動作確認が可能です。
さらにCloudWatchでログやメトリクスを監視し、オートスケーリングを設定することで、本番運用に耐える環境を整えられます。
コメント