クラウドインテグレーション部の渡邊です。
今回は、Terraformを利用して、RDSを構築する際に設定可能なapply_immediately
について検証しました。apply_immediately
は設定値の変更を、すぐに適用するための設定です。aws_rds_cluster
にapply_immediately
をtrue
にしている状況でca_cert_identifier
の設定値を変更したところ、設定が即時反映されていない事象が確認されました。
なぜこのようなことが起こってしまったか、動作確認しながら見ていきましょう。
今回使用した初期コードはこちらです。
ネットワークリソース等は、既存環境の値を用いる想定でコードを作成しました。variable
は省略しているため、ご自身の環境に合ったものをご用意ください。
provider "aws" {
region = "ap-northeast-1"
}
terraform {
required_version = "~> 1.6.5"
backend "s3" {
bucket = "test-bucket"
key = "actions/rds/terraform.tfstate"
region = "ap-northeast-1"
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.29.0"
}
}
}
resource "aws_db_subnet_group" "db-subgp" {
name = "test-dbsg"
subnet_ids = [
var.subnet-1a,
var.subnet-1c
]
}
resource "aws_rds_cluster" "db" {
cluster_identifier = "test-db-cluster"
db_cluster_parameter_group_name = "default.aurora-mysql8.0"
db_subnet_group_name = aws_db_subnet_group.db-subgp.name
vpc_security_group_ids = [var.sg]
engine_mode = "provisioned"
master_username = "admin"
master_password = "Passw0rd!"
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.02.0"
port = 3306
apply_immediately = false
serverlessv2_scaling_configuration {
max_capacity = 64
min_capacity = 0.5
}
}
resource "aws_rds_cluster_instance" "db-instance" {
identifier = "test-db-instance-01"
cluster_identifier = aws_rds_cluster.db.id
instance_class = "db.serverless"
engine = aws_rds_cluster.db.engine
engine_version = aws_rds_cluster.db.engine_version
ca_cert_identifier = "rds-ca-2019"
}
aws_rds_cluster
にapply_immediately
をTrue
にしている状況で、ca_cert_identifier
の値を、rds-ca-2019
からrds-ca-rsa2048-g1
に変更します。
その後、terraform plan
コマンドで、設定変更されるリソースを確認します。
$ terraform plan
aws_db_subnet_group.db-subgp: Refreshing state... [id=test-dbsg]
aws_rds_cluster.db: Refreshing state... [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Refreshing state... [id=test-db-instance-01]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
~ update in-place
Terraform will perform the following actions:
# aws_rds_cluster.db will be updated in-place
~ resource "aws_rds_cluster" "db" {
~ apply_immediately = false -> true
id = "test-db-cluster"
tags = {}
# (37 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# aws_rds_cluster_instance.db-instance will be updated in-place
~ resource "aws_rds_cluster_instance" "db-instance" {
~ ca_cert_identifier = "rds-ca-2019" -> "rds-ca-rsa2048-g1"
id = "test-db-instance-01"
tags = {}
# (26 unchanged attributes hidden)
}
Plan: 0 to add, 2 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform
apply" now.
terraform apply
コマンドで設定を適用します。
$ terraform apply -auto-approve
aws_db_subnet_group.db-subgp: Refreshing state... [id=test-dbsg]
aws_rds_cluster.db: Refreshing state... [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Refreshing state... [id=test-db-instance-01]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
~ update in-place
Terraform will perform the following actions:
# aws_rds_cluster.db will be updated in-place
~ resource "aws_rds_cluster" "db" {
~ apply_immediately = false -> true
id = "test-db-cluster"
tags = {}
# (37 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# aws_rds_cluster_instance.db-instance will be updated in-place
~ resource "aws_rds_cluster_instance" "db-instance" {
~ ca_cert_identifier = "rds-ca-2019" -> "rds-ca-rsa2048-g1"
id = "test-db-instance-01"
tags = {}
# (26 unchanged attributes hidden)
}
Plan: 0 to add, 2 to change, 0 to destroy.
aws_rds_cluster.db: Modifying... [id=test-db-cluster]
aws_rds_cluster.db: Still modifying... [id=test-db-cluster, 10s elapsed]
aws_rds_cluster.db: Still modifying... [id=test-db-cluster, 20s elapsed]
aws_rds_cluster.db: Still modifying... [id=test-db-cluster, 30s elapsed]
aws_rds_cluster.db: Modifications complete after 31s [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Modifying... [id=test-db-instance-01]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 10s elapsed]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 20s elapsed]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 30s elapsed]
aws_rds_cluster_instance.db-instance: Modifications complete after 31s [id=test-db-instance-01]
Apply complete! Resources: 0 added, 2 changed, 0 destroyed.
設定変更に成功しましたが、実機の値を確認すると設定変更が行われていません。
aws rds describe-db-instances
コマンドで情報を確認すると、設定変更が次回のメンテナンスウィンドウで適用されることがわかります(抜粋)。
"PreferredMaintenanceWindow": "sun:14:40-sun:15:10",
"PendingModifiedValues": {
"CACertificateIdentifier": "rds-ca-rsa2048-g1"
}
terraform plan
コマンドで、変更されるリソースを確認すると、以下の通りステートファイルと実機の値に差異があります(抜粋)。
ステートファイルは、Terraformが管理対象とするインフラの状態を保存するものです。
# aws_rds_cluster_instance.db-instance will be updated in-place
~ resource "aws_rds_cluster_instance" "db-instance" {
~ ca_cert_identifier = "rds-ca-2019" -> "rds-ca-rsa2048-g1"
id = "test-db-instance-01"
tags = {}
# (27 unchanged attributes hidden)
}
ドキュメントの情報から以下がわかります。
aws_rds_cluster
のapply_immediately
の値をtrue
にする(デフォルトはfalse
)aws_rds_cluster_instance
のapply_immediately
の値をtrue
にする(デフォルトはfalse
)apply_immediately - (Optional) Specifies whether any database modifications are applied immediately, or during the next maintenance window. Default isfalse.
引用元:Resource: aws_rds_cluster_instance
apply_immediately - (Optional) Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is false. See Amazon RDS Documentation for more information.
今回は、aws_rds_cluster_instance
のapply_immediately
の値をtrue
に設定していなかったため、即時反映されていないと考えられます。apply_immediately
をtrue
にして、再度設定変更を適用します。
$ terraform apply -auto-approve
aws_db_subnet_group.db-subgp: Refreshing state... [id=test-dbsg]
aws_rds_cluster.db: Refreshing state... [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Refreshing state... [id=test-db-instance-01]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# aws_rds_cluster_instance.db-instance will be updated in-place
~ resource "aws_rds_cluster_instance" "db-instance" {
~ apply_immediately = false -> true
~ ca_cert_identifier = "rds-ca-2019" -> "rds-ca-rsa2048-g1"
id = "test-db-instance-01"
tags = {}
# (26 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
aws_rds_cluster_instance.db-instance: Modifying... [id=test-db-instance-01]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 10s elapsed]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 20s elapsed]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 30s elapsed]
aws_rds_cluster_instance.db-instance: Modifications complete after 32s [id=test-db-instance-01]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
設定変更が即時反映され、ステートファイルと実機の値に、差異はないことが以下の情報からわかります。
$ terraform plan
aws_db_subnet_group.db-subgp: Refreshing state... [id=test-dbsg]
aws_rds_cluster.db: Refreshing state... [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Refreshing state... [id=test-db-instance-01]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
以上で本件は解決ですが、apply_immediately
の設定において、apply_immediately
の値を保持する事象が、執筆時点(2023/11/9)で確認されたので注意してください。
まず、apply_immediately
の値がtrue
の状態から、apply_immediately
をコメントアウトします。
resource "aws_rds_cluster_instance" "db-instance" {
identifier = "test-db-instance-01"
cluster_identifier = aws_rds_cluster.db.id
instance_class = "db.serverless"
engine = aws_rds_cluster.db.engine
engine_version = aws_rds_cluster.db.engine_version
# apply_immediately = true
ca_cert_identifier = "rds-ca-rsa2048-g1"
}
ドキュメントの記述(再掲)の通り、デフォルト値はfalse
なのでコメントアウトしたらfalse
に変更される想定です。
apply_immediately - (Optional) Specifies whether any database modifications are applied immediately, or during the next maintenance window. Default is false. See Amazon RDS Documentation for more information.
引用元:Resource: aws_rds_cluster_instance
ただ、設定変更予定のリソースを確認すると、以下の通り、変更はない旨のメッセージが表示されます。
$ terraform plan
aws_db_subnet_group.db-subgp: Refreshing state... [id=test-dbsg]
aws_rds_cluster.db: Refreshing state... [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Refreshing state... [id=test-db-instance-01]
No changes. Your infrastructure matches the configuration.
つまりapply_immediately
の最後に指定した値true
を保持しているということになります。apply_immediately
をコメントアウトした状態で、ca_cert_identifier
の値をrds-ca-rsa2048-g1
からrds-ca-2019
に変更します。terraform apply
コマンドで設定変更を適用します(抜粋)。
Terraform will perform the following actions:
# aws_rds_cluster_instance.db-instance will be updated in-place
~ resource "aws_rds_cluster_instance" "db-instance" {
~ ca_cert_identifier = "rds-ca-rsa2048-g1" -> "rds-ca-2019"
id = "test-db-instance-01"
tags = {}
# (27 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
(略)
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
設定の適用に成功したため、設定値を確認すると、設定変更が即時反映されてました。
では、apply_immediately
をfalse
にして、ca_cert_identifier
の値をrds-ca-2019
からrds-ca-rsa2048-g1
に変更して、再確認します。
$ terraform apply -auto-approve
aws_db_subnet_group.db-subgp: Refreshing state... [id=test-dbsg]
aws_rds_cluster.db: Refreshing state... [id=test-db-cluster]
aws_rds_cluster_instance.db-instance: Refreshing state... [id=test-db-instance-01]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# aws_rds_cluster_instance.db-instance will be updated in-place
~ resource "aws_rds_cluster_instance" "db-instance" {
~ apply_immediately = true -> false
~ ca_cert_identifier = "rds-ca-2019" -> "rds-ca-rsa2048-g1"
id = "test-db-instance-01"
tags = {}
# (26 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
aws_rds_cluster_instance.db-instance: Modifying... [id=test-db-instance-01]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 10s elapsed]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 20s elapsed]
aws_rds_cluster_instance.db-instance: Still modifying... [id=test-db-instance-01, 30s elapsed]
aws_rds_cluster_instance.db-instance: Modifications complete after 31s [id=test-db-instance-01]
すると、コンソールの設定値とaws rds describe-db-instances
実行結果(抜粋)から、設定がまだ反映されていないことが確認できました。
"PendingModifiedValues": {
"CACertificateIdentifier": "rds-ca-rsa2048-g1"
},
今回は、ca_cert_identifier
のみ検証対象としているため、他の設定が同様の挙動であるかわかりませんのでご注意ください。
apply_immediately
はクラスター(aws_rds_cluster
)およびインスタンス(aws_rds_cluster_instance
)に設定可能である
aws_rds_cluster
のapply_immediately
の値をtrue
にする(デフォルトはfalse
)aws_rds_cluster_instance
のapply_immediately
の値をtrue
にする(デフォルトはfalse
)apply_immediately
をtrue
の設定適用後、apply_immediately
を設定値ごと消した場合、デフォルト値のfalse
にならない
【参考】
Resource: aws_rds_cluster
Resource: aws_rds_cluster_instance