Handling Sensitive Data
1. Marking Variables Sensitive
| Variable | Sensitivity | Description |
|---|---|---|
| sensitive | true |
Indicates that the variable's value should be treated as sensitive and not displayed in logs or output |
Note: Setting
sensitive = true prevents the variable's value from being logged or shown in plan output, but does not encrypt or store the value securely. It is still visible to anyone with access to the state file.
2. Marking Outputs Sensitive
| Property | Description | Example |
|---|---|---|
| sensitive | Flag to mark output values as sensitive, preventing them from being displayed in logs or CLI output | sensitive = true |
Example: Marking an Output as Sensitive
output "api_key" {
value = aws_iam_access_key.main.secret
sensitive = true
}
Note: Even when marked as sensitive, output values are still stored in the Terraform state file. Ensure proper access controls and encryption for the state file to maintain security.
3. Using Environment Variables
| Variable Type | Description | Usage Example |
|---|---|---|
| TF_VAR_ | Environment variables prefixed with TF_VAR_ are automatically recognized by Terraform as variable values. |
export TF_VAR_instance_type="t3.micro" |
| Terraform Variables | Variables defined in variables.tf can be overridden via environment variables. |
variable "instance_type" { type = string} |
Example: Setting Environment Variables
export TF_VAR_aws_region="us-west-2"
export TF_VAR_instance_count=5
Note: Environment variables are useful for passing sensitive values like API keys or region settings without storing them in version-controlled files.
4. Storing Secrets in Vault
| Property | Description | Example |
|---|---|---|
| vault.address | Address of the Vault server | "https://vault.example.com" |
| vault.token | Authentication token for Vault | "s.xxxxxxxxxx" |
| vault.mount | Mount point for secrets engine | "secret" |
| vault.path | Path to secret within the mount | "myapp/credentials" |
Example: Using Vault with Terraform
data "vault_generic_secret" "app_creds" {
path = "secret/myapp/credentials"
}
resource "aws_ssm_parameter" "db_password" {
name = "/myapp/db/password"
value = data.vault_generic_secret.app_creds.data["password"]
type = "SecureString"
}
Note: Ensure the Vault token has appropriate permissions to read secrets.
5. Using Cloud Secret Managers
| Provider | Secret Manager | Integration Method | Notes |
|---|---|---|---|
| AWS | AWS Systems Manager Parameter Store |
Using aws_ssm_parameter data source |
Supports secure parameter storage with encryption |
| GCP | Google Secret Manager |
Using google_secret_manager_secret_version data source |
Provides versioned secrets with IAM-based access control |
| Azure | Azure Key Vault |
Using azurerm_key_vault_secret data source |
Enables secure storage and retrieval of secrets with RBAC |
Example: Retrieving Secret from AWS SSM Parameter Store
data "aws_ssm_parameter" "my_secret" {
name = "/prod/myapp/secret_key"
}
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
user_data = <<EOF
export SECRET_KEY="${data.aws_ssm_parameter.my_secret.value}"
EOF
}
Example: Using GCP Secret Manager
data "google_secret_manager_secret_version" "my_secret" {
secret = "my-secret"
}
resource "google_compute_instance" "web" {
name = "web-instance"
machine_type = "e2-medium"
metadata = {
startup-script = <<EOF
export SECRET_KEY="${data.google_secret_manager_secret_version.my_secret.secret_data}"
EOF
}
}
Note: Ensure IAM roles or service accounts have appropriate permissions to access secret managers.
Warning: Never store secrets in plain text within Terraform configuration files.
6. Encrypting State Files
| Option | Values | Notes |
|---|---|---|
| backend | "s3" |
State file storage backend |
| encrypt | true |
Enable encryption at rest |
| kms_key_id | "arn:aws:kms:us-east-1:123456789012:key/abcd1234-a1b2-c3d4-e5f6-7890ghij1234" |
KMS key ARN for encryption |
Example: S3 Backend with Encryption
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/abcd1234-a1b2-c3d4-e5f6-7890ghij1234"
}
}
Note: Ensure the IAM role or user has permissions to use the KMS key for encryption.
7. Redacting Sensitive Values
| Property | Description | Usage |
|---|---|---|
| sensitive | Flag to mark a value as sensitive, preventing it from being logged or displayed in plain text | sensitive = true |
Example: Using sensitive flag
resource "aws_ssm_parameter" "my_secret" {
name = "my-secret"
type = "SecureString"
value = "secret-value"
sensitive = true
}
Note: The
sensitive attribute prevents the value from appearing in logs or output, but does not encrypt the value in state files. Ensure proper access controls and encryption at rest for sensitive data.
8. Using .gitignore for Secrets
| File Pattern | Description | Usage |
|---|---|---|
| .gitignore | File to specify intentionally untracked files to ignore | Prevents sensitive files from being committed to version control |
| secrets.tfvars | Variable file containing sensitive values | Used with terraform apply -var-file=secrets.tfvars |
| *.key | Wildcard pattern for private keys | Prevents accidental commit of private keys |
Note: .gitignore only prevents tracking of uncommitted files. It does not remove already committed files from history.
9. Rotating Credentials
| Method | Description | Notes |
|---|---|---|
| aws_iam_access_key | Manage IAM access keys for AWS users | Use rotate attribute to rotate keys |
| google_service_account_key | Manage service account keys for GCP | Keys are rotated by generating new ones and deleting old |
| azurerm_key_vault_secret | Manage secrets in Azure Key Vault | Use rotation_policy to automate rotation |
Example: Rotating AWS IAM Access Key
resource "aws_iam_access_key" "example" {
user = aws_iam_user.example.name
rotate = true
}
Note: Ensure that the new key is properly configured in your application before deleting the old one to avoid service interruption.
Warning: Manual rotation of credentials is not recommended in production environments due to the risk of downtime or security breaches.
10. Auditing Secret Access
| Aspect | Description | Notes |
|---|---|---|
| audit_logging | true |
Enables logging of secret access events |
| log_retention_days | 90 |
Number of days to retain audit logs |
| log_destination | cloudwatch |
Destination for audit logs (e.g., CloudWatch, S3) |
Example: Enable Secret Access Auditing
resource "aws_iam_user" "user_with_audit" {
name = "audited-user"
}
resource "aws_iam_user_policy" "audit_policy" {
name = "audit-secret-access"
user = aws_iam_user.user_with_audit.name
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "*"
}
]
}
EOF
}
Note: Ensure that the IAM policy includes
secretsmanager:GetSecretValue to allow access and audit logging.
Warning: Audit logs should be stored securely and rotated regularly to prevent unauthorized access.