【AWS】RDS for PostgreSQLをスナップショットから復元するCloudFormationテンプレート

RDSは利用料が結構かかることが多いです。そのため、使用しない期間はスナップショットだけ残して、あとで復元するという使い方をしていました。
その時に、前の設定をマネジメントコンソールから毎回入力するのは面倒なので、CloudFormationでRDSを復元する方法を学びました。
今回はその中で、RDS for PostgeSQLのスナップショットを復元するCloudFormationを紹介します。

# 結論

「コードだけ読めれば大丈夫!」って方のために最初にCloudFormationテンプレートの例を載せます。(YAML形式です。)
各項目については後ほど説明しますので、気になるところがあれば以降も読んでいただけると嬉しいです。

:::note info
「Encryption Settings」「Performance Insights Settings」の設定とオートスケーリング設定のための"MaxAllocatedStorage"は必要であれば設定してください。
:::

```yaml:cf-rds-example.yml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  MyDBSnapshot:
    Default: my-db-snapshot-name
    Type: String
  MyDBSubnetGroup:
    Default: default-vpc-xxxxxxxx
    Type: String
  MySecurityGroup:
    Default: sg-xxxxxxxx
    Type: String
  MyKmsKeyId:
    Default: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Type: String
Resources:
  MyDB:
    Type: AWS::RDS::DBInstance
    Properties:
      VPCSecurityGroups:
        - Ref: MySecurityGroup
      MultiAZ: true
      DBSubnetGroupName:
        Ref: MyDBSubnetGroup
      AllocatedStorage: 20
      DBInstanceClass: db.t3.micro
      Engine: postgres
      EngineVersion: 13.4
      DBInstanceIdentifier: my-db-name
      DBSnapshotIdentifier:
        Ref: MyDBSnapshot
      PubliclyAccessible: false
      StorageType: gp2
      # Encryption Settings
      StorageEncrypted: true
      KmsKeyId: 
        Ref: MyKmsKeyId
      # Performance Insights Settings
      EnablePerformanceInsights: true
      PerformanceInsightsKMSKeyId:
        Ref: MyKmsKeyId
      MaxAllocatedStorage: 100
      CopyTagsToSnapshot: true
      Tags:
        - Key: example
          Value: qiita
      DeletionProtection: false
    DeletionPolicy: Snapshot

```

# テンプレートの説明

## テンプレートの基本

### AWSTemplateFormatVersion

CloudFormationテンプレートのバージョンです。

### Parameters

テンプレート内で使用する定数を定義します。
繰り返し使う値や他のリソースに依存する値を分かりやすいように書いてします。
同じテンプレート内で`Ref`で参照することができます。

### Resources

リソースを定義します。Resourcesの下に任意の名前で書きます。
テンプレート例で書いている`MyDB`の部分が任意の名前です。

## リソースの項目 (Resources > リソース名 > ...)

### Type

リソースタイプを指定します。
リソースごとに決まった値があり、RDSは`AWS::RDS::DBInstance`です。

### Properties

リソースの設定を記載します。
項目の種類はリソースによって違いますので、公式ドキュメントを見ながら書くことをお勧めします。

### DeletionPolicy

リソース(スタック)の削除時の設定です。
EC2やRDSなどはスナップショットをサポートしているので、`Snapshot`を指定します。

## RDSのプロパティ項目 (Resources > リソース名 > Properties > ...)

### VPCSecurityGroups

RDSで使用するVPCに設定するセキュリティグループのIDを指定します。
例では、Parametersで定義しているMySecurityGroupを参照しています。

### MultiAZ

可用性のためにマルチAZ構成にする場合は`true`を選択します。設定しない場合は、デフォルトで`false`です。

### DBSubnetGroupName

multiAZを`true`にした場合は、複数のAZにあるサブネットをグループ化したサブネットグループというリソースを使用します。この項目では、DBサブネットグループのIDを指定します。
例では、Parametersで定義しているMyDBSubnetGroupを参照しています。

### AllocatedStorage

DBインスタンスに割り当てるストレージ容量です。
例では設定していませんが、もし`Iops`が設定されている場合は、最低でも100(GiB)以上でないといけません。

### DBInstanceClass

DBインスタンスのクラスを指定します。サポートされているインスタンスクラスのみ指定可能です。
AWS CLIが使用可能であれば、以下のコマンドで確認できます。

```bash:PosgreSQLの使用可能インスタンスクラス一覧確認
aws rds describe-orderable-db-instance-options --engine postgres --engine-version 13.4 --query "OrderableDBInstanceOptions[].[DBInstanceClass,StorageType,Engine,EngineVersion]" --region ap-northeast-1
```

### Engine

DBのエンジンを指定します。MySQLは`MySQL`、PostgreSQLは`postgres`です。

### EngineVersion

DBのエンジンのバージョンを指定します。サポートされているバージョンのみ指定可能です。
AWS CLIが使用可能であれば、以下のコマンドで確認できます。

```bash: PosgreSQLの使用可能バージョン一覧確認
# 全バージョン
aws rds describe-db-engine-versions --engine postgres --region ap-northeast-1
# デフォルトバージョンのみ
aws rds describe-db-engine-versions --default-only --engine postgres --region ap-northeast-1
```
参考 | [利用可能な PostgreSQL データベースのバージョン](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.DBVersions)

### DBInstanceIdentifier

復元後のRDS名を任意で指定します。

### DBSnapshotIdentifier

復元したいスナップショット名を指定します。
例では、Parametersで定義しているMyDBSnapshotを参照しています。

### PubliclyAccessible

パブリックアクセス可能かどうかを`true`または`false`で指定します。

### StorageType

ストレージタイプを選択します。
`standard`, `gp2`, `io1`から選択します。`standard`はmagneticのことです。
デフォルトでは、`Iops`の項目が設定されている場合は`io1`で、それ以外の場合は`standard`です。

### StorageEncrypted

暗号を有効化したい場合は、`true`を指定します。設定しない場合は、デフォルトで`false`です。
もし`true`に設定した場合は、後述する`KmsKeyId`で任意のKMSキーを設定することができます。

### KmsKeyId

暗号を有効化した場合は、KMSキーIDを指定することで、任意のKMSキーを設定することができます。
指定しない場合はデフォルトのKMSキーが使用されます。

### EnablePerformanceInsights

Performance Insights の有効化をしたい場合は`true`を設定します。設定しない場合は、デフォルトで`false`です。

### PerformanceInsightsKMSKeyId

Performance Insights の有効化をした場合は、KMSキーIDを指定することで、任意のKMSキーを設定することができます。

### MaxAllocatedStorage

ストレージサイズの上限を設定します。
この項目を設定することで、間接的にストレージの自動スケーリングを有効化することができます。

### CopyTagsToSnapshot

スナップショットを作成した場合にタグをコピーしたい場合は、`true`を設定します。設定しない場合は、デフォルトで`false`です。

### Tags

タグを任意で設定します。

### DeletionProtection

削除保護の有効化をしたい場合は`true`を設定します。設定しない場合は、デフォルトで`false`です。

# おわりに

RDS for PostgreSQLのテンプレートの具体例を調べてみたところ、意外に少なかったので紹介してみました。
エンタープライズアプリケーション向けなAuroraのCloudFormationテンプレート例は検索でたくさんヒットしたことから推測すると、ある程度大規模開発じゃないとCloudFormationが採用されてないのかもしれないですね。
CloudFormation(IaC)は一定の学習コストは必要なものの、一度そのコストを払ってしまえば小規模開発でもリターンは十分だと思いますので、積極的に活用していきたいです。