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
β¨ Step 2: Generate an age
Key
Run:
age-keygen -o ~/.config/sops/age/keys.txt
This will generate a key similar to:
# public key: age1xxxxxxx
AGE-SECRET-KEY-1XXXXXXYYYYYYYYZZZZZZ
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"
Now, encrypt it using SOPS:
sops --encrypt --age age1xxxxxxx -i secrets.yaml
If you open secrets.yaml
, you'll see it's fully encrypted! π‘οΈ
To decrypt:
sops --decrypt secrets.yaml
π§ 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
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
βοΈ 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"
Encrypt it:
sops --encrypt -i secrets.yaml
β¨ 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
}
Now, when you run:
terragrunt apply
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
π₯ What Happens in This Workflow?
- Checks out the code β
- Installs SOPS & age β
- Loads the age private key from GitHub Secrets β
- Decrypts secrets into a temporary file β
- 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)