allow sharing secrets using sops + age/rage

This commit is contained in:
Kiara Grouwstra 2024-01-16 18:02:43 +01:00
parent 0badb72e8f
commit e1b127678a
7 changed files with 99 additions and 10 deletions

6
.gitignore vendored
View File

@ -1,3 +1,9 @@
# sops
/secrets.yaml
# age
/keys.txt
# Direnv directory
.direnv/

10
.sops.yaml Normal file
View File

@ -0,0 +1,10 @@
# let's make anchors so we can use names to refer to the keys
keys:
- &automation age1d53yeje0ggysc93uptlpufyhpchyyfs006368j8mw9r20uyeeydse3n7aw
# actual sops config
creation_rules:
- path_regex: secrets(\.enc)?\.yaml$
key_groups:
- age:
- *automation

View File

@ -1,6 +1,20 @@
# This file is maintained automatically by "tofu init".
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/carlpett/sops" {
version = "1.0.0"
hashes = [
"h1:tnN2Mgl0NUF3cg7a0HtGmtOhHcG+tkaT6ncOPRuA9l8=",
"zh:064e63ea800cd1a8e575064097bc7de6fd5faa8ad50dbb3f2f9d8a3ebc9d7b97",
"zh:0663900085949d2faf24c170c7cdfbf76e545797915cc331da8304144c02bf27",
"zh:2ff26c7e5ee356c30791a12dd8e114c6237bd873d09e52805cb30dd5d758ed23",
"zh:44211fa474112ad0c9fcdae03f13ec7c75cdefd3ab29979b99cb834208055593",
"zh:6c3ab441c12b9679ad1dcac580d1ee7782f0d94efe6da6e983435ed39335cd3f",
"zh:8924cc939b52382ef042dc38bde93cdf438ff0aeab5e1801fbd198f05b80cd47",
"zh:ebc189ce22c23b903399f71e33d465001a79d7de7f7bf115c7763fcf794f4b58",
]
}
provider "registry.opentofu.org/hashicorp/local" {
version = "2.4.1"
hashes = [

View File

@ -15,6 +15,15 @@ Contains [Terraform](https://terraform.io/) code used to manage our infrastructu
- Run `nix run` to apply changes.
- Run `nix flake update` to update dependencies.
### Secrets
- if you want to reset secrets:
- generate an [`age`](https://age-encryption.org/) key pair, using [`rage`](https://github.com/str4d/rage) installed as part of the nix shell: `rage-keygen -o keys.txt`
- list it in [`sops`](https://getsops.io/) config file `.sops.yaml`
- key setup: set environment variable `SOPS_AGE_KEY_FILE` or `SOPS_AGE_KEY` so `sops` can locate the secret key to an `age` key pair that has its public key listed in `.sops.yaml`
- encoding secrets: `sops -e secrets.yaml > secrets.enc.yaml`
- decoding secrets: `sops -d secrets.enc.yaml > secrets.yaml`
### Authentication
Create a file `terraform.tfvars` containing:

View File

@ -1,21 +1,49 @@
{ config, lib, pkgs, options, specialArgs, ... }:
{ config, lib, inputs, pkgs, options, specialArgs, ... }:
let
var = options.variable;
my-lib = import ./lib/default.nix { inherit lib; };
# (k: k + k) -> { a = 1; } -> { aa = 1; }
mapKeys = f: lib.mapAttrs' (k: v: lib.nameValuePair (f k) v);
# (v: 2 * v) -> { a = 1; } -> { a = 2; }
mapVals = f: lib.mapAttrs (_: f);
# { b = 0; } -> { c = { a = 1; } } -> { c = { b = 0; a = 1; } }
default = defaults: mapVals (v: defaults // v);
# "b" -> { a = 1; } -> { b_a = 1; }
inNamespace = prefix: mapKeys (k: "${prefix}_${k}");
setNames = lib.mapAttrs (k: v: v // { name = k; });
# { a = 1; } -> { name = "a"; a = 1; }
setNames = lib.mapAttrs (k: v: { name = k; } // v);
# "foo" -> "\${data.sops_file.secrets.data[\"foo\"]}"
secret = str: lib.tfRef "data.sops_file.secrets.data[\"${str}\"]";
hetzner = let
# https://docs.hetzner.com/cloud/api/getting-started/generating-api-token
token = secret "hcloud_api_token";
in { inherit token; };
in rec {
terraform.required_providers = {
sops.source = "carlpett/sops";
};
provider = {
sops = {};
# Configure the Hetzner Cloud Provider
hcloud.token = lib.mkForce (lib.tfRef "var.hcloud_api_token");
hcloud.token = lib.mkForce hetzner.token;
};
@ -30,25 +58,23 @@ in rec {
# or using -var="hcloud_api_token=..." CLI option
variable = {
hcloud_api_token = {
type = "string";
description = "Hetzner Cloud API Token";
sensitive = true;
};
};
# https://github.com/terranix/terranix-hcloud/blob/main/options.md
hcloud = {
enable = true;
# can also be specified with the TF_VAR_hcloud_api_token environment variable
provider.token = builtins.getEnv "TF_VAR_hcloud_api_token";
provider = { inherit (hetzner) token; };
export.nix = "hetzner.nix";
};
data = {
sops_file.secrets = {
source_file = "secrets.enc.yaml";
};
hcloud_ssh_keys."all_keys" = {};
};

View File

@ -44,8 +44,11 @@
devShell = pkgs.mkShell {
buildInputs = with pkgs; [
treefmt
sops
rage
inputs.terranix.defaultPackage.${system}
(opentofu.withPlugins (p: with p; [
sops # https://registry.terraform.io/providers/carlpett/sops/latest/docs
hcloud # https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs
]))
];

21
secrets.enc.yaml Normal file
View File

@ -0,0 +1,21 @@
hcloud_api_token: ENC[AES256_GCM,data:vXsyffsjp5yiMWepyq8KNR8fJNbMB1sj1wAvc7eJm5smysww+Jm8sNCso8dn0X3M4eMCUx9SZUJx3qVh6Mr6Kw==,iv:RQK3mvKPtUmFSZjvlkh9Iffv8vYeEV+G95JcCp88W1o=,tag:CSsVCl35muqlTq5VYvsZIQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1d53yeje0ggysc93uptlpufyhpchyyfs006368j8mw9r20uyeeydse3n7aw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzdytpNTZ3M3JpWlBKR1Nr
S0xXK2krNDVvRk5vYzl1dEhUYkdtZDN4S3pnCkFFanIraGZlelJTVGpwOXBKM1dO
Q0lXcnZPU0dtUDNUV2NIMHhDL3pPUmMKLS0tIDlpV25BRnlXMm1pNk81bDFySk5B
M1Q2Q2V4RUxxVGpIRVc4aHZCUzVHaXcKePAXhBPzLQnfzhklXqY2uM9vBQqh4ZAS
EglXonol4QVUJNBj6hMwepUeeeyLw5foWxJbBwzfdyPWdeSM+zkctw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-01-16T16:09:37Z"
mac: ENC[AES256_GCM,data:H1IXPgNzGwnbz27kc/M9kfsWLFWX7pWLfpPU3F6LDz3c76Ap8kgjlwc52r2thOfQhky14iaZgP+9EqAL7wP7WK3ZcN18mq9PHePsqAIQBkb8+80YFcEBel8yUPJFUFpeJGq4Ty+JBbADY9hbJKteLvkoOA0BaeIckMkAQXNB7nU=,iv:+XgndQValWgwSL+16Zr/q7aeQpxWvmNQ2ECD7298MX8=,tag:txLiO/MilTx9H6GoSCHxZg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1