amazon-web-servicesterraformterraform-provider-awsamazon-rds-proxy

Terraform use a list of configuration blocks as an argument


The Terraform resource, aws_db_proxy, has a list of auth block(s) as an argument. Below is an example from the terraform documentation.

Each auth block represents a user, and each user needs a secret in Secrets Manager. Our platform has four different environments (dev,qa,cert,prod), and we do not use secrets in our lower environments to save on costs. Ideally, I would create two lists of auth blocks, one for lower environments and one for upper environments. Then, in the resource I could pick the appropriate one based on environment.

Is there a way to pass a list of auth blocks to the aws_db_proxy resource?

The other solution I was thinking of was to use two separate aws_db_proxy configurations and use the appropriate one for each environment using the count meta-argument. However, I think this could get a little messy.

resource "aws_db_proxy" "example" {
  name                   = "example"
  debug_logging          = false
  engine_family          = "MYSQL"
  idle_client_timeout    = 1800
  require_tls            = true
  role_arn               = aws_iam_role.example.arn
  vpc_security_group_ids = [aws_security_group.example.id]
  vpc_subnet_ids         = [aws_subnet.example.id]

  auth {
    auth_scheme = "SECRETS"
    description = "user1"
    iam_auth    = "DISABLED"
    secret_arn  = aws_secretsmanager_secret.example1.arn
  }

  auth {
    auth_scheme = "SECRETS"
    description = "example2"
    iam_auth    = "DISABLED"
    secret_arn  = aws_secretsmanager_secret.example2.arn
  }

  auth {
    auth_scheme = "SECRETS"
    description = "example3"
    iam_auth    = "DISABLED"
    secret_arn  = aws_secretsmanager_secret.example3.arn
  }

  tags = {
    Name = "example"
    Key  = "value"
  }
}

Solution

  • You could use dynamic blocks to create auth blocks dynamically.

    An example usage would depend on exactly how are you defing your aws_secretsmanager_secret for each user, but you could also make it dynamic.

    Below is sample code. I haven't run it as its aim is to demonstrate the concept of the use of dynamic blocks and how you could make your aws_secretsmanager_secret:

    # list of users
    variable "proxy_users" {
        default = ["user1", "example2", "example3"]
    }
    
    # secret for each user
    resource "aws_secretsmanager_secret" "mysecret" {
      for_each = toset(var.proxy_users) 
    
      name = "example${each.key}"
    
      # rest of attributes
    }
    
    
    resource "aws_db_proxy" "example" {
      name                   = "example"
      debug_logging          = false
      engine_family          = "MYSQL"
      idle_client_timeout    = 1800
      require_tls            = true
      role_arn               = aws_iam_role.example.arn
      vpc_security_group_ids = [aws_security_group.example.id]
      vpc_subnet_ids         = [aws_subnet.example.id]
    
      # create auth for each user 
      dynamic "auth" {
    
        for_each = var.proxy_users
    
        content {
            auth_scheme = "SECRETS"
            description = auth.key
            iam_auth    = "DISABLED"
            secret_arn  = aws_secretsmanager_secret.mysecret[auth.key].arn
        }
      }  
    
      tags = {
        Name = "example"
        Key  = "value"
      }
    }