From ea4b4b4a8e609b719ef5967885ac7e78b996dcf7 Mon Sep 17 00:00:00 2001 From: Ryan Lahfa Date: Thu, 10 Oct 2024 12:27:40 +0200 Subject: [PATCH] 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 --- .credentials/admin-environment.age | 5 +++++ .gitignore | 3 +++ default.nix | 14 ++++++++++++++ npins/sources.json | 15 +++++++++++++++ terranix/common.nix | 7 +++++++ terranix/default.nix | 6 ++++++ terranix/state.nix | 21 +++++++++++++++++++++ 7 files changed, 71 insertions(+) create mode 100644 .credentials/admin-environment.age create mode 100644 terranix/common.nix create mode 100644 terranix/default.nix create mode 100644 terranix/state.nix diff --git a/.credentials/admin-environment.age b/.credentials/admin-environment.age new file mode 100644 index 0000000..b49cd20 --- /dev/null +++ b/.credentials/admin-environment.age @@ -0,0 +1,5 @@ +age-encryption.org/v1 +-> ssh-ed25519 +qVung Rzqud7wBklrZ+T/50qx2Ly8d7OVb1za+pShg/4Wu3Hw +CtSs7bGmE8gpt6pxm5FlP8Btr0hwx9F4UUB40bxSg24 +--- Ur0gMkDzmnrlX8rwx0b2uPA11KYnD28WhC3E2sQYUic +TݥlFIRuP8wZ9Zc^ (X& #Pb_0[HIrcS?0xqgq,1Fj,VJ#ܾe8!5[PBF'xȉ!x)9Ny ;i9)pП~+DP~ \ No newline at end of file diff --git a/.gitignore b/.gitignore index d50eeb8..51613c9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ result-* *.qcow2 .gcroots .pre-commit-config.yaml + +# Ignore Terraform configuration file +config.tf.json diff --git a/default.nix b/default.nix index 414feb8..f45524a 100644 --- a/default.nix +++ b/default.nix @@ -67,9 +67,18 @@ let 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 { + inherit terranixConfigFile terranixConfig; + nodes = builtins.mapAttrs ( host: { site, ... }: "${host}.${site}.infra.dgnum.eu" ) (import ./meta/nodes.nix); @@ -83,6 +92,11 @@ in name = "dgnum-infra"; packages = [ + (pkgs.writeShellScriptBin "tf" '' + set -eo pipefail + ln -snf ${terranixConfigFile} config.tf.json + exec ${pkgs.lib.getExe pkgs.opentofu} "$@" + '') (pkgs.nixos-generators.overrideAttrs (_: { version = "1.8.0-unstable"; src = builtins.storePath sources.nixos-generators; diff --git a/npins/sources.json b/npins/sources.json index fa089ef..ee03e5b 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -300,6 +300,21 @@ "url": null, "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": { "type": "Git", "repository": { diff --git a/terranix/common.nix b/terranix/common.nix new file mode 100644 index 0000000..0e8b0be --- /dev/null +++ b/terranix/common.nix @@ -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"; + }; +} diff --git a/terranix/default.nix b/terranix/default.nix new file mode 100644 index 0000000..b6ff81e --- /dev/null +++ b/terranix/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./common.nix + ./state.nix + ]; +} diff --git a/terranix/state.nix b/terranix/state.nix new file mode 100644 index 0000000..ef2f7d5 --- /dev/null +++ b/terranix/state.nix @@ -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; + }; +}