Terraform secrets with SOPS and Azure Keyvault
Posted in development on October 24, 2023 by Adrian Wyssmann ‐ 3 min read
We are heavily using Terraform and and also Azure. However until now, we left out certain things cause they contain secrets which we don't want to expose in the code. SOPS is a nice solution to solve that problem and keep things together what belongs together.
What is SOPS?
SOPS stands for Secrets OPerationS, and is an open-source text file editor that encrypts/decrypts YAML, JSON, ENV, INI and BINARY formats and encrypts with AWS KMS, GCP KMS, Azure Key Vault, age, and PGP.
If you want more details to SOPS as such you can also have a look at A Comprehensive Guide to SOPS: Managing Your Secrets Like A Visionary, Not a Functionary (gitguardian.com).
What do you need?
As we will use azure-key-vault: you will need
access to the respective key-vault
sops binary
Encrypting/decrypting with Azure Key Vault requires the resource identifier for a key. This has the following form:
Sops only encrypts the secrets, so the advantage is you can have key-value pairs in a yaml or json file, and while the key is readable, the value part is encrypted. This also allows to address particular keys - we will see this later.
Setup
We setup a keyvault (Key Vault names are globally unique) - you can do this using azure cli (as per example) or prefferable using terraform
We create a key - you can do this using azure cli (as per example) or prefferable using terraform
Encryption and Decryption
Once we have the key created and configured, then we can use it for encryption. I usually grab it as follows
Now you can encrypt a file using:
And decrypt it using:
As mentioned in the beginning, sops only encrypts the values not the keys, so assuming the content of test.json
looks as follows:
Encryption will result in something like
Usage in Terraform
We need carlpett/sops-provider. As part of your terraform code, you have to define the encrypted file from above
As they keys can be accessed you can e.g. use the secret from key1
as follows
You can also encrypt whole files, e.g. private keys (not .yaml or .json)
These have then to be declared using input_type=raw
…
… accessed using .raw
Conclusion
Using SOPS with an external keyvault, really simplifes managing secret data together with your terraform code, without exposing them. So you can still make your code visible to the rest of your team(s)/company without compromising on leaking secrets.