Skip to content

Commit 7a5c866

Browse files
committed
docs: Add article on terranix flake-module integration
Document how the terranix flake-module for flake-parts replaces manual lib.terranixConfiguration wiring with a declarative terranixConfigurations option, covering generated outputs, passthru scripts, devShells, and configuration options.
1 parent 7791300 commit 7a5c866

2 files changed

Lines changed: 134 additions & 0 deletions

File tree

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [What is Terraform / OpenTofu?](what-is-terranix.md)
88
- [Getting started with flakes](getting-started-with-flakes.md)
99
- [Customizing the Terraform binary](terraform-wrapper.md)
10+
- [terranix and flake modules](terranix-and-flake-modules.md)
1011
- [Differences between terranix and HCL](terranix-vs-hcl.md)
1112
- [Functions](functions.md)
1213
- [Modules](modules.md)

src/terranix-and-flake-modules.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# terranix and flake modules
2+
3+
[flake-parts][flake-parts] is a framework for Nix flakes built on the module
4+
system. As flake.parts puts it:
5+
6+
> flakes are configuration, and the module system lets you refactor that configuration
7+
> into reusable pieces — reducing the proliferation of custom Nix glue code.
8+
9+
terranix ships a [flake-module][flake-module] that plugs into flake-parts. It
10+
gives you a declarative, options-based way to use terranix instead of calling
11+
`lib.terranixConfiguration` manually and wiring up your own flake outputs.
12+
13+
[flake-parts]: https://flake.parts
14+
[flake-module]: https://github.com/terranix/terranix/blob/main/flake-module.nix
15+
16+
## Before and after
17+
18+
Without the flake-module, you call `lib.terranixConfiguration` yourself and
19+
manually assemble `packages`, `apps`, and `devShells`. The [Getting started
20+
with flakes](./getting-started-with-flakes.md) page shows what this looks like.
21+
22+
With the flake-module, you declare `terranixConfigurations` and everything else
23+
is generated for you:
24+
25+
```nix
26+
# flake.nix
27+
{
28+
inputs = {
29+
nixpkgs.url = "github:nixos/nixpkgs";
30+
terranix.url = "github:terranix/terranix";
31+
terranix.inputs.nixpkgs.follows = "nixpkgs";
32+
flake-parts.url = "github:hercules-ci/flake-parts";
33+
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
34+
};
35+
36+
outputs = inputs@{ flake-parts, ... }:
37+
flake-parts.lib.mkFlake { inherit inputs; } {
38+
imports = [ inputs.terranix.flakeModules.default ];
39+
systems = [ "x86_64-linux" ];
40+
41+
perSystem = { pkgs, ... }: {
42+
terranix.terranixConfigurations.myproject = {
43+
modules = [ ./config.nix ];
44+
};
45+
};
46+
};
47+
}
48+
```
49+
50+
This single declaration auto-generates `packages`, `apps`, and `devShells` for
51+
each configuration.
52+
53+
## What you get
54+
55+
### packages
56+
57+
Each `terranixConfigurations.<name>` becomes a package. The package is an
58+
`apply` script that runs `terraform init && terraform apply`.
59+
60+
```shell
61+
nix run .#myproject
62+
```
63+
64+
### Passthru scripts
65+
66+
The apply derivation carries `init`, `plan`, `apply`, and `destroy` as passthru
67+
attributes. This means you can run each command directly:
68+
69+
```shell
70+
nix run .#myproject # apply
71+
nix run .#myproject.plan # plan
72+
nix run .#myproject.destroy # destroy
73+
nix run .#myproject.init # init only
74+
```
75+
76+
### devShells
77+
78+
Run `nix develop .#myproject` to get an interactive shell with `apply`, `plan`,
79+
`destroy`, `init`, and the terraform/opentofu wrapper all on your `PATH`.
80+
81+
```shell
82+
$ nix develop .#myproject
83+
$ plan
84+
$ apply
85+
$ destroy
86+
```
87+
88+
Set `terranix.exportDevShells = false` if you don't want these.
89+
90+
### Terraform/OpenTofu wrapper
91+
92+
Each script automatically creates the working directory, symlinks the generated
93+
`config.tf.json`, and runs the appropriate terraform commands.
94+
95+
See [Customizing the Terraform binary](terraform-wrapper.md) for how to use
96+
OpenTofu, bundle provider plugins, or inject secrets.
97+
98+
## Configuration options
99+
100+
Each entry under `terranix.terranixConfigurations` accepts:
101+
102+
| Option | Description |
103+
|---|---|
104+
| `modules` | List of terranix modules to evaluate |
105+
| `extraArgs` | Extra arguments passed to module evaluation (as `specialArgs`) |
106+
| `workdir` | Working directory for terraform state (defaults to the configuration name) |
107+
| `terraformWrapper.package` | Terraform or OpenTofu package (default: `pkgs.terraform`) |
108+
| `terraformWrapper.extraRuntimeInputs` | Additional packages available during terraform runs |
109+
| `terraformWrapper.prefixText` | Shell commands to run before each terraform invocation |
110+
| `terraformWrapper.suffixText` | Shell commands to run after each terraform invocation |
111+
112+
## Multiple configurations
113+
114+
You can define more than one configuration in the same flake. Each gets its own
115+
package, scripts, and devShell:
116+
117+
```nix
118+
perSystem = { pkgs, ... }: {
119+
terranix.terranixConfigurations.staging = {
120+
modules = [ ./staging.nix ];
121+
};
122+
terranix.terranixConfigurations.production = {
123+
modules = [ ./production.nix ];
124+
terraformWrapper.package = pkgs.opentofu;
125+
};
126+
};
127+
```
128+
129+
```shell
130+
nix run .#staging # apply staging
131+
nix run .#production.plan # plan production
132+
nix develop .#staging # interactive shell for staging
133+
```

0 commit comments

Comments
 (0)