Terraform: Store and retrieve secrets the right way (4 approaches)

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Managing secrets securely is an essential aspect of infrastructure as code, especially when working with Terraform. This tutorial aims to guide you through the best practices of storing and retrieving secrets when working with Terraform. We will cover several methods, starting from basic to more advanced strategies, helping you safeguard your sensitive data efficiently.

Understanding Terraform and Secrets Management

Before we dive into secrets management, let’s understand what Terraform is and why managing secrets is crucial. Terraform is an open-source tool created by HashiCorp, used for building, changing, and versioning infrastructure safely and efficiently. Secrets management refers to the tools and methods for managing digital authentication credentials (like passwords, keys, and tokens), ensuring they are stored and accessed securely.

Method 1: Environment Variables

One of the simplest ways to manage secrets in Terraform is through environment variables. Terraform automatically reads environment variables prefixed with TF_VAR_ as input variables.

export TF_VAR_my_secret="s3cr3tValue"
terraform plan

This method makes it easy to pass secrets without hardcoding them into your configuration files. However, it relies on the security of the environment where Terraform is executed and is not suitable for all scenarios, especially with sensitive data.

Method 2: Terraform Cloud & Enterprise

Terraform Cloud and Enterprise offer a more secure way to manage secrets through their Variables feature. You can store secrets as environment variables within the workspace, which Terraform can then access during runs.

# Configuring a sensitive environment variable in Terraform Cloud
1. Navigate to your workspace.
2. Go to "Variables".
3. Click "Add variable".
4. Check "Sensitive" to ensure the variable's value is hidden in logs.

This approach centralizes secret management and adds an additional layer of security by hiding the value in logs and UI.

Method 3: Using Vault for Secrets Management

Vault by HashiCorp is a tool designed for securing, storing, and tightly controlling access to tokens, passwords, certificates, API keys, and other secrets. Integrating Vault with Terraform allows you to manage secrets dynamically and securely.

# Example: Retrieving a secret from Vault
provider "vault" {}

data "vault_generic_secret" "example" {
  path = "secret/my-app"
}

output "my_secret" {
  value = data.vault_generic_secret.example.data["my_secret"]
}

This code snippet demonstrates how to retrieve a secret from Vault using Terraform. Here, Vault acts as the central store for all secrets, which Terraform accesses securely during runtime.

Method 4: Using AWS Secrets Manager

For projects deployed on AWS, using AWS Secrets Manager can be a robust solution for managing secrets. This service enables you to easily rotate, manage, and retrieve secrets throughout their lifecycle.

# Example: Retrieving a secret from AWS Secrets Manager using Terraform
provider "aws" {}

data "aws_secretsmanager_secret_version" "example" {
  secret_id = "my-secret"
}

output "my_secret" {
  value = data.aws_secretsmanager_secret_version.example.secret_string
}

In this example, the AWS Secrets Manager securely stores the secret, and Terraform retrieves it dynamically, ensuring that the secret does not get exposed or hard-coded in your configurations.

Advanced: Using SOPS with Terraform

For organizations looking for an advanced secrets management solution, SOPS (Secrets OPerationS) can encrypt secrets for storage in VCS. SOPS can use various key management systems like KMS, GCP KMS, Azure Key Vault, or PGP. Integrating SOPS with Terraform allows you to store your Terraform configurations and secrets together securely.

# Encrypt files using SOPS with AWS KMS
sops --encrypt --kms <KMS ARN> secrets.unencrypted.yaml > secrets.yaml

# Decrypting with Terraform
data "external" "sops_decrypted" {
  program = ["sops", "--decrypt", "secrets.yaml"]
}

output "secret" {
  value = yamldecode(data.external.sops_decrypted.result)["my_secret"]
}

This method adds an encryption layer to the secrets, ensuring that they’re only accessible to authorized individuals and systems. It’s an excellent way to leverage infrastructure as code while maintaining security best practices.

Conclusion

In this tutorial, we’ve explored several methods for securely managing secrets in Terraform. From environmental variables to sophisticated tools like Vault and SOPS, each approach offers different levels of security and complexity. Choosing the right method depends on your project’s needs and the infrastructure environment. With the right tools and practices, you can efficiently safeguard sensitive data and maintain a high standard of security in your Terraform projects.