CloudFormaitonを使ってRDSでMySQLをマルチAZで構築する。

今回はCloudFormaitonを使ってRDSでMySQLをマルチAZで構築する手順を説明します。

#前提条件
- Windows10を使用。
- PCはDELLを使用。
- ファイルの拡張子は.ymlを使用。
- 東京リージョンを使用。
- アベイラビリティゾーンは1aと1cを使用。
- DBはMySQLを選択。

#料金
テンプレート自体に料金は発生しないが、作成後のAWSリソースに関しては料金が発生しますのでご注意下さい。
RDSは**<font color="Red">非常に高額</font>**なのでハンズオンのみの使用であれば即時に削除をお願い致します。

#事前準備
- AWSアカウントを所持していること。
- Amazon VPCへのアクセス権限（書き込み・読み取り）を許可していること。
- AWS Cloudformationへのアクセス権限（書き込み・読み取り）を許可していること。
- AWS RDSへのアクセス権限（書き込み・読み取り）を許可していること。
- VPCとpublic subnetとprivate subnetが作成済みであること。
- EC2インスタンスはLinuxであること。
- ネットワーク構成がpublic subnetとprivate subnetのEC2インスタンスをそれぞれ作成していること。
- public subnetはIGWを介してインターネットアクセスできること。
- private subnetはNatGatewayを介してインターネットにアクセスできること。
- private subnetのEC2インスタンスにMySQLがインストールされていること。

#構築内容
- 東京リージョンにRDSでMySQLをマルチAZで構築。
- private subnetを介してDBへアクセス。

#テンプレート
RDSの作成のスタックは以下の通りです。

```yml:rds_create.yml
AWSTemplateFormatVersion: "2010-09-09"
Description:
  Cloudformation RDS for  MySQL Create

#各種メタデータ一覧
Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "Project Name Prefix"
        Parameters:
          - PJPrefix
      - Label:
          default: "RDS Configuration"   
        Parameters:
          - DBInstanceName
          - MySQLMajorVersion　
          - MySQLMinorVersion
          - DBInstanceClass
          - DBInstanceStorageSize
          - DBInstanceStorageType
          - DBName
          - DBMasterUserName
          - DBPassword
          - MultiAZ
    ParameterLabels:
      DBInstanceName:
        default: "DBInstanceName"
      MySQLMajorVersion:
        default: "MySQLMajorVersion"
      MySQLMinorVersion:
        default: "MySQLMinorVersion"
      DBInstanceClass:
        default: "DBInstanceClass"
      DBInstanceStorageSize:
        default: "DBInstanceStorageSize"
      DBInstanceStorageType:
        default: "DBInstanceStorageType"
      DBName:
        default: "DBName"
      DBMasterUserName:
        default: "DBMasterUserName"
      DBPassword:
        default: "DBPassword"
      MultiAZ:
        default: "MultiAZ"

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Type: String

  DBInstanceName:
    Type: String
    Default: "rds"

# MysqlのMajorVersionのデフォルト値を5.7で固定
  MySQLMajorVersion:
    Type: String
    Default: "5.7"
    AllowedValues: [ "5.7" ]

# MysqlのMinorVersionのデフォルト値を22で固定
  MySQLMinorVersion:
    Type: String
    Default: "22"

# インスタンスタイプはt2.microを使用
  DBInstanceClass:
    Type: String
    Default: "db.t2.micro" 

# EBSボリュームのサイズは30GB
  DBInstanceStorageSize:
    Type: String
    Default: "30"

# EBSボリュームは汎用SSD(gp2)を使用
  DBInstanceStorageType:
    Type: String
    Default: "gp2"
  DBName:
    Type: String
    Default: "db"

# MasterUserNameを5文字以上16文字以内に設定し、デフォルト値をadminとする
  DBMasterUserName:
    Type: String
    Default: "admin"
    NoEcho: true
    MinLength: 5
    MaxLength: 16
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."

# passwordを8文字以上20文字以内に設定し、デフォルト値をZaq12wsxとする
  DBPassword: 
    Default: "Zaq12wsx"
    NoEcho: true
    Type: String
    MinLength: 8
    MaxLength: 20
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: "must contain only alphanumeric characters."

# デフォルトでマルチAZ配置を設定
  MultiAZ: 
    Default: "true"
    Type: String
    AllowedValues: [ "true" ]

Resources: 
# ------------------------------------------------------------#
#  DBInstance MySQL
# ------------------------------------------------------------#
  DBInstance: 
    Type: "AWS::RDS::DBInstance"
    Properties: 
      DBInstanceIdentifier: !Sub "${PJPrefix}-${DBInstanceName}"
      Engine: MySQL
      EngineVersion: !Sub "${MySQLMajorVersion}.${MySQLMinorVersion}"
      DBInstanceClass: !Ref DBInstanceClass
      AllocatedStorage: !Ref DBInstanceStorageSize
      StorageType: !Ref DBInstanceStorageType
      DBName: !Ref DBName
      MasterUsername: !Ref DBMasterUserName
      MasterUserPassword: !Ref DBPassword
      DBSubnetGroupName: !Ref DBSubnetGroup
      PubliclyAccessible: false
      MultiAZ: !Ref MultiAZ
      PreferredBackupWindow: "18:00-18:30"
      PreferredMaintenanceWindow: "sat:19:00-sat:19:30"
      AutoMinorVersionUpgrade: false
      DBParameterGroupName: !Ref DBParameterGroup  
      VPCSecurityGroups:
        - !Ref RDSSecurityGroup
      CopyTagsToSnapshot: true
      BackupRetentionPeriod: 7
      Tags: 
        - Key: "Name"
          Value: !Ref DBInstanceName
    DeletionPolicy: "Delete"

# ------------------------------------------------------------#
#  DBParameterGroup
# ------------------------------------------------------------#
  DBParameterGroup:
    Type: "AWS::RDS::DBParameterGroup"
    Properties:
      Family: !Sub "MySQL${MySQLMajorVersion}"
      Description: !Sub "${PJPrefix}-${DBInstanceName}-parm"

# ------------------------------------------------------------#
#  SecurityGroup for RDS (MySQL)
# ------------------------------------------------------------#
  RDSSecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: { "Fn::ImportValue": !Sub "CloudFormation-vpc" }   #事前に作成したVPCを指定
      GroupName: !Sub "${PJPrefix}-${DBInstanceName}-sg"
      GroupDescription: "-"
      Tags:
        - Key: "Name"
          Value: !Sub "${PJPrefix}-${DBInstanceName}-sg"
# インバウントルール
# Mysql/Auroraの接続を許可
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 0.0.0.0/0
# SSH接続を許可
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
# HTTP通信の接続を許可
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
# HTTPS通信の接続を許可
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
# ------------------------------------------------------------#
#  DBSubnetGroup
# ------------------------------------------------------------#
  DBSubnetGroup: 
    Type: "AWS::RDS::DBSubnetGroup"
    Properties: 
      DBSubnetGroupName: !Sub "${PJPrefix}-${DBInstanceName}-subnet"
      DBSubnetGroupDescription: "-"
      SubnetIds: 
        - { "Fn::ImportValue": !Sub "CloudFormation-private-subnet-a" }    #1aのプライベートサブネット
        - { "Fn::ImportValue": !Sub "CloudFormation-private-subnet-c" }    #1cのプライベートサブネット

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#                
Outputs:
#DBInstance
  DBInstanceID:
    Value: !Ref DBInstance
    Export:
      Name: !Sub "${PJPrefix}-${DBInstanceName}-id"

  DBInstanceEndpoint:
    Value: !GetAtt DBInstance.Endpoint.Address
    Export:
      Name: !Sub "${PJPrefix}-${DBInstanceName}-endpoint"

  DBName:
    Value: !Ref DBName
    Export:
      Name: !Sub "${PJPrefix}-${DBInstanceName}-dbname"

```

#スタック作成後の確認手順

##設定確認

１、RDSのコンソールへ移動し、DBが作成されたことを確認する。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/cd40b85c-4f85-6772-7256-70e013bbfae9.png)

２、設定のタブへ移動し、テンプレート通りに設定されていることを確認する。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/cc67011f-e023-30f7-6596-9a5d1902735a.png)

３、接続とセキュリティのタブへ移動し、エンドポイントを確認する。(※接続確認で使います)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/767bbf82-a55e-07d7-b6e0-099929077052.png)

４、セキュリティグループをクリックする。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/abf080a3-e290-b839-bfb0-41433195a0e7.png)

５、インバウントルールとアウトバウンドルールがテンプレート通りに設定されていることを確認する。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/f67d1402-276a-28ce-8f5f-f2e083e4fe25.png)

##接続確認
１、スタート画面から「TeraTarm」を開く。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/347cbcc5-a115-aee2-a201-03656d4a18b0.png)

２、事前に準備したネットワーク構成がpublic subnetのEC2インスタンスのIPアドレスを入力し、ポート番号は22、サービスはSSHを指定する。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/ea647c81-25c1-f745-c235-01886e34baf1.png)

３、事前に設定したユーザ名と秘密鍵を指定する。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/8de867df-f053-91c5-a2fa-148b88a7c5e6.png)

４、正常にログイン出来たことを確認する。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/ac2db9ef-2b7c-709a-0e70-148b04799364.png)


５、ルートユーザにスイッチする。

```
$ sudo su
```
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/345711ad-c012-6bbc-f3c7-84c0c7efe4a4.png)

６、ルートユーザにスイッチされたことを確認する。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/c76818dd-41a1-ac43-267a-9191c434a2a2.png)

７、事前に準備したネットワーク構成がprivate subnetのEC2インスタンスにアクセスする。

```
# ssh  <ユーザ名>@<プライベートIPアドレス> -i <秘密鍵のファイル名>.pem
```

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/881f8659-be93-1cc9-da75-d41253bb2738.png)

８、yesを入力する。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/adb45a5d-3177-75b4-e96b-67700505360d.png)

９、private subnetのEC2インスタンスにアクセスしたことを確認する。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/d50a8b05-abcf-9408-5676-99aa9cf2eb82.png)

１０、ルートユーザにスイッチする。

```
$ sudo su
```
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/fe530461-4c56-e553-902f-72de6b4c3212.png)

１１、MySQLを起動する。

```
# systemctl start mysqld
```
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/8e5beb74-de28-4e12-92d4-b3e1f07d4614.png)

１２、MySQLが起動されていることを確認する。

```
# systemctl is-active mysqld
```
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/03e6b070-b0a9-50c8-e52e-2ddc448c0309.png)

１３、MySQLにアクセスする。

```
# mysql -h <RDSの「設定タブ」で確認したエンドポイント> -u <ユーザ名> -p
```
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/f2e055da-31eb-34d9-f3d1-0b2c013cdfda.png)

１４、MySQLにアクセスしたことを確認する。
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/07e93c9c-7965-64f6-9d93-545662476e6d.png)


#終わりに
今回はCloudFormaitonを使ったRDSの作成について解説しました。
テンプレートの理解に時間がかかりましたが、少しずつコード化の幅が広がっていることを実感しております。
他のAWSリソースでコード化が実現出来たら随時Qiitaに投稿します♪