feat(infra): introduce Terranix
This requires the support for monorepo-terraform-state.s3.dgnum.eu being available. `.credentials/` is age-encrypted using only my key for now until we figure out the right mechanism. Signed-off-by: Ryan Lahfa <ryan@dgnum.eu>
This commit is contained in:
parent
e382980f25
commit
c6cc2baa8f
7 changed files with 93 additions and 0 deletions
5
.credentials/admin-environment.age
Normal file
5
.credentials/admin-environment.age
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 +qVung Rzqud7wBklrZ+T/50qx2Ly8d7OVb1za+pShg/4Wu3Hw
|
||||||
|
CtSs7bGmE8gpt6pxm5FlP8Btr0hwx9F4UUB40bxSg24
|
||||||
|
--- Ur0gMkDzmnrlX8rwx0b2uPA11KYnD28WhC3E2sQYUic
|
||||||
|
®T£û£Ý¥ñlF›ÚìIRušˆâŠëP8±wZ9<5A>ŠZ¿<>ù·ÿçúc^ (ÊßX°»Â& ¹#P<>“áb_‰0†³[ÚHæŽI Ì´·áÞrcñS¬?0îx¾üÁqgqÞ,”ÙÂá1Fîj,V¹J#ܾe8!5[PüÐBÕFâ'Ðx«È‰!›¤x¹)ë9Nöy„
;×iØ9)pП~‡+”DÄ¡Pòõ~
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -9,3 +9,6 @@ result-*
|
||||||
*.qcow2
|
*.qcow2
|
||||||
.gcroots
|
.gcroots
|
||||||
.pre-commit-config.yaml
|
.pre-commit-config.yaml
|
||||||
|
|
||||||
|
# Ignore Terraform configuration file
|
||||||
|
config.tf.json
|
||||||
|
|
36
default.nix
36
default.nix
|
@ -67,9 +67,18 @@ let
|
||||||
commitizen.enable = true;
|
commitizen.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
terranixConfig = import "${sources.terranix}/core" {
|
||||||
|
inherit pkgs;
|
||||||
|
strip_nulls = true;
|
||||||
|
terranix_config.imports = [ ./terranix ];
|
||||||
|
};
|
||||||
|
terranixConfigFile = (pkgs.formats.json { }).generate "config.tf.json" terranixConfig.config;
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
inherit terranixConfigFile terranixConfig;
|
||||||
|
|
||||||
nodes = builtins.mapAttrs (
|
nodes = builtins.mapAttrs (
|
||||||
host: { site, ... }: "${host}.${site}.infra.dgnum.eu"
|
host: { site, ... }: "${host}.${site}.infra.dgnum.eu"
|
||||||
) (import ./meta/nodes.nix);
|
) (import ./meta/nodes.nix);
|
||||||
|
@ -83,11 +92,36 @@ in
|
||||||
name = "dgnum-infra";
|
name = "dgnum-infra";
|
||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
|
(pkgs.writeShellScriptBin "tf" ''
|
||||||
|
set -eo pipefail
|
||||||
|
ln -snf ${terranixConfigFile} config.tf.json
|
||||||
|
exec ${pkgs.lib.getExe pkgs.opentofu} "$@"
|
||||||
|
'')
|
||||||
|
(pkgs.writeShellScriptBin "decryptAndSourceEnvironment" ''
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
# TODO: don't hardcode me.
|
||||||
|
SECRET_FILE=".credentials/admin-environment.age"
|
||||||
|
IDENTITIES=()
|
||||||
|
for identity in [ "$HOME/.ssh/id_ed25519" "$HOME/.ssh/id_rsa" ]; do
|
||||||
|
test -r "$identity" || continue
|
||||||
|
IDENTITIES+=(-i)
|
||||||
|
IDENTITIES+=("$identity")
|
||||||
|
done
|
||||||
|
|
||||||
|
test "''${#IDENTITIES[@]}" -eq 0 && echo "[agenix-shell] WARNING: no readable identities found!"
|
||||||
|
|
||||||
|
test -f "$SECRET_FILE" || echo "[agenix-shell] WARNING: encrypted environment file $SECRET_FILE not found!"
|
||||||
|
export eval $(${pkgs.lib.getExe pkgs.rage} --decrypt "''${IDENTITIES[@]}" -o - $SECRET_FILE)
|
||||||
|
|
||||||
|
echo "[agenix-shell] Repository-wide secrets loaded in the environment."
|
||||||
|
'')
|
||||||
(pkgs.nixos-generators.overrideAttrs (_: {
|
(pkgs.nixos-generators.overrideAttrs (_: {
|
||||||
version = "1.8.0-unstable";
|
version = "1.8.0-unstable";
|
||||||
src = builtins.storePath sources.nixos-generators;
|
src = builtins.storePath sources.nixos-generators;
|
||||||
}))
|
}))
|
||||||
pkgs.npins
|
pkgs.npins
|
||||||
|
pkgs.rage
|
||||||
|
|
||||||
(pkgs.callPackage ./lib/colmena { inherit (nix-pkgs) colmena; })
|
(pkgs.callPackage ./lib/colmena { inherit (nix-pkgs) colmena; })
|
||||||
(pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { })
|
(pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { })
|
||||||
|
@ -97,6 +131,8 @@ in
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
${git-checks.shellHook}
|
${git-checks.shellHook}
|
||||||
|
# If we want to export these environments, we need to source it, not call it.
|
||||||
|
source $(which decryptAndSourceEnvironment)
|
||||||
'';
|
'';
|
||||||
|
|
||||||
preferLocalBuild = true;
|
preferLocalBuild = true;
|
||||||
|
|
|
@ -300,6 +300,21 @@
|
||||||
"url": null,
|
"url": null,
|
||||||
"hash": "11vvfxw2sznc155x0xlgl00g6n9sr90xa0b1hr14vchg7gkz46r5"
|
"hash": "11vvfxw2sznc155x0xlgl00g6n9sr90xa0b1hr14vchg7gkz46r5"
|
||||||
},
|
},
|
||||||
|
"terranix": {
|
||||||
|
"type": "GitRelease",
|
||||||
|
"repository": {
|
||||||
|
"type": "GitHub",
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix"
|
||||||
|
},
|
||||||
|
"pre_releases": false,
|
||||||
|
"version_upper_bound": null,
|
||||||
|
"release_prefix": null,
|
||||||
|
"version": "2.7.0",
|
||||||
|
"revision": "00710f39f38a0a654a2c4fd96cbb988b4f4cedfa",
|
||||||
|
"url": "https://api.github.com/repos/terranix/terranix/tarball/2.7.0",
|
||||||
|
"hash": "1wsyhsdsjw6xlhpkhaqvia3x0na3nx2vamcb2rbcbdmb7ra1y9f6"
|
||||||
|
},
|
||||||
"wp4nix": {
|
"wp4nix": {
|
||||||
"type": "Git",
|
"type": "Git",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
7
terranix/common.nix
Normal file
7
terranix/common.nix
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
# Until we get some kind of KMS operational, store secrets in the state file.
|
||||||
|
terraform.required_providers.secret = {
|
||||||
|
version = "~> 1.2.1";
|
||||||
|
source = "numtide/secret";
|
||||||
|
};
|
||||||
|
}
|
6
terranix/default.nix
Normal file
6
terranix/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./common.nix
|
||||||
|
./state.nix
|
||||||
|
];
|
||||||
|
}
|
21
terranix/state.nix
Normal file
21
terranix/state.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
# We use terraform.backend.s3 directly instead of the type-checked Terranix
|
||||||
|
# backend.s3 options. The latter does not support setting arbitrary s3
|
||||||
|
# endpoints.
|
||||||
|
#
|
||||||
|
# Note: currently requires the user to provide AWS_ACCESS_KEY_ID as well as
|
||||||
|
# AWS_SECRET_ACCESS_KEY in their environment variables.
|
||||||
|
|
||||||
|
terraform.backend.s3 = {
|
||||||
|
endpoints.s3 = "s3.dgnum.eu";
|
||||||
|
region = "garage";
|
||||||
|
bucket = "monorepo-terraform-state";
|
||||||
|
key = "state";
|
||||||
|
|
||||||
|
# It's just a dumb Garage server, don't try to be smart.
|
||||||
|
skip_credentials_validation = true;
|
||||||
|
skip_region_validation = true;
|
||||||
|
skip_requesting_account_id = true;
|
||||||
|
skip_metadata_api_check = true;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue