AWS Secrets Manager provides a service for securely encrypting, storing, and rotating credentials for databases and other services. It helps you replace hardcoded credentials in your 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 AES 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.
Combining Secrets Manager with Terraform creates 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.
How Secrets Manager Fits Terraform Workflows
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, etc.
- Setting up authentication through API keys, OAuth tokens, and SSL certificates to allow the user access to applications
- 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.
Modern infrastructure management revolves around secrets to ensure high environmental security. While most organizations are adopting infrastructure as code, managing secrets becomes challenging for technical teams.
Terraform will record anything it needs to compute in state. To manage Terraform secrets safely:
- Keep secrets out of code, no plaintext in .tf, .tfvars, or modules
- Use a secrets manager, Vault/OpenBao or cloud KMS/Secrets services
- Prefer dynamic, short-lived credentials via OIDC for CI/CD
- Protect Terraform state, remote backend, encryption, tight access controls
- Avoid leaking via outputs or logs, and rotate regularly
What are Terraform secrets?
Terraform secrets are sensitive data, such as API keys, passwords, and database connection strings, used to configure and manage your infrastructure. These secrets are crucial for accessing and authenticating to various services and systems within your infrastructure.
Creating Secrets with Terraform Resources
Creating a secret and storing a value is the simplest case.
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"
}
}
Store the secret value:
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"
})
}
Generate a random password:
resource "random_password" "database" {
length = 32
special = true
override_special = "!#$%&*()-_=+[]{}<>:?"
}
To create and manage secrets dynamically, three key Terraform resources are used:
- random_password generates a random password dynamically
- awssecretsmanagersecret defines secret name in AWS secrets manager
Example random password definition:
resource "random_password" "db_password"{
length = 16
special = true
override_special = "_!%^"
}
Managing Secrets Securely with External Tools
Terraform can fetch and manage secrets stored in external secret management services such as Hashicorp vault, AWS secrets manager, Azure key vault etc.
Let’s look at how to generate and store secrets securely using AWS Secrets Manager in a Terraform project.
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.
Using Terraform Variables with sensitive = true
We can mark variables as sensitive to prevent their values from being displayed in the CLI output or logs.
variable "db-password"{
description= "Database password"
type = "string"
sensitive = true
}
Although Terraform hides sensitive values in logs, they are still stored, encrypted or not, in the state file, so we need to secure the statefile properly with remote backend like S3 + DynamoDB with encryption at rest SSE.
Retrieving Secrets and Data Sources
Read existing secrets using data sources.
The guide covers the full range of Secrets Manager operations in Terraform. Infrastructure code can both create secrets and reference them without hardcoding the actual values in configuration files.
Terraform offers many different methods for managing these secrets, such as using environment variables, leveraging secret management tools like HashiCorp Vault and AWS Secrets Manager, or encrypting sensitive data.
State Protection and Best Practices
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.
Best practices for managing Terraform secrets:
- Use a real secrets manager for all sensitive values — never commit secrets to Git, *.tfvars, or CI variables in plain text
- Keep secrets out of code, no plaintext in .tf, .tfvars, or modules
- Use a secrets manager Vault/OpenBao or cloud KMS/Secrets services
- Prefer dynamic, short-lived credentials via OIDC for CI/CD
- Protect Terraform state, remote backend, encryption, tight access controls
- Avoid leaking via outputs or logs, and rotate regularly
The policy only allows reading a specific secret from AWS Secrets Manager and managing a single RDS instance — just enough for our Terraform code to work.
In a real-world setup, you will:
- Replace the ARNs, region, and resource names with values from your own environment
- Further restrict resources, for example, 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.
Module Based Secret Management
Terraform module which creates AWS Secrets Manager resources.
Module example:
module "secrets_manager" {
source = "terraform-aws-modules/secrets-manager/aws"
name_prefix = "example"
description = "Example Secrets Manager secret"
recovery_window_in_days = 30
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 = ["*"]
}
}
create_random_password = true
random_password_length = 64
random_password_override_special = "!@#$%^&*()_+"
tags = {
Environment = "Development"
Project = "Example"
}
}
Another module configuration:
module "secrets_manager" {
source = "terraform-aws-modules/secrets-manager/aws"
name_prefix = "rotated-example"
description = "Rotated example Secrets Manager secret"
recovery_window_in_days = 7
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
}
}
See examples directory for working examples to reference.
Resource Comparison and Configuration Options
The following table summarizes key Terraform resources and their purpose in Secrets Manager workflows.
| Resource | Purpose | Typical Attributes |
| awssecretsmanagersecret | Defines secret metadata and name | name, description, recoverywindowindays, tags |
| awssecretsmanagersecretversion | Stores the secret value | secretid, secretstring |
| randompassword | Generates dynamic credentials | length, special, overridespecial |
| data source | Reads existing secrets | name or ARN |
Access methods for Secrets Manager:
| Approach | Use Case |
| Secrets Manager console | Manual review and rotation |
| Command line tools | CLI automation |
| AWS SDKs | Application integration |
| HTTPS Query API | Direct API calls |
| AWS Secrets Manager endpoints | Service connectivity |
Secret value formats supported by Secrets Manager:
| Format | Description |
| binary | Binary data |
| single string | Single string value |
| multiple strings | Multiple strings |
Operational Guidance and Security Controls
Where are the secrets used in Terraform?
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.
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.
Watch the video below to learn how to manage Terraform secrets securely with secrets managers, short-lived credentials, and encrypted remote state.
Terraform uses secrets to automate infrastructure provisioning activities similar to the ones listed above.
Conclusion
Secrets Manager provides 256-bit AES symmetric encryption for secret values, and Terraform provides state management for infrastructure. The intersection requires explicit safeguards because Terraform state may store sensitive data in plain text by default, especially with local Terraform.tfstate files in JSON format.
The authoritative pattern is to let Terraform create and reference secrets via awssecretsmanagersecret and awssecretsmanagersecretversion, generate values with randompassword, and retrieve existing secrets with data sources. Never embed plaintext secrets in .tf, .tfvars, or modules. Mark variables sensitive = true to reduce log exposure, but remember that state files still contain values.
Protect state with remote backend with encryption at rest, such as S3 + DynamoDB with SSE. Use write-only attributes where available, avoid outputs, and rotate secrets regularly. Use dedicated secrets managers for all sensitive values and codify least-privilege RBAC with policies that only allow needed actions on the smallest possible resource set.
Module based approaches with terraform-aws-modules/secrets-manager/aws provide standardized creation, policy attachment, and random password generation with configurable recovery windows and tags. Combining these practices yields infrastructure as code that creates secrets, references them programmatically, and keeps them out of code and version control.