
今回はめんどくさいのでCloudformation で一気にECSの環境を作成します。
リージョンはus-east-1 で作成する前提です。テンプレートは下記を使ってみてください
AWSTemplateFormatVersion: "2010-09-09" # このテンプレートのバージョンを指定します(CloudFormation用)
Description: ECS Fargate Service with NGINX and full VPC setup + CloudWatch Logs # テンプレートの簡単な説明です
Resources: # ここからリソース定義が始まります
# VPC
MyVPC:
Type: AWS::EC2::VPC # VPC(仮想ネットワーク)を作成します
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags: # リソースに名前などのタグを付けます
- Key: Name
Value: MyECSVPC
# Internet Gateway
InternetGateway:
Type: AWS::EC2::InternetGateway # インターネットゲートウェイを作成します(外部との通信に必要)
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment # VPC(仮想ネットワーク)を作成します
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref InternetGateway
# Public Subnets
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true # 起動するインスタンスにパブリックIPを自動で割り当てます
AvailabilityZone: !Select [0, !GetAZs ''] # サブネットを配置するアベイラビリティゾーンを指定します
Tags: # リソースに名前などのタグを付けます
- Key: Name
Value: PublicSubnet1
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.2.0/24
MapPublicIpOnLaunch: true # 起動するインスタンスにパブリックIPを自動で割り当てます
AvailabilityZone: !Select [1, !GetAZs ''] # サブネットを配置するアベイラビリティゾーンを指定します
Tags: # リソースに名前などのタグを付けます
- Key: Name
Value: PublicSubnet2
# Route Table for public subnets
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
SubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
SubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
# Security Group
ECSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP
VpcId: !Ref MyVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
# ECS Cluster
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: MyCluster
# CloudWatch Log Group
MyLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /ecs/nginx-fargate
RetentionInDays: 7
# IAM Role for ECS Task Execution
ECSTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
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
Policies:
- PolicyName: AllowCWLogs
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
# ECS Task Definition
MyTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: nginx-fargate-task
Cpu: 256
Memory: 512
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
ContainerDefinitions:
- Name: nginx
Image: nginx:latest
PortMappings:
- ContainerPort: 80
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: /ecs/nginx-fargate
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: nginx
# ECS Service
ECSService:
Type: AWS::ECS::Service
DependsOn: MyLogGroup
Properties:
Cluster: !Ref ECSCluster
DesiredCount: 1
LaunchType: FARGATE
TaskDefinition: !Ref MyTaskDefinition
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ECSSecurityGroup
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
HealthCheckGracePeriodSeconds: 60
Outputs:
ServiceName:
Description: ECS Service Name # テンプレートの簡単な説明です
Value: !Ref ECSService
LogGroupName:
Description: CloudWatch Log Group # テンプレートの簡単な説明です
Value: /ecs/nginx-fargate
ClusterName:
Description: ECS Cluster # テンプレートの簡単な説明です これで終了
Value: !Ref ECSCluster
大体10分程度で、作成が終了するはずです。完了したら、ECSのタスクからみえるパブリックアドレスをクリックすれば、NGINXの画面を確認できます

これをクリック

NGINXの画面が見えるはずです

各設定と重要な概念
デプロイに成功したら、ECSの概念について説明します。CloudFormation でデプロイが確認できたら下記の項目をGUIで確認するといいと思います。
1. クラスター(Cluster)
- 定義: ECS におけるコンテナの実行環境(インフラ)をまとめた論理的なグループ。
- 存在意義: タスクやサービスを管理・スケジューリングする単位。Fargate や EC2 を使ってリソース(CPUやメモリ)を提供。
- テンプレート内:
ECSCluster
リソースとして定義。
GUIではこのように確認できます

2. タスク定義(Task Definition)
- 定義: コンテナの設定(イメージ、CPU、メモリ、環境変数など)をまとめたレシピ。
- 存在意義: ECS サービスがどのようなアプリケーションを動かすかを定義する。Docker の
docker-compose.yml
に近い。 - テンプレート内:
ECSTaskDefinition
リソースにて設定(コンテナ定義やログ設定などが含まれる)。

3. タスク(Task)
- 定義: タスク定義に基づいて起動された実行単位。1つ以上のコンテナで構成。
- 存在意義: 実際にアプリケーションコードが動作する単位。スケーリングの基本単位でもある。
- テンプレート内: 明示的には定義されていないが、サービスによって自動的に起動される。

4. サービス(Service)
- 定義: 指定された数のタスクを常に実行し続ける ECS のリソース。タスクのローリング更新やヘルスチェックも管理。
- 存在意義: 高可用性を担保し、ロードバランサーとの統合も可能。デプロイの継続性と安定性を支える。
- テンプレート内:
ECSService
リソースにより、1タスクを起動し続ける設定。

5. Fargate
- 定義: サーバーレスなコンテナ実行エンジン。EC2のようなインスタンス管理が不要。
- 存在意義: インフラを意識せずにコンテナを動かせる。スケーラブルで自動管理。
- テンプレート内: タスク定義に
"RequiresCompatibilities": ["FARGATE"]
とあることで、Fargate を使用していることが明示されている。

ネットワーク構成
今回のネットワーク構成は簡単で次のようになっています
[ VPC: 10.0.0.0/16 ]
├─ Subnet1: 10.0.1.0/24 ─┐
├─ Subnet2: 10.0.2.0/24 ─┘
↓
[ Route Table ]
└─ Route: 0.0.0.0/0 → InternetGateway
↓
[ Internet Gateway ] ← 外部と通信可能
1. VPC(Virtual Private Cloud)とは?
- 定義: AWS 内で自分専用の仮想ネットワーク。
- 存在意義: IP アドレス範囲(CIDR)を指定して、セキュアに AWS リソースを配置・管理できる領域。
- このテンプレートでは:
Vpc
リソースとして10.0.0.0/16
の範囲で定義。
2. サブネット(Subnet)とは?
- 定義: VPC をさらに分割した小さなネットワーク。
- 存在意義: AWSリソースを異なる「ゾーン」や「機能ごとの区画」に配置して冗長性やセキュリティを高める。
- テンプレートでは:
Subnet1
(10.0.1.0/24)とSubnet2
(10.0.2.0/24)を定義。
GUIで見るとこのような感じになる。これらのサブネットは10から始まる内部IPしか持っていないので、インターネットゲートウェイが必要になります。

なぜサブネットを2つ作るのか?
- 理由①: 高可用性の確保
- 各サブネットは異なるアベイラビリティゾーン(AZ)に配置。
- Fargate や ELB などのサービスは複数のAZにまたがることで、片方のゾーンが落ちても継続できる。
- 理由②: ロードバランシング対応
- ALB(Application Load Balancer)を使うときは、少なくとも2つの AZ(=サブネット)にまたがって配置する必要がある。
- 理由③: 将来の分離設計
- Public subnet / Private subnet に分けて NAT gateway なども使えるようにする拡張性のため。
3. インターネットゲートウェイ(Internet Gateway)とは?
- 定義: VPC 内のリソースがインターネットと通信するための「出入り口」。
- 存在意義: VPC に接続し、ルートテーブル経由で外部へのトラフィックを可能にする。
- テンプレートでは:
InternetGateway
リソースとして作成し、AttachGateway
によってVpc
にアタッチしている。
GUIではVPCの設定から確認できます

4. ルートテーブルとルート(RouteTable, Route)
- ルートテーブルとは?
- サブネットから外部(他のサブネット、インターネット、VPNなど)への通信ルールを定めるもの。
- ルートとは?
- 実際の「行き先」と「どのゲートウェイやターゲットを通るか」の設定。
VPCのリソースマップで見てみましょう

サブネットがルートテーブルに紐づいているのがわかります。ルートテーブルはどうなっているのかというと

となっていて、サブネットの関連付けでは、2つのサブネットに紐づけられています

テンプレート内の例:
RouteTable
→ VPC用のルートテーブルDefaultRoute
→0.0.0.0/0
(全トラフィック)をInternetGateway
にルーティングSubnetRouteTableAssociation1
/2
→ 各サブネットをこのルートテーブルに紐づけ
5. サブネットとルートの関係
- サブネット単体ではインターネットアクセス不可。
- サブネットが「ルートテーブル」で
0.0.0.0/0 → InternetGateway
を持っていれば、「Public Subnet」と見なされ、外部アクセスが可能。 - このテンプレートでは、2つのサブネットともインターネットアクセス可能な構成(=パブリックサブネット)。