Sign in
Menu
Start free trial

AWS Secrets Manager Terraform module

Terraform module which creates AWS Secrets Manager resources.

SWUbanner

Usage

See examples directory for working examples to reference:

Standard

module "secrets_manager" {
  source = "terraform-aws-modules/secrets-manager/aws"

  # Secret
  name_prefix             = "example"
  description             = "Example Secrets Manager secret"
  recovery_window_in_days = 30

  # Policy
  create_policy       = true
  block_public_policy = true
  policy_statements = {
    read = {
      sid = "AllowAccountRead"
      principals = [{
        type        = "AWS"
        identifiers = ["arn:aws:iam::1234567890:root"]
      }]
      actions   = ["secretsmanager:GetSecretValue"]
      resources = ["*"]
    }
  }

  # Version
  create_random_password           = true
  random_password_length           = 64
  random_password_override_special = "!@#$%^&*()_+"

  tags = {
    Environment = "Development"
    Project     = "Example"
  }
}

w/ Rotation

module "secrets_manager" {
  source = "terraform-aws-modules/secrets-manager/aws"

  # Secret
  name_prefix             = "rotated-example"
  description             = "Rotated example Secrets Manager secret"
  recovery_window_in_days = 7

  # Policy
  create_policy       = true
  block_public_policy = true
  policy_statements = {
    lambda = {
      sid = "LambdaReadWrite"
      principals = [{
        type        = "AWS"
        identifiers = ["arn:aws:iam:1234567890:role/lambda-function"]
      }]
      actions = [
        "secretsmanager:DescribeSecret",
        "secretsmanager:GetSecretValue",
        "secretsmanager:PutSecretValue",
        "secretsmanager:UpdateSecretVersionStage",
      ]
      resources = ["*"]
    }
    read = {
      sid = "AllowAccountRead"
      principals = [{
        type        = "AWS"
        identifiers = ["arn:aws:iam::1234567890:root"]
      }]
      actions   = ["secretsmanager:DescribeSecret"]
      resources = ["*"]
    }
  }

  # Version
  ignore_secret_changes = true
  secret_string = jsonencode({
    engine   = "mariadb",
    host     = "mydb.cluster-123456789012.us-east-1.rds.amazonaws.com",
    username = "Bill",
    password = "Initial"
    dbname   = "ThisIsMySuperSecretString12356!&*()",
    port     = 3306
  })

  # Rotation
  enable_rotation     = true
  rotation_lambda_arn = "arn:aws:lambda:us-east-1:123456789012:function:my-function"
  rotation_rules = {
    # This should be more sensible in production
    schedule_expression = "rate(1 minute)"
  }

  tags = {
    Environment = "Development"
    Project     = "Example"
  }
}

Metadata Only (Value Managed Externally)

module "secrets_manager" {
  source = "terraform-aws-modules/secrets-manager/aws"

  # Secret
  name        = "my-app/prod/api-key"
  description = "API key managed by CI/CD pipeline"

  # Skip secret version creation - value is managed outside Terraform
  create_secret_version = false

  tags = {
    Environment = "Production"
    Project     = "Example"
  }
}

Known limitations (Terraform/OpenTofu, not this module)

A few requests come up again and again and cannot be implemented by this module, or by any module: Terraform requires lifecycle arguments to be literal values inside the resource block. hashicorp/terraform#18367 has been open since 2018, #22544 since 2019, and opentofu/opentofu#1329 is the same request for OpenTofu.

  • terraform destroy deleted a secret other systems depend on - Native option: keep recovery_window_in_days at a real value so a deleted secret can be restored.

Compliance.tf serves this module with these rules applied at download time, on top of whatever your organization already has enabled there. Inputs and outputs do not change; the source line does. Drop the version argument and pin the release you use by adding &version= and that release number to the URL. To get started, register a free compliance.tf account and configure an access token:

source = "https://registry.compliance.tf/terraform-aws-modules/secrets-manager/aws?add_rules=lifecycle_prevent_destroy_encryption"

The full workaround for each item above, and the exact diff each rule makes, are in the compliance.tf docs for this module. To preview a diff without an account, open this module in the Rules Playground.

Disclosure: written by this module's maintainer, who also builds compliance.tf.

Examples

Examples codified under the examples are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module. If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you!

License

Apache-2.0 Licensed. See LICENSE.