-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: basic lib for terraform configs
- Loading branch information
1 parent
2a47b3d
commit 7d955dc
Showing
4 changed files
with
324 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
config, | ||
lib, | ||
flake-parts-lib, | ||
... | ||
}: let | ||
inherit | ||
(lib) | ||
mkOption | ||
types | ||
; | ||
inherit | ||
(flake-parts-lib) | ||
mkTransposedPerSystemModule | ||
; | ||
in | ||
mkTransposedPerSystemModule { | ||
name = "terraformConfigurationPackages"; | ||
option = mkOption { | ||
type = types.lazyAttrsOf types.package; | ||
default = {}; | ||
description = '' | ||
An attribute set of Terraform configuration packages. | ||
The contents will be valid terraform HCL/JSON files containing the terraform configuration merged with the terranix configuration. | ||
''; | ||
}; | ||
# this refers to the current file | ||
file = ./custom-outputs.nix; | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
inputs = { | ||
nixpkgs.url = "nixpkgs/nixos-unstable"; | ||
flake-parts.url = "github:hercules-ci/flake-parts"; | ||
terranix.url = "github:terranix/terranix"; | ||
}; | ||
|
||
outputs = { | ||
self, | ||
flake-utils, | ||
flake-parts, | ||
... | ||
}: | ||
flake-parts.lib.mkFlake {inherit self;} { | ||
systems = ["x86_64-linux" "aarch64-linux"]; | ||
imports = [ | ||
./lib.nix | ||
]; | ||
|
||
flake.customOutputModule = ./custom-outputs.nix; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
{ | ||
inputs, | ||
self, | ||
lib, | ||
... | ||
}: { | ||
imports = [ | ||
./custom-outputs.nix | ||
]; | ||
|
||
flake.lib = rec { | ||
# call into terranix to build a configuration, loading all `.nix` files in the directory as modules | ||
mkTerranixConfiguration = { | ||
path, | ||
system, | ||
}: let | ||
filterFileName = name: lib.strings.hasSuffix ".nix" name; | ||
|
||
# filter out all directories and files that are not .nix files | ||
directoryContents = builtins.readDir path; | ||
filesOnly = lib.attrsets.filterAttrs (x: y: y == "regular") directoryContents; | ||
nixFiles = builtins.attrNames (lib.attrsets.filterAttrs (x: y: filterFileName x) filesOnly); | ||
|
||
modules = map (x: "${path}/${x}") nixFiles; | ||
in | ||
inputs.terranix.lib.terranixConfiguration { | ||
inherit system modules; | ||
# support manually specifying null values. without this terranix will remove keys with a null value | ||
# strip_nulls = true; | ||
}; | ||
|
||
# find all `.tf` and `.tf.json` files in the directory and create a list of paths to them | ||
# includes all subdirectories so they can be used as terraform modules | ||
mkTerraformConfiguration = {path}: let | ||
# filter out all directories and files that are not .tf or .tf.json files | ||
directoryContents = builtins.readDir path; | ||
filesOnly = lib.attrsets.filterAttrs (x: y: y == "regular") directoryContents; | ||
filterFileName = name: lib.strings.hasSuffix ".tf" name || lib.strings.hasSuffix ".tf.json" name; | ||
tfFiles = builtins.attrNames (lib.attrsets.filterAttrs (x: y: filterFileName x) filesOnly); | ||
|
||
includedFiles = map (x: "${path}/${x}") tfFiles; | ||
subdirectories = builtins.attrNames (lib.attrsets.filterAttrs (x: y: y == "directory") directoryContents); | ||
includedDirectories = map (x: "${path}/${x}") subdirectories; | ||
in (includedFiles ++ includedDirectories); | ||
|
||
# combine the terranix and terraform configurations into a single derivation containing all of the files | ||
# intended for the final build output for terraform. | ||
# the output is devoid of any nix-specific code | ||
# bundles the generated terranix configurations with existing `.tf` and `.tf.json` files from their configuration directory | ||
mkTerraformConfigurationPackage = { | ||
name, | ||
path, | ||
pkgs, | ||
system, | ||
}: let | ||
generatedConfig = self.lib.mkTerranixConfiguration {inherit path system;}; | ||
providedConfig = self.lib.mkTerraformConfiguration {inherit path;}; | ||
in | ||
pkgs.runCommandNoCC "terraform-config-${name}" {} '' | ||
mkdir -p $out | ||
# copy the provided (terraform) configuration files | ||
${lib.strings.concatStringsSep "\n" (map (x: "cp -r ${x} $out") providedConfig)} | ||
# copy the generated (terranix) configuration file | ||
cp ${generatedConfig} $out/config.tf.json | ||
''; | ||
|
||
# helper to create and bundle multiple configurations | ||
buildTerraformConfigurations = { | ||
configDir, | ||
configNames, | ||
system, | ||
pkgs, | ||
}: let | ||
# reducer should provide an output containing the configurations keyed by name | ||
reducer = l: r: let | ||
path = "${configDir}/${r}"; | ||
configuration = self.lib.mkTerraformConfigurationPackage { | ||
name = r; | ||
inherit path pkgs system; | ||
}; | ||
in | ||
{ | ||
"${r}" = configuration; | ||
} | ||
// l; | ||
in | ||
builtins.foldl' reducer {} configNames; | ||
|
||
determineSubdirNames = {path}: let | ||
directoryContents = builtins.readDir path; | ||
subdirectories = builtins.attrNames (lib.attrsets.filterAttrs (x: y: y == "directory") directoryContents); | ||
in | ||
subdirectories; | ||
}; | ||
} |