CloudFormationでRDSのセキュアな構築

## はじめに
RDSをCloudFormationで作成し、構築できるようにする

## 目次
- RDS作ってみる
- ユーザ名とパスワードのパラメータを直接設定
- SSMを使用
- SecretsManagerを使用
- 最後に

## RDS作ってみる
最低限の設定をして、作成してみる。
このままでは、ユーザ名・パスワードが誰にでも見えてしまう

```
Resources: 
  RdsMsSql:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: "db.t2.micro"
      AllocatedStorage: 20
      Engine: MySQL
      EngineVersion: 8.0.16
      MasterUsername: admin
      MasterUserPassword: secret_password
      DeletionProtection: false
      DeleteAutomatedBackups: true
```

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html#cfn-rds-dbinstance-deleteautomatedbackups

## ユーザ名とパスワードのパラメータ設定
外部からユーザ名とパスワードを外部から設定できるようにする。
スタックイベントのパスワードもマスクされる。

ただ、RDS作成した際に、ユーザとパスワードが決定し、手動管理が必要

:::note info
NoEcho属性を True で指定
スタックまたはスタックイベントを説明するすべての呼び出しに対してアスタリスク（*****）としてマスクされたパラメーター値を返します。
:::

```
Parameters: 
  RDSMasterUsername:
    Description: "RDS Master User Name"
    Type: String
    MinLength: 8
    MaxLength: 128
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
  RDSUserPassword:
# パラメータ値をマスク
    NoEcho: true
    Description: "RDS Master User Password"
    Type: String
    MinLength: 8
    MaxLength: 128
    AllowedPattern: "[a-zA-Z0-9]*"

Resources: 
  RdsMsSql:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: "db.t2.micro"
      AllocatedStorage: 20
      Engine: MySQL
      EngineVersion: 8.0.16
      MasterUsername: !Ref RDSMasterUsername
      MasterUserPassword: !Ref RDSUserPassword
      DeletionProtection: false
      DeleteAutomatedBackups: true
```

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html

## SSMを使用
SSM（AWS Systems Manager）でユーザ名とパスワードを管理
ただ、機密データ用のパラメータストアを使用するほうがベーター

:::note info
SSMのパラメータを指定
'{{resolve:ssm: **parameter-name:version** }}'
'{{resolve:ssm-secure: **parameter-name:version** }}'
:::

:::note warn
事前に下記にSSMを設定する必要がある
・/MyDB/RDSInstanceType
・/MyDB/RDSMasterUsername
・/MyDB/RDSUserPassword ※Type：SecureString
:::
```
Parameters: 
  RDSInstanceType:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /MyDB/RDSInstanceType

Resources: 
  RdsMsSql:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: !Ref RDSInstanceType
      AllocatedStorage: 20
      Engine: MySQL
      EngineVersion: 8.0.16
      MasterUsername: '{{resolve:ssm:/MyDB/RDSMasterUsername:1}}'
      MasterUserPassword: '{{{resolve:ssm-secure:/MyDB/RDSUserPassword:1}}'
      DeletionProtection: false
      DeleteAutomatedBackups: true
```
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-ssm

## SecretsManagerを使用
RDS作成時点で、SecretsManagerで自動的にパスワード作成し、セキュアな管理できる
パスワードのローテーション可能

:::note info
{{resolve:secretsmanager:**secret-id:secret-string:json-key:version-stage:version-id**}}
:::

```
  MyRDSSecret:
    Type: "AWS::SecretsManager::Secret"
    Properties:
      Description: "This is a Secrets Manager secret for an RDS DB instance"
      GenerateSecretString:
        SecretStringTemplate: '{"username": "admin"}'
        GenerateStringKey: "password"
        PasswordLength: 16
        ExcludeCharacters: '"@/\'

  MyRDSInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      AllocatedStorage: 20
      DBInstanceClass: db.t2.micro
      Engine: mysql
      MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref MyRDSSecret, ':SecretString:username}}' ]]
      MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref MyRDSSecret, ':SecretString:password}}' ]]
      BackupRetentionPeriod: 0
      DBInstanceIdentifier: 'rotation-instance'

  SecretRDSInstanceAttachment:
    Type: "AWS::SecretsManager::SecretTargetAttachment"
    Properties:
      SecretId: !Ref MyRDSSecret
      TargetId: !Ref MyRDSInstance
      TargetType: AWS::RDS::DBInstance

```

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-secret.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-secrettargetattachment.html#aws-resource-secretsmanager-secrettargetattachment--examples

## 最後に
CloudFormationを使用して、機密情報を管理し、セキュアな環境構築ができるようになればと思います。