もふもふ技術部

IT技術系mofmofメディア

serverless framework でバブリックアクセス可能なmysqlを立ててみた

やること

serverless frameworkを利用してmysqlを構築できるようにします。 aws自体の学習を含む内容となります。(VPCの構築) 主にcloudformationをserverless frameworkにより作成している形になります。

実装

流れ

VPC環境を構築し、そこにDBインスタンスを追加していく形になります。

  1. VPCの作成
  2. ルートテーブルの作成
  3. インターネットゲートウェイの作成
  4. インターネットゲートウェイVPCに接続
  5. ルートの設定
  6. サブネットの作成
  7. セキュリティグループの作成
  8. インバウンドルールを設定
  9. DBサブネットグループを作成
  10. DBインスタンスを作成

以下 Resources 内に追加する内容となります。

1. VPCの作成

VPCの本体を作成します。

VPC:
  Type: AWS::EC2::VPC
  DeletionPolicy: Delete
  Properties:
    CidrBlock: 10.0.0.0/16 # 任意
    EnableDnsSupport: true
    EnableDnsHostnames: true
    Tags:
      - Key: Name
        Value: serverless-rds # 任意

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html

2. ルートテーブルの作成

VPC内部の通信経路の設定に基板のルートテーブルを作成

RouteTable:
  Type: AWS::EC2::RouteTable
  Properties:
    VpcId: !Ref VPC
    Tags:
      - Key: Name
        Value: serverless-rds-public-route-table # 任意

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html

3. インターネットゲートウェイの作成

VPCとインターネットの通信を可能とするためのインターネットゲートウェイを作成 (ここでは作成のみを行いどのリソースとも接続がされていない)

InternetGateway:
  Type: AWS::EC2::InternetGateway
  Properties:
    Tags:
      - Key: Name
        Value: serverless-rds-igw

4. インターネットゲートウェイVPCに接続

3で作成したインターネットゲートウェイVPCに接続し、外部とVPCの接続経路を確立

VPCGatewayAttachment:
  Type: AWS::EC2::VPCGatewayAttachment
  Properties:
    VpcId: !Ref VPC
    InternetGatewayId: !Ref InternetGateway

5. ルートの設定

2・3で作成したルートテーブルとインターネットゲートウェイを紐付けて、サブネットの接続する経路を作成する。

Route:
  Type: AWS::EC2::Route
  Properties:
    RouteTableId: !Ref RouteTable
    DestinationCidrBlock: 0.0.0.0/0
    GatewayId: !Ref InternetGateway

6. サブネットの作成

DBインスタンスを作成するにはサブネットが2以上必要なので2つのサブネットを作成する。 また2で作成し、5で設定を行ったルートテーブルと紐付けて通信経路を確立する。

PublicSubnetA:
  Type: AWS::EC2::Subnet
  Properties:
    VpcId: !Ref VPC
    CidrBlock: 10.0.64.0/20 # 任意
    AvailabilityZone: us-east-1a # 任意
    Tags:
      - Key: Name
        Value: serverless-rds-public-subnet-a # 任意

SubnetRouteTableAssociationPublicSubnetA:
  Type: AWS::EC2::SubnetRouteTableAssociation
  Properties:
    RouteTableId: !Ref RouteTable
    SubnetId: !Ref PublicSubnetA

PublicSubnetB:
  Type: AWS::EC2::Subnet
  Properties:
    VpcId: !Ref VPC
    CidrBlock: 10.0.80.0/20 # 任意
    AvailabilityZone: us-east-1b # 任意
    Tags:
      - Key: Name
        Value: serverless-rds-public-subnet-b # 任意

SubnetRouteTableAssociationPublicSubnetB:
  Type: AWS::EC2::SubnetRouteTableAssociation
  Properties:
    RouteTableId: !Ref RouteTable
    SubnetId: !Ref PublicSubnetB

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html

7. セキュリティグループの作成

リソースへのアクセスを制限するためのセキュリティグループを作成する。

SecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupName: serverless-rds # 任意
    GroupDescription: Security Group for serverless-rds # 任意
    VpcId: !Ref VPC

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html

8. インバウンドルールを設定

10で作成するMySQLへのアクセス設定を追加する。

SecurityGroupIngress:
  Type: AWS::EC2::SecurityGroupIngress
  Properties:
    IpProtocol: tcp
    CidrIp: <任意のIPアドレス> # 接続を許可するIPを設定
    GroupId: !GetAtt SecurityGroup.GroupId
    ToPort: 3306 # fromとtoでどこからどこまでの範囲のポートを解放するのかを設定する
    FromPort: 3306

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html

9. DBサブネットグループを作成

DBサーバーを作成する際に割り当てるIPアドレスの範囲の設定 6で作成したサブネットを使用する。 2つ以上のサブネットが必要

DBSubnetGroup:
  Type: AWS::RDS::DBSubnetGroup
  Properties:
    DBSubnetGroupName: serverless-rds-db-subnetgroup # 任意
    DBSubnetGroupDescription: "serverless-rds subnet" # 任意
    SubnetIds:
      - !GetAtt PublicSubnetA.SubnetId
      - !GetAtt PublicSubnetB.SubnetId

10. DBインスタンスを作成

RDS上にDBインスタンスを作成する。 詳細はコード上にコメントで表示。 内部を書き換えることにより、mysql以外のDBエンジンでの作成も可能です。

DBInstance:
  Type: AWS::RDS::DBInstance
  Properties:
    AllocatedStorage: "20" # ストレージの容量
    AvailabilityZone: !GetAtt PublicSubnetA.AvailabilityZone # インスタンスを作成するアベイラビリティゾーン
    BackupRetentionPeriod: 7 # 自動バックアップが保持される日数
    CopyTagsToSnapshot: true # スナップショットにタグをコピーする
    DBInstanceClass: db.t2.micro # メモリ容量
    DBInstanceIdentifier: serverless-rdb-db-instance # インスタンス名
    DBName: mydb # 初回に自動で作成するdatabase名 必須ではない
    DBSubnetGroupName: !Ref DBSubnetGroup
    Engine: MySQL # DBエンジンの設定 postgres aurora など
    MasterUsername: admin # mysqlのユーザー名
    MasterUserPassword: # mysqlのパスワード
    MaxAllocatedStorage: 1000 # ストレージのオートスケーリングの最大値
    Port: "3306" # 接続を受け入れるポート
    PubliclyAccessible: true # ネットからの接続を可能にする
    # StorageEncrypted: true # インスタンスの暗号化設定 db.t2.microではサポートしていない
    StorageType: gp2 # ストレージタイプ
    VPCSecurityGroups:
      - !GetAtt SecurityGroup.GroupId
  DeletionPolicy: Snapshot

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbinstance.html

最後にserverless deployコマンドでデプロイを行えば自動でmysqlサーバーが作成されます。

以上でmysqlの構築は完了となります。serverless-mysqlprismaなどと繋げて利用できるようになったかと思います。 作成したDBインスタンスAWS RDS上で確認が可能です。

まとめ

serverless frameworkでcloudformationを操作できることを理解してきたための挑戦でした。 Resourceをうまく利用することで今回のようにmysqlを構築するだけでなくさまざまな環境を容易に作成できるのはとても面白いなと感じました。 今後は他の構成も積極的に作ってみたいです。

会社の紹介

株式会社 mofmof では一緒に働いてくれるエンジニアを募集しています。 興味のある方は是非こちらのページよりお越しください! https://www.mof-mof.co.jp/ https://www.mof-mof.co.jp/recruit/

最後に

serverless removeコマンドで一括でVPCごと削除できるのは楽でいいですね。試してみるにはちょうどいいですね。cloudformation最高!