はじめに
この記事では、AWS CloudFormation テンプレートを使って、Fargate 上で動作する ECS クラスタと MySQL を利用した RDS インスタンスを構築する方法について解説します。
個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。
AWS のインフラをコードで管理し、自動的に一貫した構成を作成・更新できる Infrastructure as Code(IaC)の基本的な理解にも役立ちます。
書こうと思ったきっかけ
筆者自身が AWS を学び始めたとき、ネット上のテンプレート例は多くあるものの、実際にどのリソースが何をしているのかが掴みにくいと感じました。
このテンプレートは、自分で ECS + RDS を構築する中で整理したものであり、初心者の方でも全体像をつかめるように解説を加えました。
実際のテンプレート
test.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
# VPCの作成
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: "10.0.0.0/16"
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: "Name"
Value: "honda-vpc"
# サブネットの作成
PublicSubnet1:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref VPC
CidrBlock: "10.0.0.0/20"
AvailabilityZone: "ap-northeast-1a"
Tags:
- Key: "Name"
Value: "honda-subnet-public1-ap-northeast-1a"
PublicSubnet2:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref VPC
CidrBlock: "10.0.16.0/20"
AvailabilityZone: "ap-northeast-1c"
Tags:
- Key: "Name"
Value: "honda-subnet-public2-ap-northeast-1c"
# インターネットゲートウェイの設定
InternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: "Name"
Value: "honda-igw"
AttachInternetGateway:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# ルートテーブルの設定
PublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: "Name"
Value: "honda-rtb-public"
PublicRoute:
Type: "AWS::EC2::Route"
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
# ECS用セキュリティグループ(HTTPとMySQLに対応)
SecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Allow HTTP and MySQL traffic"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: "tcp"
FromPort: 80
ToPort: 80
CidrIp: "0.0.0.0/0"
- IpProtocol: "tcp"
FromPort: 8000
ToPort: 8000
CidrIp: "0.0.0.0/0"
- IpProtocol: "tcp"
FromPort: 3306
ToPort: 3306
CidrIp: "0.0.0.0/0" # 本番では特定のRDSセキュリティグループに制限推奨
# RDSのセキュリティグループ(必要に応じて制限可能)
RDSSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Allow ECS to access RDS"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref SecurityGroup
# RDSインスタンスの作成
MyRDS:
Type: "AWS::RDS::DBInstance"
Properties:
DBInstanceIdentifier: "honda-mysql-db"
AllocatedStorage: 20
DBInstanceClass: db.t4g.micro
Engine: mysql
EngineVersion: "8.0"
MasterUsername: "youruser"
MasterUserPassword: "yourpassword"
VPCSecurityGroups:
- !Ref RDSSecurityGroup
DBName: "yourdatabase"
DBSubnetGroupName: !Ref DBSubnetGroup
PubliclyAccessible: false
BackupRetentionPeriod: 0
# DBサブネットグループ(RDSに必要、2つのAZにまたがる)
DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription: "Subnets for RDS"
SubnetIds:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
DBSubnetGroupName: "honda-db-subnet-group"
# ECSクラスターの作成
ECSCluster:
Type: "AWS::ECS::Cluster"
Properties:
ClusterName: "my-ecs-cluster"
# ECSタスク定義(環境変数にRDS情報を追加)
ECSTaskDefinition:
Type: "AWS::ECS::TaskDefinition"
Properties:
Family: "my-app-task"
RequiresCompatibilities:
- FARGATE
NetworkMode: "awsvpc"
Cpu: "256"
Memory: "512"
ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
ContainerDefinitions:
- Name: "my-app-container"
Image: "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/backend-repo"
PortMappings:
- ContainerPort: 8000
HostPort: 8000
Protocol: "tcp"
Environment:
- Name: MYSQL_HOST
Value: !GetAtt MyRDS.Endpoint.Address
- Name: MYSQL_USER
Value: "youruser"
- Name: MYSQL_PASSWORD
Value: "yourpassword"
- Name: MYSQL_DATABASE
Value: "yourdatabase"
# ECSタスク実行ロール
ECSTaskExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "ecs-tasks.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "ecsTaskExecutionPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "ecr:GetAuthorizationToken"
- "ecr:GetDownloadUrlForLayer"
- "ecr:BatchGetImage"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
- "s3:GetObject"
Resource: "*"
# ECSサービスの作成
ECSService:
Type: "AWS::ECS::Service"
Properties:
Cluster: !Ref ECSCluster
TaskDefinition: !Ref ECSTaskDefinition
DesiredCount: 1
LaunchType: "FARGATE"
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref SecurityGroup
AssignPublicIp: "ENABLED"
1. VPCとサブネットの作成
VPC
- CIDR ブロック
10.0.0.0/16
を持つ仮想ネットワークを作成します。 - DNS サポートと DNS ホスト名の利用を有効化。
- タグ
Name: honda-vpc
が付与されます。
サブネット
-
ap-northeast-1a
とap-northeast-1c
にまたがる2つのパブリックサブネットを作成。 - それぞれ
10.0.0.0/20
と10.0.16.0/20
のCIDRブロック。
2. インターネット接続の構成
インターネットゲートウェイ
- VPCと接続することで外部アクセスを可能にするためのゲートウェイです。
ルートテーブル
-
0.0.0.0/0
(全ての宛先)へのルートをインターネットゲートウェイに設定。 - 作成したサブネットと関連付けられます。
3. セキュリティグループ
ECS 用セキュリティグループ
- HTTP(ポート80)とアプリケーション用(ポート8000)、MySQL(ポート3306)へのアクセスを許可。
- 本番環境では IP 制限や他のセキュリティグループとの関連付けを推奨。
RDS 用セキュリティグループ
- ECS セキュリティグループからの 3306 ポートアクセスのみを許可。
4. RDS(MySQL)構成
- インスタンス識別子
honda-mysql-db
、インスタンスクラスdb.t4g.micro
。 - エンジン: MySQL 8.0。
- パスワードやユーザー名はベタ書きされており、Parameter Storeなどを使って安全に管理すべきです。
- DBサブネットグループは、異なるAZにあるサブネット2つを含む必要があります。
5. ECS クラスタとサービス
ECS クラスタ
- 名前付き ECS クラスタを作成。
ECS タスク定義
-
FARGATE
対応。 - 環境変数に RDS 接続情報を設定。
- コンテナのポートは 8000 に設定。
タスク実行ロール
- ECS タスクが ECR(コンテナレジストリ)やログサービス(CloudWatch Logs)にアクセスするための IAM ロール。
ECS サービス
- 1つのタスクを常に稼働させる構成。
- パブリックサブネット上で稼働。
- セキュリティグループを指定し、パブリックIPを割り当てる設定(AssignPublicIp: ENABLED)。
まとめ
このテンプレートでは、VPCからECS、RDSまで、Webアプリケーションを構成するための基本的なインフラ構成が整っています。
セキュリティやスケーラビリティを高めるためには、以下の点を追加・改善するとより実践的になります。
- Secrets Manager で DB パスワードの管理
- ALB(Application Load Balancer)の追加
- Auto Scaling の設定
- CloudWatch メトリクスやログのより詳細な設定
この構成は学習用途としても、小規模なプロジェクトのベースとしても適しています。テンプレートの全体像を理解し、インフラ構築の第一歩として活用いただければ幸いです!