-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description
When upgrading the module from version = "3.1.0" to version = "4.1.1", terraform tries to update my database username and password (which have not changed) however it fails with:
Error: Error modifying DB Instance au-devops-logs: InvalidParameterValue: The parameter MasterUserPassword must be provided and must not be blank. status code: 400, request id: c79cd027-bd63-4d4b-af3a-71942ec6251e
Notes:
I'm using Terraform Cloud to run my code, so all projects follow the best practices provided by Terraform Cloud.
Versions
- Terraform: 1.1.3 in Terraform Cloud
- This is the output of my local configuration from a fresh terraform init:
> terraform providers -version
Terraform v1.1.3
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v4.1.0
+ provider registry.terraform.io/hashicorp/cloudinit v2.2.0
+ provider registry.terraform.io/hashicorp/helm v2.0.1
+ provider registry.terraform.io/hashicorp/kubernetes v2.0.3
+ provider registry.terraform.io/hashicorp/local v2.1.0
+ provider registry.terraform.io/hashicorp/null v3.1.0
+ provider registry.terraform.io/hashicorp/random v3.1.0
+ provider registry.terraform.io/hashicorp/template v2.2.0
+ provider registry.terraform.io/terraform-aws-modules/http v2.4.1
- Module:
source = "terraform-aws-modules/rds/aws"
version = "4.1.1"
Reproduction
Steps to reproduce the behavior:
I'm using Terraform Cloud Workspaces.
I don't run locally. Runs are executed in Terraform Cloud. The problem is reported by Terraform Cloud.
a. I upgraded my AWS provider from 3.46.0 to 4.1.0 From my Git:
aws = {
source = "hashicorp/aws"
- version = "3.46.0"
+ version = "4.1.0"
configuration_aliases = [ aws.global, aws.dns, aws.storage ]
}
b. I upgraded the module version:
module "logs-db" {
source = "terraform-aws-modules/rds/aws"
- version = "3.1.0" <<< Version change here
+ version = "4.1.1"
... more code
- name = "au-devops-logs" <<< Changed the name parameter to db_name parameter
+ db_name = "au-devops-logs"
username = var.logs_db_admin_user <<< Notice the username and password didn't change
password = var.logs_db_admin_password <<< These values come from an encrypted source, no changes at all
<< This was verified ok because the values are also saved as Kubernetes secrets and the values are ok and unchanged
<< This is a development test logs DB so the values are:
<< LOGS_DB_ADMIN_USER: logs
<< LOGS_DB_ADMIN_PASSWORD: adminpassword
... more code
- final_snapshot_identifier = "au-devops-logs-final"
+ final_snapshot_identifier_prefix = "final"
+ create_db_subnet_group = true
}
The final code (simplified so its easier to replicate the code:
module "logs-db" {
source = "terraform-aws-modules/rds/aws"
version = "4.1.1"
identifier = "au-devops-logs"
snapshot_identifier = "au-devops-logs-backup" <<< IMPORTANT: This DB was initialised from a backup.
engine = "postgres"
engine_version = "13.2"
auto_minor_version_upgrade = false
family = "postgres13" # DB parameter group
major_engine_version = "13" # DB option group
instance_class = "db.t3.small"
allocated_storage = 10
max_allocated_storage = 1000
storage_encrypted = true
kms_key_id = "aws/rds"
db_name = "au-devops-logs"
username = var.logs_db_admin_user
password = var.logs_db_admin_password
port = 5432
vpc_security_group_ids = [sg-replace_your_sg_id]
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
backup_retention_period = 0
deletion_protection = false
performance_insights_enabled = true
performance_insights_retention_period = 7
parameters = [
{
name = "autovacuum"
value = 1
},
{
name = "client_encoding"
value = "utf8"
},
{
name = "timezone"
value = "UTC"
}
]
tags = {
Environment = "au-devops"
}
# Subnets with access to the DB
subnet_ids = var.private_subnets.
# Snapshot name upon DB deletion
final_snapshot_identifier_prefix = "final"
skip_final_snapshot = true
copy_tags_to_snapshot = true
option_group_description = "Option group for au-devops-logs"
option_group_timeouts = { "delete": "45m" }
parameter_group_description = "Database parameter group for au-devops-logs"
create_db_subnet_group = true
db_subnet_group_description = "Database subnet group for au-devops-logs"
multi_az = var.logs_db_multi_az
}
Expected behavior
Some parameters should update that's ok, but there shouldn't be any problems with the DB username and password as they have been unchanged.
Actual behavior
Along other updates, the module attempts to update the username and password. This is an output from Terraform Cloud:
~ password : Sensitive value << Tries to update password
~ username : Sensitive value << Tries to update username
This is harder to debug as TFC won't show the value because of its sensitive nature.
Terminal Output Screenshot(s)
Additional context
After reading the code of the terraform-aws-rds module, my suspicion is in the following lines:
terraform-aws-rds/module/db_instance/main.tf: Lines 7-9
metadata_already_exists = var.snapshot_identifier != null || var.replicate_source_db != null
username = local.metadata_already_exists ? null : var.username
password = local.metadata_already_exists ? null : var.password
My suspicion is that in this case, this code might work fine as long as the module is creating a DB from scratch. However in this case, the snapshot_identifier variable exists and is not null, therefore the local.metadata_already_exists variable will be true.
Given the local.metadata_already_exists is true, then the local.username and local.password vars will be set to null. Not sure the effect this might have on the DB change but the error message "The parameter MasterUserPassword must be provided and must not be blank." suggests a null value might not be welcome for the password.
In addition this kind of code immediately cancels the ability to change the master username and password. Imagine I would like to change those values because they have become compromised, then it's not possible because the local.username will take the null value if the snapshot_identifier is set.
Thanks!