Managing infrastructure as code with Terraform requires handling credentials, API keys, passwords, and other confidential values without exposing them in configuration files, version control, or state files. AWS Secrets Manager provides a managed service for securely encrypting, storing, and rotating credentials for databases and other services. When combined with Terraform, the workflow allows infrastructure code to create secrets and reference them without hardcoding actual values in configuration files.
Terraform stores information about managed AWS infrastructure and its configurations in 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. Because Secret values managed with Terraform can still be stored in Terraform state, protect your state backend carefully or use write-only attributes where available.
Secrets Manager Fundamentals
AWS Secrets Manager is a 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
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
Creating Secrets With Terraform
Creating a secret and storing a value is the simplest case.
```hcl
resource "awssecretsmanagersecret" "database" {
name = "production/database/credentials"
description = "Database credentials for the production environment"
recoverywindowin_days = 30
tags = {
Environment = "production"
ManagedBy = "terraform"
}
}
resource "awssecretsmanagersecretversion" "database" {
secretid = awssecretsmanagersecret.database.id
secretstring = jsonencode({
username = "admin"
password = randompassword.database.result
engine = "postgres"
host = awsdbinstance.main.address
port = 5432
dbname = "myapp"
})
}
resource "randompassword" "database" {
length = 32
special = true
overridespecial = "!#$%&*()-_=+[]{}<>:?"
}
```
The resource awssecretsmanagersecret defines the secret name in AWS Secrets Manager. The resource awssecretsmanagersecretversion stores the secret value. The randompassword resource generates a random password dynamically.
It is common to generate and store secrets securely using AWS Secrets Manager in a Terraform project. 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
- awssecretsmanagersecret_version stores the secret value
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 and Referencing Secrets
Read existing secrets using data sources. 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.
Terraform can fetch and manage secrets stored in external secret management services such as Hashicorp vault, AWS secrets manager, Azure key vault etc.
The best way to manage Terraform secrets is to use a dedicated secrets manager and run workflows through an orchestration layer. 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.
- Use a real secrets manager for all sensitive values
- Never commit secrets to Git
- Never commit secrets to .tfvars
- Never commit secrets to CI variables in plain text
Variable Sensitivity and State Protection
Terraform offers many different methods for managing secrets, such as using environment variables, leveraging secret management tools like HashiCorp Vault and AWS Secrets Manager, or encrypting sensitive data.
You 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 secure the state file properly with remote backend like S3 + DynamoDB with encryption at rest.
Terraform was never meant to be your secrets store.
Module Features and Compatibility
Terraform modules provide comprehensive input validation and advanced features for Secrets Manager.
- 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
AWS Secrets Manager helps protect secrets needed to access applications, services, and IT resources. The service enables you to easily rotate, manage, and retrieve database credentials, API keys, and other secrets throughout their lifecycle.
Component compatibility requirements:
| 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 |
The module declares the AWS provider minimum at the root, so all usage modes use the same compatibility policy.
Policy and Example Usage
Example module configuration with policy and random password generation:
```hcl
module "secrets_manager" {
source = "terraform-aws-modules/secrets-manager/aws"
nameprefix = "example"
description = "Example Secrets Manager secret"
recoverywindowindays = 30
createpolicy = true
blockpublicpolicy = true
policystatements = {
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:
```hcl
module "secrets_manager" {
source = "terraform-aws-modules/secrets-manager/aws"
nameprefix = "rotated-example"
description = "Rotated example Secrets Manager secret"
recoverywindowindays = 7
createpolicy = true
blockpublicpolicy = true
policystatements = {
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 = [""]
}
}
}
```
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.
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 for Managing Terraform Secrets
Best practices for managing Terraform secrets include using a real secrets manager for all sensitive values and never committing secrets to Git, .tfvars, or CI variables in plain text.
- Use a real secrets manager for all sensitive values
- Never commit secrets to Git
- Never commit secrets to .tfvars
- Never commit secrets to CI variables in plain text
Terraform uses secrets to automate infrastructure provisioning activities similar to the ones listed above. Watch the video below to learn how to manage Terraform secrets securely with secrets managers, short-lived credentials, and encrypted remote state.
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.
Conclusion
Integrating AWS Secrets Manager with Terraform provides a clean workflow where infrastructure code can both create secrets and reference them without hardcoding actual values in configuration files. Secrets Manager encrypts secret values with 256-bit AES symmetric data keys and supports binary, single string, or multiple string values with full metadata management. Terraform resource models allow creation of secrets, generation of random passwords, storage of secret versions with JSON encoded values, and attachment of IAM resource policies with least-privilege principals.
State protection remains critical because Terraform state may contain sensitive data in plain text. Using sensitive variables, remote encrypted backends, and write-only secret attributes reduces exposure. Modules add input validation, type safety, automatic rotation support, cross-region replication, customer-managed KMS encryption, and flexible secret types while requiring Terraform >= 1.11.0 and AWS provider >= 6.50.0 for consistent final-plan behavior.
The operational pattern is clear: generate secrets dynamically, store them in Secrets Manager, reference them via data sources or secure retrieval, and never commit secrets to version control. Codifying least-privilege policies in Terraform and reviewing them as infrastructure evolves completes the secure lifecycle.