コンテンツにスキップ

database pattern

概要

database patternモジュールでは、Runtime環境で実行するアプリケーションから利用するデータベースを構築します。

想定する適用対象環境

database patternは、Runtime環境で使用することを想定しています。

依存するpattern

database patternは、事前に以下のpatternが適用されていることを前提としています。

pattern名 利用する情報
network pattern プライベートサブネット
encryption_key pattern CMKのエイリアス

構築されるリソース

このpatternでは、以下のリソースが構築されます。

リソース名 説明
Amazon Relational Database Service (RDS) 入力変数で指定された設定で、リレーショナルデータベースを構築します
Amazon CloudWatch Logs データベースログの格納先を構築します

モジュールの理解に向けて

サーバーアプリケーションでは、永続的にデータを格納するためのデータベースを必要とすることが多くあります。 Amazon Relational Database Service(以下、Amazon RDS)は、データの永続化をするためのリレーショナルデータベースをフルマネージドで提供するサービスです。

Amazon RDSが提供するデータベースシステムとしては、以下があります。

  • Amazon Aurora
  • PostgresSQL
  • MySQL
  • MariaDB
  • Oracleデータベース
  • SQLServer

⚠️ Eponaの開発では、PostgreSQLを使って動作確認を行っています。

⚠️ Amazon Auroraのデータベースエンジンはdatabase patternでは構築できません。

ここでは、database patternにて構築されるデータベースの運用観点と、その対応について記載しています。

  • セキュリティ
  • ログ
  • モニタリング
  • 監視
  • メンテナンス
  • 高可用性
  • リードレプリカ
  • バックアップ

patternモジュールそのものだけではなく、データベースを利用するアプリケーションに必要な情報や環境を管理する際に知っておくべき知識もあるので、各々把握するようにしてください。

セキュリティ

ネットワーク配置

一般的にAmazon RDSをインターネットからアクセス可能な環境に配置することは、悪意ある第三者による不正アクセスのリスクがあります。

Eponaでは、Amazon RDSインスタンスをnetwork patternで構築されたプライベートサブネットに配置し、同サブネット内のリソースからのアクセスに限定することを推奨します。

接続情報の管理

データベースへの接続情報は、秘匿すべき情報として管理されるべきです。

Eponaでは、アプリケーションはpublic_traffic_container_serviceのようなコンテナサービスを使用して構築される想定です。

アプリケーションとデータベースとの接続情報は別途 parameter_store patternで構築される、パラメータストアで管理することを推奨します。

初期マスタパスワードの変更について

database patternを適用後に構築されるデータベースシステムのマスタパスワードは、リソース構築用のterraformスクリプトに平文で記述する必要があります。

この状況は、コードを参照可能なユーザーによる不正なデータベースアクセスや、悪意のある第三者による不正アクセスのリスクを増大させます。

そのため、database patternを適用した後には必ずマスタパスワードを変更するようにしてください。

変更手順は以下のようになります。

  1. 構築されたRDSのマスタパスワードを変更する

    構築したRDSインスタンスに対して rds:ModifyDBInstance 権限を持つユーザーで以下のコマンドを実行する。

    ```sh
    $ aws rds modify-db-instance --db-instance-identifier [データベース名] --master-user-password [password]
    ```
    

ℹ️ 通常、Terraformは構成定義ファイルの変更を検出して環境に反映しますが、database patternでのパスワードは変更検出の対象外としています。

データの暗号化

encryption_key patternで作成したAWS KMS CMKを用いて、ストレージや後述するパフォーマンスインサイトに保存するデータの暗号化を行うことができます。

SSL/TLS

Amazon RDSでは、データベースインスタンスへの接続をSSL/TLS化できます。要件に応じ、SSL/TLS通信を使用したデータベースへの接続も可能です。

SSL/TLS を使用した DB インスタンスへの接続の暗号化

構築されたデータベースインスタンス自体は、SSL/TLS通信が有効化されています。

ただし、クライアントプログラムからサーバー証明をしつつSSL/TLSで通信するためには、クライアントの環境にAmazon RDSが提供する証明書を組み込む必要がある点に注意してください。

詳細については、Amazon RDSのSSL/TLSに関するドキュメントを確認してください。

また、クライアントプログラムからのSSL/TLS通信を強制したい場合は、以下のようにパラメーターグループを設定します。

  parameters = [
    { name = "rds.force_ssl", value = "1", apply_method = "pending-reboot" }

    ## その他のパラメーター
    ...
  ]

⚠️ このパラメーターが有効なデータベースエンジンは、PostgreSQLとSQL Serverに限られます。

ログ

Amazon RDSでは、データベースインスタンスが出力するログをAmazon CloudWatch Logsへ保存できます。

Amazon RDS データベースログファイル

ただし、データベースに関するすべてのログをAmazon CloudWatch Logsに出力できるわけではありません。

データベースエンジンとAmazon CloudWatch Logsに出力なログの組み合わせは、Amazon RDSのドキュメントを確認してください。

database patternは、各データベースエンジンがAmazon CloudWatch Logsに出力可能なログについては、デフォルトですべて有効化します。

Amazon CloudWatch Logsに出力する対象を絞りたい、もしくは出力自体をやめたい場合はenabled_cloudwatch_logs_exports変数を設定してください。

また、Amazon CloudWatch Logsのロググループは自動で作成します。

Datadogが利用可能な場合は、ログの集約を参照してください。Datadogへのログの集約が可能です。

モニタリング

database patternでは、デフォルトで以下の3つのモニタリングが可能なように構成されます。

Amazon RDSのモニタリングの概要については、以下のページを参照してください。

モニタリングの概要

収集したメトリクスを使い、モニタリングおよび監視を行えます。

拡張モニタリング、パフォーマンスインサイトに関しては有効なままとすることを推奨しますが、patternモジュールの設定で無効にできます。

また、拡張モニタリングのメトリクスの収集間隔(詳細度)はデフォルトで60秒に、パフォーマンスインサイトのデータの保持期間はデフォルトで7日に設定しています。

database patternの変数で設定可能ですので、必要に応じて変更してください。

拡張モニタリングの保存先はAmazon CloudWatch Logsとなるため、Datadogが利用可能な場合はログ集約が可能です。
ログの集約を参照してください。

イベント通知

Amazon RDSで発生するイベントは、Amazon SNSにより通知されます。

Amazon RDS イベント通知の使用

この通知をモニタリングすることで、Amazon RDS上で発生するイベントを把握できます。

ℹ️ 現時点のEponaでは、このテーマをサポートしていません。

メンテナンス

Amazon RDSでは、データベースインスタンスのメンテナンスが実施されます。

database patternでは、デフォルトでデータベースエンジンのメジャーアップグレードを無効に、マイナーバージョンの自動アップグレードの有無とメンテナンスウィンドウの指定を必須にしています。

  • allow_major_version_upgrade : メジャーバージョンのアップグレードの許可
  • auto_minor_version_upgrade : マイナーバージョンの自動アップグレードの有無
  • maintenance_window : メンテナンスウィンドウ(ddd:hh24:mi-ddd:hh24:mi:24時間表記、UTC指定)

サービスの内容に応じて、メンテナンスウィンドウとエンジンのアップグレード方針を決定し、モジュールの設定に反映してください。

高可用性

Amazon RDSでは、インスタンスをマルチAZ配置にすることで、高可用構成を実現できます。

Amazon RDS での高可用性 (マルチ AZ)

ただし、インスタンス構成がマルチAZとなっても、インスタンスのフェイルオーバーの可能性を考慮したアプリケーションの対応が必要となる点に注意してください。

Eponaではdatabase patternにおいて、multi_az変数をtrueとすることでAmazon RDSインスタンスをマルチAZ構成とできます。この変数はデフォルトではfalseとなっており、シングルAZで構築されます。

リードレプリカ

現在のdatabase patternでは、リードレプリカを含めた構成はサポートしていません。

バックアップ

Amazon RDSでは、自動スナップショットを取得することで、バックアップを実現できます。

Amazon RDS DB インスタンスのバックアップと復元

Eponaでは、database patternにおいて、以下変数を入力することでAmazon RDSインスタンスの自動スナップショット取得を有効とします。これら変数はデフォルトではnullとなっており、自動スナップショットは無効化されます。

  • backup_retention_period : バックアップ保管世代(最大35)
  • backup_window : バックアップウィンドウ(HH:MM-HH:MM表記)

⚠️
自動スナップショットには保持期間があり、期限が過ぎたスナップショットは削除されます。
database patternモジュールを使用して、自動で取得したスナップショットからリストアを行う場合、スナップショットをコピーして使用することを強く推奨します

DB スナップショットのコピー

詳細は、リストアを参照してください。

リストア

Amazon RDSはスナップショットからのリストア可能です。database patternでは、リストアは指定のスナップショットからDBインスタンスを作り直すことで行います。

⚠️
自動で取得したスナップショットからリストアする場合、スナップショットのコピーを行い、コピーからリストアすることを強く推奨します
また、Terraformでは、ポイントインタイムリカバリをサポートしていません。

リストア手順は以下のとおりです。

  1. RDSインスタンスをデプロイしたterraformコードに、snapshot_identifierを追加指定します。変数の値は、リストア先のSnapshot名を入力します
  2. terraformを実行します

リストアを行うと、snapshot_identifierに指定したスナップショットを使ってDBインスタンスが再作成されます。
RDSのエンドポイント(DNS名)は変わりませんが、インスタンスのIPアドレスは変更されることに注意してください。

RDSを使用するアプリケーションがDNSの参照結果をキャッシュする場合は、TTLを適切に指定してください。

Javaの場合は、以下を参考にします。


⚠️ リストア後の注意点について。

リストアを行った後は、別のスナップショットからリストアする場合を除いてsnapshot_identifierに指定した値を変更しないでください。
snapshot_identifierを指定してリストア後、この値を変更してTerraformを実行した場合、以下の挙動になります。

  • snapshot_identifierの値を削除 → インスタンスの再作成(データがない状態で再作成)
  • snapshot_identifierに別のスナップショットIDを指定 → 指定のスナップショットからリストア

またsnapshot_identifierに指定したスナップショットが存在しない場合、 インスタンスが削除されリストアは失敗します
スナップショットが期限切れなどで削除されたりすると、その後のTerraform実行時に意図せぬインスタンス削除となる恐れがあるため注意してください。

ℹ️ リストア後にsnapshot_identifierを変更せずにTerraformを実行した場合、リストアされるのは初回だけです。

このため自動バックアップで取得したスナップショットは直接使わずに、事前に手動でコピーして使用してください。

DB スナップショットのコピー


削除保護

database patternで構築したRDSインスタンスは、デフォルトで削除保護が有効になっています。

削除保護

これはterraform destroyを誤って実行してしまいデータを失うことを避けるため、セーフティネットを意図して有効化しています。

テスト目的などでRDSインスタンスの破棄できるようにするには、deletion_protectionfalseに設定します。
削除保護が無効になり、terraform destroyが可能になります。

ℹ️ 削除保護が有効なRDSを削除する場合は、先にdeletion_protectionfalseに設定変更してください。

Amazon QuickSightとの連携

RDSはAmazon QuickSightのデータソースとして使用できます。 本パターンで構築したRDSをQuickSightのデータソースとして利用する場合、source_security_group_idsの設定が必要です。 この場合、source_security_group_idsquicksight_vpc_inbound_source patternで出力されたセキュリティグループのIDを設定してください。

quicksight_vpc_inbound_source patternの適用については、quicksight_vpc_inbound_source patternのドキュメントを参照してください。

サンプルコード

database patternを使用したサンプルコードを、以下に記載します。

module "database" {
  source = "git::https://gitlab.com/eponas/epona.git//modules/aws/patterns/database?ref=v0.2.6"

  name = "my-database-instance"
  tags = {
    # 任意のタグ
    Name               = "my-database"
    Environment        = "runtime"
    RuntimeEnvironment = "production"
    ManagedBy          = "epona"
  }

  identifier            = "my-rds-instance"
  engine                = "postgres"
  engine_version        = "12.4"
  port                  = 5432
  instance_class        = "db.t3.medium"
  allocated_storage     = 5
  max_allocated_storage = 10

  auto_minor_version_upgrade = true
  maintenance_window         = "Tue:18:00-Tue:18:30"

  username = "user"
  password = "password"

  kms_key_id = data.terraform_remote_state.encryption_key.outputs.encryption_key.keys["alias/my-encryption-key"].key_arn  # encryption_key patternで作成したモジュールから値を設定

  # network patternで作成したモジュールから値を設定
  vpc_id = data.terraform_remote_state.network.outputs.network.vpc_id
  availability_zone = "ap-northeast-1a"

  db_subnets = data.terraform_remote_state.staging_network.outputs.network.private_subnets
  db_subnet_group_name = "my-rds-subnet-group"

  parameter_group_name   = "my-rds-parameter-group"
  parameter_group_family = "postgres12"

  option_group_name                 = "my-rds-option-group"
  option_group_engine_name          = "postgres"
  option_group_major_engine_version = "12"

  backup_retention_period           = "35"
  backup_window                     = "00:00-01:00"

  performance_insights_kms_key_id = data.terraform_remote_state.encryption_key.outputs.encryption_key.keys["alias/my-encryption-key"].key_arn  # encryption_key patternで作成したモジュールから値を設定

  parameters = [
    # DBパラメータを記載
  ]

  # QuickSightから本パターンで構築したRDSを参照する場合、quicksight_vpc_inbound_source pattern適用後、再実行してください
  # source_security_group_ids = [
    # "sg-00000000000000000"  # quicksight_vpc_inbound_source patternで出力されるセキュリティグループID
  # ]
}

関連するpattern

database patternに関連するpatternを、以下に記載します。

pattern名 説明
public_traffic_container_service pattern DBを利用するアプリケーションがデプロイされるECS

ログの集約

database patternでは、データベースに関連するログおよび拡張モニタリングをAmazon CloudWatch Logsに出力します。

これらのログは、datadog_log_trigger patternを使用することでDatadogに集約できます。

入出力リファレンス

Requirements

Name Version
terraform ~> 0.14.10
aws >= 3.37.0, < 4.0.0

Inputs

Name Description Type Default Required
allocated_storage RDSに割り当てるストレージ容量(GB単位) number n/a yes
auto_minor_version_upgrade メンテナンスウィンドウ中に、RDSエンジンのマイナーバージョンアップグレードを許可する場合、true bool n/a yes
backup_retention_period バックアップ保管期間。0〜35(日)の範囲で指定すること。
なお、このパラメータを0から0以外の値、0以外の値から0に変更した場合、機能停止が発生する点に注意。詳細はドキュメントを参照のこと。
バックアップの使用
string n/a yes
backup_window DBスナップショット(バックアップ)を作成する時間帯を09:46-10:16(UTC)という形式で指定する。
Single-AZ DBインスタンスの場合、スナップショット取得中はI/Oが短時間中断する点に注意。また、maintenance_windowとは重複させないこと。
string n/a yes
db_subnet_group_name DBサブネットグループ名 string n/a yes
db_subnets DBサブネットに割り当てる、サブネットIDのリスト list(string) n/a yes
engine RDSのエンジンの種類 string n/a yes
engine_version RDSのエンジンのバージョン string n/a yes
identifier RDSのインスタンス名 string n/a yes
instance_class RDSのDBインスタンスクラス string n/a yes
kms_key_id 暗号化に使用するKMSキーを指定 string n/a yes
maintenance_window メンテナンスを実行する時間帯を指定する https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Maintenance.html#AdjustingTheMaintenanceWindow string n/a yes
name RDSのデータベース名 string n/a yes
option_group_engine_name DBオプショングループに関連付けるエンジンの名前 string n/a yes
option_group_major_engine_version DBオプショングループに関連付けるエンジンのメジャーバージョン string n/a yes
option_group_name DBオプショングループ名 string n/a yes
parameter_group_family DBパラメーターグループのファミリー string n/a yes
parameter_group_name DBパラメーターグループ名 string n/a yes
password RDSのマスタユーザーのパスワード string n/a yes
performance_insights_kms_key_id パフォーマンスインサイトに保存する際の、KMSキー string n/a yes
port RDSのポートを指定する number n/a yes
username RDSのマスタユーザー名 string n/a yes
vpc_id VPC ID string n/a yes
allow_major_version_upgrade RDSエンジンのメジャーアップグレードを許可する場合、true bool false no
apply_immediately データベースの変更をすぐに反映する場合、trueを指定する。falseを指定した場合、次のメンテナンス期間に適用される bool false no
availability_zone このRDSインスタンスを配置するAZ。マルチAZ構成とする場合は、nullを指定します string null no
ca_cert_identifier RDSインスタンスに適用するSSL/TLS証明書の識別子 string "rds-ca-2019" no
character_set_name OracleおよびMicrosoft SQL Server使用時の、エンコーディングに使用する文字集合名 string null no
cloudwatch_logs_kms_key_id CloudWatch Logsを暗号化するためのKMS CMKのARN string null no
cloudwatch_logs_retention_in_days ログをCloudWatch Logsに出力する場合の保持期間を設定する。

値は、次の範囲の値から選ぶこと: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
Resource: aws_cloudwatch_log_group / retention_in_days
number null no
copy_tags_to_snapshot 最終スナップショットに、インスタンスのタグをコピーして付与するか否か bool true no
deletion_protection RDSインスタンスの削除保護を有効にする場合、trueを指定する。有効にすると、RDSインスタンスを削除できなくなる bool true no
enabled_cloudwatch_logs_exports CloudWatch Logsに出力するログの種類をリストで指定する。空のリストを指定した場合、ログはCloudWatch Logsに出力されない。
なにも指定しない場合、RDSMSごとのデフォルトのログが出力される。

指定可能なログの種類はRDBMSごとに異なるので、Amazon RDS データベースログファイルResource: aws_db_instance#enabled_cloudwatch_logs_exportsを参照すること
list(string) null no
final_snapshot_identifier 最終スナップショットに指定する識別子 string null no
iops プロビジョンドIOPS SSDストレージを使用した場合の、IOPSを指定する https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_Storage.html#USER_PIOPS number null no
license_model OracleまたはMicrosoft SQL Serverを使用する際のライセンスモデル string null no
max_allocated_storage この値が指定されている場合、RDSのストレージが不足した場合にこの値(GBで指定)まで自動的にスケーリングする number null no
monitoring_interval 拡張モニタリングにおける詳細度(収集間隔)を秒単位で指定する。0, 1, 5, 10, 15, 30, 60のいずれかが指定可能 number 60 no
monitoring_role_arn 拡張モニタリング用のIAMロールのARNを指定する string null no
mssql_timezone Microsoft SQL Server使用時のタイムゾーンを指定する string null no
multi_az マルチAZを有効にする場合、true bool false no
option_group_options DBオプショングループに割り当てる、オプションのリスト list(map(any)) [] no
parameters DBパラメーターグループに割り当てる、パラメーターのリストを指定する。各パラメーターには、name, value, apply_methodの3つを指定する list(map(string)) [] no
performance_insights_enabled パフォーマンスインサイトを有効にするか否か bool true no
performance_insights_retention_period パフォーマンスインサイトのデータ保持期間を日数で指定する。performance_insights_enabledtrueの時のみ設定可能で、7 または 731 (2年)のいずれかを指定する number 7 no
security_groups RDSインスタンスに割り当てるセキュリティグループのリスト list(string) [] no
skip_final_snapshot RDSのインスタンスを削除する際に、最後のスナップショットを作成しない場合はtrueを指定する bool false no
snapshot_identifier Snapshotから復元する場合、Snapshot IDを入力 string null no
source_security_group_ids RDSに設定するセキュリティグループのインバウンドに指定するSecurity Group IDリスト list(string) [] no
storage_encrypted ストレージの暗号化を行う場合、true bool true no
storage_type RDSのストレージタイプ string null no
tags このモジュールで作成するリソースに、共通的に付与するタグ map(string) {} no

Outputs

Name Description
instance_address RDSインスタンスへアクセスするためのアドレス
instance_endpoint RDSインスタンスのエンドポイント
instance_engine RDSインスタンスのデータベースエンジン
instance_engine_version RDSインスタンスのデータベースエンジンのバージョン
instance_identifier RDSインスタンスの識別子
instance_log_group_names RDSインスタンスのロググループ名のリスト
instance_name データベース名
instance_port RDSインスタンスへアクセスするためのポート
instance_security_group_id RDSインスタンスのセキュリティグループのID
instance_username ユーザー名
monitoring_log_group_name 拡張モニタリングが有効な場合、拡張モニタリングメトリクスを含むCloudWatch Logsロググループ名を返却する。ただし、このロググループは、各RDSインスタンスで共有となる

※ このドキュメントはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。

※ このドキュメントに記載されている会社名、製品名は、各社の登録商標または商標です。

© 2021 TIS Inc.