Skip to main content

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

Example: Declaring a sensitive variable

variable "api_key" {
  type = string
  sensitive = true
}
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

Example: .gitignore content

# Ignore sensitive files
secrets.tfvars
*.key
.env
terraform.tfstate
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.

Secret Access Auditing Best Practices

  • Enable audit logging for all secret access operations
  • Store logs in a secure, centralized location (e.g., CloudWatch or S3)
  • Set up log retention policies to comply with compliance requirements
  • Monitor logs for unauthorized or suspicious access patterns

Was this article helpful?