Search code examples
terraformaws-secrets-manager

Is it possible to set up a multiuser secret rotation in AWS secrets manager with terraform?


... Given the existing capabilities of terraform (v.3.23.0)

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_rotation

Or is it simply not available in terraform yet as of this writing? Obviously, this can be done in the AWS UI, but I'm interested in scripting it out in TF.

I have a simple example for rotating a singular secret in AWS secrets manager, but if I edit the created rotation associated with that secret in the AWS dashboard, there is no way to make it a multi-user rotation -- the UI simply does not show it as being an option.

    resource "aws_secretsmanager_secret_rotation" "rds_postgres_key_rotation" {
      secret_id           = aws_secretsmanager_secret.rotation_example.id
      rotation_lambda_arn = aws_serverlessapplicationrepository_cloudformation_stack.postgres_rotator.outputs["RotationLambdaARN"]
    
      rotation_rules {
        automatically_after_days = 1
      }
    }
    
    resource "aws_secretsmanager_secret" "rotation_example" {
      name       = "normalusersecret"
      kms_key_id = aws_kms_key.my_key.id
    }

resource "aws_serverlessapplicationrepository_cloudformation_stack" "postgres_rotator" {
  name           = "postgres-rotator"
  application_id = "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSPostgreSQLRotationMultiUser"
  capabilities = [
    "CAPABILITY_IAM",
    "CAPABILITY_RESOURCE_POLICY",
  ]
  parameters = {
    functionName = "func-postgres-rotator"
    #endpoint     = "secretsmanager.${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}"
    endpoint = "secretsmanager.us-east-1.lambda.amazonaws.com"
  }
}

Solution

  • It appears that the SecretsManager just inspects the Secret Value JSON for the masterarn key. If that key exists, it flips the multi user radio button.

    e.g.

    Single user

    resource "aws_secretsmanager_secret_version" "example" {
      secret_id = aws_secretsmanager_secret.example.id
      secret_string = tostring(jsonencode({
        password            = "password"
        username            = "user"
      }))
    }
    

    Multi user

    resource "aws_secretsmanager_secret_version" "example" {
      secret_id = aws_secretsmanager_secret.example.id
      secret_string = tostring(jsonencode({
        masterarn           = aws_secretsmanager_secret.master.arn
        password            = "password"
        username            = "user"
      }))
    }