Cycle : DB and secret manager

i’m attempting to create the rds while leveraging aws secrets manager.
Unfortunately Im running into a cycle dependency.

Appreciate your input.

Simplified code:

resource "aws_db_instance" "dbs" {
  for_each = var.RDS
  engine         = each.value.engine
  username       = each.value.username
  password       = jsondecode(data.aws_secretsmanager_secret_version.rds_secret_data[each.key]).password


resource "aws_secretsmanager_secret" "rds_secret" {
  for_each = var.RDS
  name = "blah"

resource "random_password" "password" {
  for_each = var.RDS
  length           = 16
  special          = true
  override_special = "!#$%&*()-_=+[]{}<>:?"

resource "aws_secretsmanager_secret_version" "rds_secret_version" {
  for_each = var.RDS
  secret_id     = aws_secretsmanager_secret.rds_secret[each.key].id
  secret_string = jsonencode("
           username = ${each.value.username} ,
           password  = "XXXX",
           engine = ${each.value.engine}, 
           host = ${aws_db_instance.dbs.endpoint}, 
           port = ${aws_db_instance.dbs.port}, 
           dbInstanceIdentifier = ${aws_db_instance.dbs.identifier}   ")

data aws_secretsmanager_secret_version rds_secret_data {
  for_each = var.RDS
  secret_id = aws_secretsmanager_secret.rds_secret[each.key].id

in the rds_secret_version resource, I have to provide aws_db_instance attributes that create a cycle …

The general idea is to use aws_secretsmanager_secret_rotation . For the rotation to work the secret_string has to include all connection parameters from RDS.

P.S. I can see dbs_cluster and aws_db_instance have the “automagical” support for the password now: the [Enhancement]: RDS support for storing master user password in Secrets Manager · Issue #28538 · hashicorp/terraform-provider-aws · GitHub
But that creates a secret with a random name that i prefer to avoid.

Hi @AZZ,

Someone else who is more familiar with this pair of AWS services might have a better answer than I do, but with my limited knowledge the best idea I can think of is to use two separate “secrets manager secrets”: one for the data that is the input to aws_rds_instance.dbs, and one for the data that contains outputs from that resource.

If you can’t avoid using only one secret then you’ll need to change the way you deal with the password so that the "XXXX" string is assigned to the password argument of aws_db_instance.dbs, and then the secret version can refer to aws_db_instance.dbs[each.key].password to populate the password. That will then resolve the cycle because the DB instance will no longer depend on the secret version.

Oh… of course! I’ve been over thinking the task all alone.

Thank you @apparentlymart!