DEV Community

Hamdi KHELIL
Hamdi KHELIL

Posted on

πŸ” Secure Secret Management with SOPS in Terraform & Terragrunt

When managing infrastructure as code (IaC), keeping secrets safe while still making them accessible to Terraform/Terragrunt is a challenge. Storing secrets in plaintext is a security risk πŸš¨β€”and that’s where SOPS (Secrets OPerationS) comes in!

In this guide, we’ll cover:

  • βœ… How to use SOPS with age and GPG
  • βœ… How to configure SOPS with sops.yaml for better management
  • βœ… How to use Terragrunt’s built-in SOPS decryption (without run_cmd)
  • βœ… A GitHub Actions workflow to securely use secrets in CI/CD

πŸ“Œ Why Use SOPS?

SOPS is an open-source tool from Mozilla that lets you encrypt and decrypt secrets easily. It supports multiple encryption methods, including GPG, AWS KMS, Azure Key Vault, Google Cloud KMS, and age.

Here’s why it’s awesome:

  • βœ… Keeps secrets encrypted in Git repositories
  • βœ… Works with YAML, JSON, ENV files
  • βœ… Has built-in support in Terragrunt (no extra scripting needed!)
  • βœ… Integrates with GitHub Actions, Kubernetes, and CI/CD pipelines

Now, let’s see how to use SOPS with age and GPG, then configure it properly for Terragrunt and GitHub Actions.

πŸ”‘ Using SOPS with age

Age is a modern, simple, and secure encryption tool. If you’re new to encryption, age is a great alternative to GPG.

✨ Step 1: Install age and sops

First, install age and sops:

sudo apt install age # Ubuntu/Debian 
Enter fullscreen mode Exit fullscreen mode

✨ Step 2: Generate an age Key

Run:

age-keygen -o ~/.config/sops/age/keys.txt 
Enter fullscreen mode Exit fullscreen mode

This will generate a key similar to:

# public key: age1xxxxxxx AGE-SECRET-KEY-1XXXXXXYYYYYYYYZZZZZZ 
Enter fullscreen mode Exit fullscreen mode

Copy the public key (age1xxxxxxx)β€”this will be used for encryption.

✨ Step 3: Encrypt a YAML File with SOPS

Create a file called secrets.yaml:

db_user: "admin" db_password: "supersecret" 
Enter fullscreen mode Exit fullscreen mode

Now, encrypt it using SOPS:

sops --encrypt --age age1xxxxxxx -i secrets.yaml 
Enter fullscreen mode Exit fullscreen mode

If you open secrets.yaml, you'll see it's fully encrypted! πŸ›‘οΈ

To decrypt:

sops --decrypt secrets.yaml 
Enter fullscreen mode Exit fullscreen mode

πŸ”§ Configuring sops.yaml for Better Management

Instead of specifying the encryption method manually every time, SOPS supports a configuration file (.sops.yaml). This makes it easier to manage secrets across teams.

Create .sops.yaml in your repository:

creation_rules: - path_regex: secrets/.*\.yaml$ age: - age1xxxxxxx # Replace with your public key - path_regex: secrets/.*\.json$ pgp: - ABC12345 # Replace with your GPG key ID 
Enter fullscreen mode Exit fullscreen mode

Now, when encrypting secrets inside the secrets/ folder, SOPS will automatically use the right encryption method! πŸŽ‰

Encrypt a new secret:

sops --encrypt -i secrets/app.yaml 
Enter fullscreen mode Exit fullscreen mode

βš™οΈ Using SOPS with Terragrunt’s Built-in Decryption

Terragrunt has native support for SOPS, meaning you don’t need to use run_cmd(). Instead, you can directly reference encrypted files in your terragrunt.hcl.

✨ Step 1: Encrypt the Secrets

Create secrets.yaml:

aws_access_key: "AKIAxxxxxxxxxxxx" aws_secret_key: "abcdefghijklmno1234567890" 
Enter fullscreen mode Exit fullscreen mode

Encrypt it:

sops --encrypt -i secrets.yaml 
Enter fullscreen mode Exit fullscreen mode

✨ Step 2: Use Terragrunt's Built-in SOPS Decryption

Modify terragrunt.hcl:

locals { secrets = yamldecode(sops_decrypt_file("secrets.yaml")) } inputs = { aws_access_key = local.secrets.aws_access_key aws_secret_key = local.secrets.aws_secret_key } 
Enter fullscreen mode Exit fullscreen mode

Now, when you run:

terragrunt apply 
Enter fullscreen mode Exit fullscreen mode

Terragrunt automatically decrypts secrets.yaml without requiring external scripts! πŸš€

πŸ€– Using SOPS in GitHub Actions

When using GitHub Actions, we need to decrypt secrets safely without exposing them.

✨ Step 1: Store the age Private Key in GitHub Secrets

Go to GitHub β†’ Your Repo β†’ Settings β†’ Secrets and variables β†’ Actions, and add:

  • SOPS_AGE_KEY: The private key from ~/.config/sops/age/keys.txt

✨ Step 2: Use SOPS in a GitHub Workflow

Create .github/workflows/deploy.yml:

name: Deploy with Terraform & SOPS on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y sops age - name: Set up SOPS run: | mkdir -p ~/.config/sops/age/ echo "${{ secrets.SOPS_AGE_KEY }}" > ~/.config/sops/age/keys.txt chmod 600 ~/.config/sops/age/keys.txt - name: Decrypt Secrets run: sops --decrypt secrets.yaml > secrets.decrypted.yaml - name: Deploy with Terraform run: | terragrunt run-all apply --auto-approve 
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ What Happens in This Workflow?

  1. Checks out the code βœ…
  2. Installs SOPS & age βœ…
  3. Loads the age private key from GitHub Secrets βœ…
  4. Decrypts secrets into a temporary file βœ…
  5. Runs Terraform/Terragrunt with the decrypted secrets βœ…

Security Tip:
Make sure secrets.decrypted.yaml is ignored in .gitignore and is never committed to Git!

🎯 Wrapping Up

SOPS is a powerful and secure way to manage secrets for Terraform, Terragrunt, and GitHub Actions. With age encryption, .sops.yaml for better configuration, and Terragrunt's built-in decryption, managing secrets has never been easier! πŸ’ͺ

By integrating SOPS into your workflow, you get:

  • βœ… Encrypted secrets in Git repositories
  • βœ… Easy decryption in Terraform/Terragrunt
  • βœ… Safe usage of secrets in CI/CD

Want to take it a step further? Try using AWS KMS, GCP KMS, or Azure Key Vault instead of age/GPG for even tighter security! πŸ”πŸš€

Have questions or suggestions? Drop them in the comments! πŸ’¬

Happy clustering and stay safe ! πŸ”

Top comments (0)