Skip to content

Commit

Permalink
test: tf
Browse files Browse the repository at this point in the history
  • Loading branch information
jz8132543 committed Sep 8, 2024
1 parent b5359cb commit 23eba3f
Show file tree
Hide file tree
Showing 24 changed files with 653 additions and 67 deletions.
18 changes: 12 additions & 6 deletions .envrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
watch_file \
$(find devshell) \
$(find nixago) \
flake/nixpkgs.nix \
flake/pre-commit.nix
# shellcheck shell=bash

use flake . --impure
files=(
"flake/nixpkgs.nix"
"flake/pre-commit.nix"
"flake/treefmt.nix"
)
mapfile -d '' -t -O "${#files[@]}" files < <(find devshell -type f -print0)
mapfile -d '' -t -O "${#files[@]}" files < <(find nixago -type f -print0)

watch_file "${files[@]}"

use flake
55 changes: 55 additions & 0 deletions devshell.bak/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
inputs,
lib,
...
}: {
imports = [
./terraform.nix
];
perSystem = {inputs', ...}: let
pkgs = import <nixpkgs> {
config.allowUnfree = true;
config.allowUnfreePredicate = pkg:
builtins.elem (lib.getName pkg) [
"terraform"
];
};
in {
devshells.default = {
commands = [
{
category = "secrets";
name = "sops-update-keys";
help = "update keys for all sops file";
command = ''
set -e
${pkgs.fd}/bin/fd '.*\.yaml' $PRJ_ROOT/secrets --exec sops updatekeys --yes
'';
}
];
packages = with pkgs; [
# development
nil
alejandra
# nodePackages.vscode-json-languageserver
vscode-langservers-extracted
terraform-ls
tflint
efm-langserver
shellcheck
shfmt
taplo
pre-commit

# secrets
sops
age
ssh-to-age
age-plugin-yubikey
# infrastructure
nvfetcher
terraform
];
};
};
}
15 changes: 15 additions & 0 deletions devshell.bak/repl.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env nix-shell
#! nix-shell -p "expect" -i expect

#set timeout -1

#cd ~/Projects/flakes

spawn nix repl

send ":lf ..\n"

send ":a builtins\n"

interact

6 changes: 6 additions & 0 deletions devshell.bak/repl.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# USAGE: nix repl ./repl.nix --argstr hostname <hostname>
let
currentHostname = builtins.head (builtins.match "([a-zA-Z0-9]+)\n" (builtins.readFile "/etc/hostname"));
in
{hostname ? currentHostname}:
(builtins.getFlake (toString ./..)).nixosConfigurations.${hostname}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
274 changes: 274 additions & 0 deletions devshell.bak/terraform.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
{pkgs, ...}: let
common = builtins.readFile ./common.sh;

encryptTo = pkgs.writeShellApplication {
name = "encrypt-to";
runtimeInputs = with pkgs; [sops];
text = ''
${common}
plain_file="$1"
target_file="$2"
type="$3"
IFS=" " read -r -a formatter <<<"$4"
message "encryping '$plain_file' to '$target_file' (type: '$type', formatter: '''''${formatter[*]}')..."
if [ -e "$target_file" ]; then
tmp_dir=$(mktemp -t --directory encrypt.XXXXXXXXXX)
target_plain="$tmp_dir/target_plain"
target_plain_formatted="$tmp_dir/target_plain_formatted"
plain_formatted="$tmp_dir/plain_formatted"
function cleanup {
rm -r "$tmp_dir"
}
trap cleanup EXIT
sops --input-type "$type" --output-type "$type" \
--decrypt "$target_file" >"$target_plain"
"''${formatter[@]}" "$target_plain" >"$target_plain_formatted"
"''${formatter[@]}" "$plain_file" >"$plain_formatted"
if diff "$plain_formatted" "$target_plain_formatted" >/dev/null 2>&1; then
message "same, skipping..."
exit 0
fi
fi
EDITOR="cp '$plain_file'" \
sops --input-type "$type" --output-type "$type" "$target_file"
'';
};

terraformInit = pkgs.writeShellApplication {
name = "terraform-init";
runtimeInputs = with pkgs; [terraform];
text = ''
terraform -chdir="$(realpath "$TERRAFORM_DIR")" init "$@"
'';
};

terraformWrapper = pkgs.writeShellApplication {
name = "terraform-wrapper";
runtimeInputs = with pkgs; [
sops
terraform
zerotierone
minio-client
syncthing
libargon2
jq
openssl
ruby
yq-go
efitools
bind
encryptTo
];
text = ''
${common}
encrypted="$SECRETS_DIR/terraform.tfstate"
plain="$TERRAFORM_DIR/terraform.tfstate"
message "decrypt terraform state to '$plain'..."
sops --input-type json --output-type json \
--decrypt "$encrypted" >"$plain"
function cleanup {
exit_code=$?
set -e
if [ -n "$(cat "$plain")" ]; then
encrypt-to "$plain" "$encrypted" json "yq --prettyPrint"
fi
message "deleting terraform state '$plain'..."
rm -f "$plain"* # remove plain and backup files
message "terraform exit code: $exit_code"
exit $exit_code
}
trap cleanup EXIT
set +e
terraform -chdir="$(realpath "$TERRAFORM_DIR")" "$@"
'';
};

terraformUpdateOutputs = pkgs.writeShellApplication {
name = "terraform-update-outputs";
runtimeInputs = with pkgs; [
encryptTo
terraformWrapper
yq-go
];
text = ''
${common}
tmp_dir=$(mktemp -t --directory encrypt.XXXXXXXXXX)
function cleanup {
rm -r "$tmp_dir"
}
trap cleanup EXIT
plain_output="$tmp_dir/terraform-outputs.plain.yaml"
terraform-wrapper output --json >"$plain_output"
encrypt-to "$plain_output" "$SECRETS_DIR/terraform-outputs.yaml" yaml "yq --prettyPrint"
'';
};

terraformOutputsExtractData = pkgs.writeShellApplication {
name = "terraform-outputs-extract-data";
runtimeInputs = with pkgs; [
yq-go
sops
];
text = ''
${common}
format="json"
message "creating 'data.$format'..."
sops exec-file "$SECRETS_DIR/terraform-outputs.yaml" \
"yq eval --from-file \"$DATA_EXTRACT_DIR/template.yq\" {} --output-format $format" \
>"$DATA_EXTRACT_DIR/data.$format"
'';
};

terraformOutputsExtractSecrets = pkgs.writeShellApplication {
name = "terraform-outputs-extract-secrets";
runtimeInputs = with pkgs; [
encryptTo
yq-go
sops
fd
];
text = ''
${common}
mkdir -p "$SECRETS_EXTRACT_DIR/terraform/hosts"
tmp_dir=$(mktemp -t --directory encrypt.XXXXXXXXXX)
function cleanup {
rm -r "$tmp_dir"
}
trap cleanup EXIT
flake="$(realpath "$DOTFILES_DIR")"
mapfile -t hosts < <(nix eval "$flake"#nixosConfigurations --apply 'c: (builtins.concatStringsSep "\n" (builtins.attrNames c))' --raw)
for name in "''${hosts[@]}"; do
message "start extracting secrets for $name..."
template_file="$tmp_dir/$name.yq"
plain_file="$tmp_dir/$name.plain.yaml"
target_file="$SECRETS_EXTRACT_DIR/terraform/hosts/$name.yaml"
message "creating '$(basename "$template_file")'..."
nix eval "$flake"#nixosConfigurations."$name".config.sops.terraformTemplate --raw >"$template_file"
message "creating '$(basename "$plain_file")'..."
sops exec-file "$SECRETS_DIR/terraform-outputs.yaml" \
"yq eval --from-file '$template_file' {}" \
>"$plain_file"
message "creating '$(basename "$target_file")'..."
encrypt-to "$plain_file" "$target_file" yaml "yq --prettyPrint"
done
'';
};
in {
devshells.default = {
env = [
{
name = "DOTFILES_DIR";
eval = "\${DOTFILES_DIR:-$(realpath \"$PRJ_ROOT\")}";
}
{
name = "TERRAFORM_DIR";
eval = "\${TERRAFORM_DIR:-$(realpath \"$DOTFILES_DIR/terraform\")}";
}
{
name = "SECRETS_DIR";
eval = "\${SECRETS_DIR:-$(realpath \"$PRJ_ROOT/../infrastructure-secrets\")}";
}
{
name = "TF_VAR_terraform_input_path";
eval = "\${TF_VAR_terraform_input_path:-$(realpath \"$SECRETS_DIR/terraform-inputs.yaml\")}";
}
{
name = "DATA_EXTRACT_DIR";
eval = "\${DATA_EXTRACT_DIR:-$(realpath \"$DOTFILES_DIR/lib/data\")}";
}
{
name = "SECRETS_EXTRACT_DIR";
eval = "\${SECRETS_EXTRACT_DIR:-$(realpath \"$DOTFILES_DIR/secrets\")}";
}
{
name = "SOPS_AGE_KEY_FILE";
eval = "/var/lib/sops-nix/key";
}
];
commands = [
{
category = "infrastructure";
name = "terraform-pipe";
help = "initialize, apply, and update all terraform related output files";
command = ''
set -e
git -C "$SECRETS_DIR" pull
function cleanup {
git -C "$SECRETS_DIR" add --all
git -C "$SECRETS_DIR" commit --message "Terraform apply"
git -C "$SECRETS_DIR" push
}
trap cleanup EXIT
terraform-init
terraform-wrapper apply "$@"
terraform-update-outputs
terraform-outputs-extract-data
terraform-outputs-extract-secrets
nix fmt
'';
}
{
category = "infrastructure";
package = terraformWrapper;
}

{
category = "infrastructure";
package = terraformUpdateOutputs;
}

{
category = "infrastructure";
package = terraformOutputsExtractSecrets;
}

{
category = "infrastructure";
package = terraformOutputsExtractData;
}

{
category = "infrastructure";
package = terraformInit;
}

{
category = "infrastructure";
package = encryptTo;
}

{
category = "infrastructure";
package = pkgs.cf-terraforming;
}
];
};
}
Loading

0 comments on commit 23eba3f

Please sign in to comment.