AWS Secrets Manager and Terraform Integration for Secure Credential Management

AWS Secrets Manager provides a managed service for securely encrypting, storing, and rotating credentials for databases and other services. It helps replace hardcoded credentials in code, including passwords, with an API call to retrieve the secret programmatically. In Secrets Manager, a secret consists of credentials information which is the secret value and its metadata. The secret value can be binary, a single string, or multiple strings. Secrets Manager uses 256-bit Advanced Encryption Standard symmetric data keys to encrypt secret values.

You can access and work with Secrets Manager by using any of the following approaches:

Secrets Manager console
Command line tools
AWS SDKs
HTTPS Query API, also called the Secrets Manager API
AWS Secrets Manager endpoints

Terraform stores information about your managed AWS infrastructure and its configurations. This information is called the state. By default, the state is stored in a local file named Terraform.tfstate. This file is in JSON format, and Terraform might store sensitive data in this state file in plain text.

AWS Secrets Manager is a managed service for storing and retrieving secrets like database credentials, API keys, and tokens. When combined with Terraform, it provides a clean workflow where infrastructure code can both create secrets and reference them without hardcoding the actual values in configuration files. Secret values managed with Terraform can still be stored in Terraform state, so protect your state backend carefully or use write-only attributes where available.

Secrets Manager Fundamentals for Terraform Users

Secrets Manager is the service layer that makes secret lifecycle operations safe for infrastructure as code. The service enables you to easily rotate, manage, and retrieve database credentials, API keys, and other secrets throughout their lifecycle.

The secret object contains two parts. The secret value holds the credentials and may be binary, a single string, or multiple strings. The metadata contains description, tags, recovery window, and encryption configuration. Encryption is performed with 256-bit Advanced Encryption Standard symmetric data keys.

For Terraform authors, the critical property is how Secrets Manager exposes secrets to automation. The Secrets Manager API and AWS SDKs allow Terraform provider actions to create secrets, update versions, and read values. This means Terraform can treat secrets as first-class resources rather than injecting values from external files.

Access patterns matter for security. Secrets Manager console provides manual inspection. Command line tools enable quick validation. AWS SDKs and HTTPS Query API provide programmatic access that Terraform uses under the hood. Endpoints allow regional routing.

State Risks and Write-Only Attributes

Terraform stores information about your managed AWS infrastructure and its configurations. This information is called the state. By default, the state is stored in a local file named Terraform.tfstate. This file is in JSON format, and Terraform might store sensitive data in this state file in plain text.

This state behavior creates a specific risk when Terraform manages secrets. Even if secrets are stored in AWS Secrets Manager, the Terraform configuration may still capture the secret value in state when using awssecretsmanagersecretversion.secretstring. Secret values managed with Terraform can still be stored in Terraform state, so protect your state backend carefully or use write-only attributes where available.

Write-only attributes were introduced to address this. The module documentation notes that Terraform >= 1.11.0 is required for ephemeral resources and write-only arguments. AWS provider >= 6.50.0 is required so the module can use awssecretsmanagersecretversion.secretstringwo / secretstringwoversion safely. Version 6.50.0 includes Secrets Manager fixes for final-plan consistency, creation eventual consistency, empty versionstages, and switching between secretstring and secretstringwo.

The practical implication is that providers and modules now expose write-only arguments that prevent secret values from being read back into state. Using these attributes requires careful version pinning and a remote state backend with encryption at rest such as S3 with SSE and DynamoDB locking.

Creating Secrets with Terraform Resources

Creating secrets in Terraform follows a two-resource pattern. First define the secret container, then store the secret value as a version.

hcl resource "aws_secretsmanager_secret" "database" { name = "production/database/credentials" description = "Database credentials for the production environment" recovery_window_in_days = 30 tags = { Environment = "production" ManagedBy = "terraform" } }

The awssecretsmanagersecret resource creates the container. Attributes include name, description, recoverywindowin_days which controls days before permanent deletion, and tags.

Secret value is stored with a version resource:

hcl resource "aws_secretsmanager_secret_version" "database" { secret_id = aws_secretsmanager_secret.database.id secret_string = jsonencode({ username = "admin" password = random_password.database.result engine = "postgres" host = aws_db_instance.main.address port = 5432 dbname = "myapp" }) }

The secretstring can be a JSON object with multiple key value pairs. This matches Secrets Manager support for multiple strings. Binary secrets are also supported via secretbinary.

Random generation is typically done with the random provider:

hcl resource "random_password" "database" { length = 32 special = true override_special = "!#$%&*()-_=+[]{}<>:?" }

This pattern generates a random password dynamically and injects it into the secret without hardcoding. The example shows length 32 with special characters. Another example from guidance uses length 16 with overridespecial "!%^".

Terraform often requires sensitive information such as API keys, passwords, and cloud credentials to create and manage resources. Managing these secrets securely is a key part of infrastructure automation.

Retrieving Existing Secrets

Read existing secrets using data sources. Data sources allow Terraform to reference secrets that are managed outside the current configuration or created by another team. This avoids coupling creation and consumption in a single plan.

Retrieving secrets is the read side of the workflow. Infrastructure such as RDS, ECS tasks, or Lambda functions can reference secrets via data source lookups and pass them to resources without embedding values in code.

Module Based Secret Management

Production teams often use community modules to avoid repeating validation and policy logic. A Terraform module to create Amazon Secrets Manager resources with comprehensive input validation and advanced features is available.

Module capabilities include:

Component Feature
Input Validation Comprehensive validation for all variables to prevent configuration errors
Type Safety Strongly typed variables with structured object definitions
Secret Rotation Built-in support for automatic secret rotation with Lambda functions
Cross-Region Replication Support for replicating secrets across AWS regions
KMS Encryption Support for customer-managed KMS keys
Resource Policies Attach custom IAM policies to secrets
Flexible Secret Types Support for plain text, key/value pairs, and binary secrets

Version requirements are explicit. The module declares the AWS provider minimum at the root, so all usage modes use the same compatibility policy.

Component Minimum version Notes
Terraform >= 1.11.0 Required for ephemeral resources and write-only arguments
AWS provider >= 6.50.0 Required so the module can use awssecretsmanagersecretversion.secretstringwo / secretstringwoversion safely. Version 6.50.0 includes Secrets Manager fixes for final-plan consistency, creation eventual consistency, empty versionstages, and switching between secretstring and secretstringwo

An example module invocation for a standard secret with policy:

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

nameprefix = "example"
description = "Example Secrets Manager secret"
recovery
windowindays = 30

createpolicy = true
block
publicpolicy = true
policy
statements = {
read = {
sid = "AllowAccountRead"
principals = [{
type = "AWS"
identifiers = ["arn:aws:iam::1234567890:root"]
}]
actions = ["secretsmanager:GetSecretValue"]
resources = ["*"]
}
}

createrandompassword = true
randompasswordlength = 64
randompasswordoverridespecial = "!@#$%^&*()+"
tags = {
Environment = "Development"
Project = "Example"
}
}
```

A rotated example shows a different recovery window and expanded actions:

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

nameprefix = "rotated-example"
description = "Rotated example Secrets Manager secret"
recovery
windowindays = 7

createpolicy = true
block
publicpolicy = 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
}
}
}
```

Secret Rotation, Replication, and Encryption

Secret rotation is a core Secrets Manager capability. Rotation can be automatic with Lambda functions. The module provides built-in support for automatic secret rotation with Lambda functions.

Cross-region replication allows secrets to be replicated across AWS regions for low-latency access and disaster recovery. The module supports replicating secrets across AWS regions.

KMS encryption allows use of customer-managed KMS keys. Support for customer-managed KMS keys enables centralized key policies and audit trails.

Resource policies can be attached to secrets to restrict who can read or write. The module supports attaching custom IAM policies to secrets.

Flexible secret types cover plain text, key/value pairs, and binary secrets. This matches the service definition that secret value can be binary, a single string, or multiple strings.

Terraform Variables and State Protection

We can mark variables as sensitive to prevent their values from being displayed in the CLI output or logs.

hcl variable "db-password" { description = "Database password" type = "string" sensitive = true }

Although Terraform hides sensitive values in logs, they are still stored in the state file, so we need to secure the state file properly with remote backend like S3 + DynamoDB with encryption at rest SSE.

Best practices for managing Terraform secrets state:

  • Use a real secrets manager for all sensitive values. Never commit secrets to Git, *.tfvars, or CI variables in plain text.
  • Use a remote backend with encryption at rest. S3 with SSE plus DynamoDB locking is common.
  • Use write-only attributes where available to avoid storing secret values in state.
  • Use least-privilege IAM roles for Terraform execution. The policy only allows reading a specific secret from AWS Secrets Manager and managing a single RDS instance.

In a real-world setup, you will replace the ARNs, region, and resource names with values from your own environment. Further restrict resources by using tags or more specific ARNs. Split responsibilities into multiple roles per environment for example one role for networking and one for databases.

The important part is that Terraform is codifying least-privilege RBAC: only the actions needed, on the smallest possible set of resources, regularly reviewed as your infrastructure evolves.

Best Practices Summary

Terraform was never meant to be your secrets store. The best way to manage Terraform secrets is to use a dedicated secrets manager Vault, OpenBao, or AWS Secrets Manager and run workflows through an orchestration layer like Spacelift. Done right, secrets stay out of plain text and version control, access is least-privilege and time-bound, and you still get strong governance and auditability.

Secrets protect sensitive information about the organization’s infrastructure and operations. This includes system passwords, encryption keys, APIs, service certificates, and other forms of confidential data. Secrets secure such information by preventing unauthorized access, data breaches, or critical security incidents.

Secrets are used in various phases of Terraform provisioning for activities like securing access to services provided by cloud platforms such as AWS, Azure, and Google Cloud, securing access to active databases that contain sensitive data such as customer information, financial records, setting up authentication through API keys, OAuth tokens, and SSL certificates to allow the user access to applications, and setting up access to network components such as routers, switches, and firewalls.

Terraform uses secrets to automate infrastructure provisioning activities similar to the ones listed above.

Conclusion

AWS Secrets Manager and Terraform together provide a production ready path for handling credentials without hardcoding. Secrets Manager supplies encryption with 256-bit Advanced Encryption Standard, metadata management, rotation, replication, and KMS integration. Terraform supplies declarative lifecycle control with the caveat that state files may contain sensitive data in plain text.

The secure pattern is to create secrets with awssecretsmanagersecret and awssecretsmanagersecretversion, generate values dynamically with randompassword, and avoid storing them in state using write-only attributes and provider versions >= 6.50.0. Modules add validation, type safety, rotation, replication, and policy attachment, reducing manual error.

State protection remains the central responsibility. Use remote encrypted backends, mark variables sensitive, and prefer data sources for consumption. Use least-privilege IAM policies scoped to specific secrets and actions. Never commit secrets to Git, tfvars, or CI variables in plain text.

When these controls are combined, infrastructure code can both create secrets and reference them without hardcoding actual values, while auditability and rotation are maintained by Secrets Manager and governance is enforced by Terraform.

Sources

  1. AWS Documentation
  2. OneUptime
  3. GitHub lgallard
  4. GitHub terraform-aws-modules
  5. AWS PlainEnglish
  6. Spacelift Blog

Related Posts