Terraform Aurora PostgreSQL 編

  • PostgreSQL
  • Terraform
  • RDS
  • 前提

    Aurora PostgreSQL を構築する前に、ネットワーク環境(VPC,Subnet,Security Group)や、CloudWatch Logs にログを転送するための IAM Role などが必要です。

    Terraform でインフラ構築するときは、その一つ一つのコンポーネントを理解しておく必要があります。

    ただ、今回は Aurora PostgreSQL 構築の話を中心に書きたいと思いますので、周辺の説明はサンプルコードの記載に留めて省略していきたいと思います。

    Aurora PostgreSQL に必要なもの

    Aurora PostgreSQL を構築するために必要な resource は aws_rds_clusteraws_rds_cluster_instance です。

    そして、それらを実行するために必要な resource をがこちらです。

    • aws_db_subnet_group
    • aws_security_group
    • aws_iam_role
    • aws_rds_cluster_parameter_group
    • aws_db_parameter_group

    AWS は親切なので default で "よろしく" やってくれるところがありますが、それでは現場で通用しませんので、1つ1つ設定していきたいと思います。

    準備

    aws_db_subnet_group

    db subnet を作成する前に、subnet を複数作成しておく必要がありますが、そこは省きたいと思います。

    # DB Subnet # https://www.terraform.io/docs/providers/aws/r/db_subnet_group.html resource "aws_db_subnet_group" "db_subnet" { name = "sample-db-subnet-gp" subnet_ids = [ aws_subnet.subnet_rds.0.id, # 作成済みの subnet id を参照 aws_subnet.subnet_rds.1.id, # 作成済みの subnet id を参照 aws_subnet.subnet_rds.2.id # 作成済みの subnet id を参照 ] tags = { Service = "sample" } }

    aws_security_group

    セキュリティ要件によってはアウトバウンド通信の制御も必要でしょう。今回はインバウンド通信だけ制限します。

    # Security Group # https://www.terraform.io/docs/providers/aws/r/security_group.html resource "aws_security_group" "rds_sg" { name = "sample-rds-sg" description = "sample rds security group" vpc_id = aws_vpc.vpc.id # 作成済みの vpc id を参照 # 許可するインバウンド通信を記載 ingress { description = "PostgreSQL" from_port = 5432 to_port = 5432 protocol = "tcp" security_groups = [ aws_security_group.public_sg.id # list 形式で記載, public subnet id を参照 ] } # 許可するアウトバウンド通信を記載 egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "sample-rds-sg" Service = "sample" } }

    aws_iam_role

    コンソールで RDS を作成した際には、ログを CloudWatch Logs に転送する設定を選択すると、専用のサービスロール(AmazonRDSEnhancedMonitoringRole )が自動的にセットされています。

    これも Terraform の管理対象に含めるために、以下のロールを作成します。

    # aws_iam_role # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role resource "aws_iam_role" "rds_monitoring_role" { name = "sample-rds-monitoring-role" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "monitoring.rds.amazonaws.com" }, "Effect": "Allow" } ] } EOF tags = { Name = "sample-rds-monitoring-role" Service = "sample" } } # aws_iam_policy_attachment # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment resource "aws_iam_policy_attachment" "rds_monitoring_policy_attachment" { name = "rds_monitoring_policy_attachment" roles = [aws_iam_role.rds_monitoring_role.name] # list policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" }

    ポイントは、AssumeRole を "monitoring.rds.amazonaws.com" とすることです。 "rds.amazonaws.com" ではありません。

    詳細はこちらの issues を参照ください。

    aws_rds_cluster_parameter_group

    監査設定、hint句、ロケール(国際化と地域化)の設定を入れておきます。

    # aws_rds_cluster_parameter_group # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group resource "aws_rds_cluster_parameter_group" "aurora_postgre_cpg" { name = "sample-aurora-postgre-cpg" family = "aurora-postgresql11" tags = { Service = "sample" } # install libraries parameter { name = "shared_preload_libraries" value = "pg_stat_statements ,pg_hint_plan ,pgaudit" apply_method = "pending-reboot" } # audit setting parameter { name = "pgaudit.log_catalog" value = true apply_method = "immediate" } parameter { name = "pgaudit.log_parameter" value = true apply_method = "immediate" } parameter { name = "pgaudit.log_relation" value = true apply_method = "immediate" } parameter { name = "pgaudit.log_statement_once" value = true apply_method = "immediate" } parameter { name = "pgaudit.log" value = "ddl ,misc ,role" apply_method = "immediate" } parameter { name = "pgaudit.role" value = "rds_pgaudit" apply_method = "immediate" } # no local parameter { name = "lc_messages" value = "C" apply_method = "immediate" } parameter { name = "lc_monetary" value = "C" apply_method = "immediate" } parameter { name = "lc_numeric" value = "C" apply_method = "immediate" } parameter { name = "lc_time" value = "C" apply_method = "immediate" } }

    aws_db_parameter_group

    インスタンス毎に設定するパラメータグループは、とりあえず、ブランクとしておきます。

    # aws_db_parameter_group # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group resource "aws_db_parameter_group" "aurora_postgre_pg" { name = "sample-aurora-postgre-pg" family = "aurora-postgresql11" tags = { Service = "sample" } }

    Aurora PostgreSQL 構築

    aws_rds_cluster

    まずは、クラスターを構築します。

    # aws_rds_cluster # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster resource "aws_rds_cluster" "aurora_postgre_cls" { cluster_identifier = "sample-aurora-postgre-cls" engine = "aurora-postgresql" engine_version = "11.7" engine_mode = "provisioned" # global,multimaster,parallelquery,serverless, default provisioned database_name = "testdb01" master_username = "xxxxxxx" master_password = "xxxxxxxxxxx" # storage storage_encrypted = true # declare KMS key ARN if true, default false # kms_key_id = "" # set KMS ARN if storage_encrypted is true, default "aws/rds" # network db_subnet_group_name = aws_db_subnet_group.db_subnet.name vpc_security_group_ids = [aws_security_group.rds_sg.id] port = 5432 # backup snapshot backup_retention_period = 1 # must be between 1 and 35. default 1 (days) copy_tags_to_snapshot = true # default false deletion_protection = false # default false skip_final_snapshot = true # default false final_snapshot_identifier = "sample-aurora-postgre" # must be provided if skip_final_snapshot is set to false. # monitoring enabled_cloudwatch_logs_exports = ["postgresql"] # backup window preferred_backup_window = "02:00-02:30" # options db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.aurora_postgre_cpg.name # tags tags = { Service = "sample" } }

    aws_rds_cluster_instance

    クラスターにインスタンスを追加します。count でインスタンスの数を調整できるようにしています。

    # aws_rds_cluster_instance # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance resource "aws_rds_cluster_instance" "aurora_postgre_instance" { count = 2 identifier = "sample-aurora-postgre-${count.index}" cluster_identifier = aws_rds_cluster.aurora_postgre_cls.cluster_identifier instance_class = "db.r5.large" engine = "aurora-postgresql" engine_version = "11.7" # netowrok #availability_zone = "" # eu-west-1a,eu-west-1b,eu-west-1c # monitoring performance_insights_enabled = false # default false monitoring_interval = 60 # 0, 1, 5, 10, 15, 30, 60 (seconds). default 0 (off) monitoring_role_arn = aws_iam_role.monitoring_role.arn # maintenance window preferred_maintenance_window = "Mon:03:00-Mon:04:00" # options db_parameter_group_name = aws_db_parameter_group.aurora_postgre_pg.name auto_minor_version_upgrade = false # tags tags = { Service = "sample" } }

    注意ポイント① preferred_backup_window

    preferred_backup_window は aws_rds_cluster 側で設定します。

    preferred_backup_window を aws_rds_cluster_instance 側で設定しようとすると以下のエラーが発生します。

    Error: error creating RDS DB Instance: InvalidParameterCombination: The requested DB Instance will be a member of a DB Cluster. Set backup window for the DB Cluster. status code: 400, request id: 21428a77-42e2-41d0-923f-7fff91186f32 on sample_aurora_postgresql.tf line 206, in resource "aws_rds_cluster_instance" "aurora_postgre_instance": 206: resource "aws_rds_cluster_instance" "aurora_postgre_instance" {

    preferred_backup_window は クラスター側、インスタンス側、どちらでも設定が可能です。

    注意ポイント② ネットワーク

    データベースのネットワーク設計では、AZ(アベイラビリティゾーン)を指定したい場合がありますね。

    そんな時は、クラスター側でサブネットを設定して、インスタンス側でAZ(アベイラビリティゾーン)を指定すること、分かりやすいかなと思います。

    terraform apply

    実行してみます。

    PS C:\Users\...\terraform_aws> terraform apply Plan: 8 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

    実行結果を確認

    実行結果をコンソールで確認してみます。

    aws_terraform_aurora_postgres_1

    aws_terraform_aurora_postgres_2

    aws_terraform_aurora_postgres_3

    aws_terraform_aurora_postgres_4

    上手く作成できました。以上です。

  • PostgreSQL
  • Terraform
  • RDS