Terraform RDS Oracle 編

  • Oracle
  • Terraform
  • RDS
  • はじめに

    前提

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

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

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

    RDS Oracle 構築に必要なもの

    RDS Oracle を構築するための resource は aws_db_instance です。

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

    • aws_db_subnet_group
    • aws_security_group
    • aws_iam_role
    • aws_db_parameter_group
    • aws_db_option_group

    上記の一部はなくても default 設定が反映されるので構築は可能です。

    まずは、これらのコンポーネントの作成方法から見ていきたいと思います。

    準備

    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 = "Oracle" from_port = 1521 to_port = 1521 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 を作成した際には、AWS RDS がログを CloudWatch Logs に転送する設定を選択すると、専用のサービスロール(AmazonRDSEnhancedMonitoringRole )が自動的に RDS にセットされています。

    これも 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_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" "rds_oracle_pg" { name = "sample-rds-oracle-pg" family = "oracle-se2-19" parameter { name = "audit_trail" value = "DB,EXTENDED" apply_method = "pending-reboot" } tags = { Service = "sample" } }

    aws_db_option_group

    タイムゾーンを東京にしておきます。

    # aws_db_option_group # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_option_group resource "aws_db_option_group" "rds_oracle_opg" { name = "sample-rds-oracle-opg" engine_name = "oracle-se2" major_engine_version = 19 option { option_name = "Timezone" option_settings { name = "TIME_ZONE" value = "Asia/Tokyo" } } tags = { Service = "sample" } }

    RDS Oracle 構築

    aws_db_instance

    Terraform で迷うところが、エンジンバージョンなどの記載方法です。少しでも間違えると、そんなバージョンありません、というエラーが出てしまいます。

    なるべく全ての項目を指定する形で作成しました。

    # aws_db_instance # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/db_instance resource "aws_db_instance" "rds_oracle_instance" { identifier = "sample-oracle" instance_class = "db.r5.large" engine = "oracle-se2" engine_version = "19.0.0.0.ru-2019-07.rur-2019-07.r1" license_model = "license-included" multi_az = false # default false name = "SAMPLEDB" # must be upper, default ORCL username = "xxxxxx" password = "xxxxxxxxxxxx" # storage storage_type = "gp2" # The default is "io1" allocated_storage = 20 # depends on storage_type max_allocated_storage = 1000 # 0 to disable Storage Autoscaling. storage_encrypted = true # declare KMS key ARN if true, default false # kms_key_id = "" # set KMS ARN, default "aws/rds" # network db_subnet_group_name = aws_db_subnet_group.db_subnet.name vpc_security_group_ids = [aws_security_group.private_sg.id] port = 1521 # 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.rds_monitoring_role.arn enabled_cloudwatch_logs_exports = ["alert", "audit", "listener", "trace"] # backup snapshot backup_retention_period = 0 # default 7 (days). 0 = disabled. backup_window = "01:00-01:30" # must not overlap with maintenance_window. copy_tags_to_snapshot = true # default false delete_automated_backups = true # default true deletion_protection = false # default false skip_final_snapshot = true # default false # final_snapshot_identifier = "" # must be provided if skip_final_snapshot is set to false. # options parameter_group_name = aws_db_parameter_group.rds_oracle_pg.name option_group_name = aws_db_option_group.rds_oracle_opg.name character_set_name = "UTF8" # Oracle and Microsoft SQL auto_minor_version_upgrade = false # default true maintenance_window = "Mon:02:00-Mon:03:00" # tags tags = { Service = "sample" } }

    データベース名は大文字で

    リソースを作成した後に、パラメータを変更したり、オプションを変更したりといったことはよくありますね。

    そこで注意しなければいけないことが、データベース名の文字です。小文字で書いてしまうと、毎回リソースを destroy してから、再度 create する挙動になってしまいます。

    データベース名を大文字で書いておけば destroy してから、再度 create する挙動とはなりません。

    原因は、Terafform と Oracle の相互の仕様によるものと思われますが、直接ソースを見たわけではないので私も詳しくは分かりません。

    バックアップの保持期間(backup_retention_period)は慎重に

    上記のコードでは、backup_retention_period = 0 としています。理由は、すぐにリソースを削除できるようにするためです。

    本番用では要件に合わせてバックアップの保持期間(backup_retention_period)を設定すべきです。

    ただ、検証等で使う場合はすぐに削除してしまうこともあるかと思います。

    気を付けなければいけないのは、※RDS Oracle の自動スナップショットはオプショングループと紐づけられるという仕様です。

    自動スナップショットが存在する限り、オプショングループは使用中となり削除できなくなります。

    つまり、バックアップの保持期間(backup_retention_period)を 1 以上に設定しておくと、バックアップのスナップショットが自動で作成されてしまい、オプショングループの削除が出来なくなってしまう罠に陥る場合があります。

    自動スナップショットが時間の経過とともに削除されれば、オプショングループも削除できるようになります。

    terraform apply

    実行してみます。

    PS C:\Users\...\terraform_aws> terraform apply Plan: 5 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: 5 added, 0 changed, 0 destroyed.

    実行結果を確認

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

    title

    title

    title

    title

    title

    一通り確認することができました。

    以上です。

  • Oracle
  • Terraform
  • RDS