0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ハッカソン個人備忘録⑳:FastAPIを動かすためのFargate×RDS(MySQL)構成をCloudFormationで自動化してみた

Posted at

はじめに

この記事では、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-1aap-northeast-1c にまたがる2つのパブリックサブネットを作成。
  • それぞれ 10.0.0.0/2010.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 メトリクスやログのより詳細な設定

この構成は学習用途としても、小規模なプロジェクトのベースとしても適しています。テンプレートの全体像を理解し、インフラ構築の第一歩として活用いただければ幸いです!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?