Skip to content

Commit 06cd025

Browse files
authored
1 parent 0e1d855 commit 06cd025

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

src/SUMMARY.md

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

src/terraform-wrapper.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Customizing the Terraform binary
2+
3+
When using terranix with [flake-parts][getting-started-flakes], the `terraformWrapper`
4+
option lets you control which Terraform implementation is used, bundle provider plugins,
5+
and run custom commands around each invocation. By default it uses `pkgs.terraform`.
6+
7+
All options live under `terranix.terranixConfigurations.<name>.terraformWrapper`.
8+
9+
[getting-started-flakes]: getting-started-with-flakes.html
10+
[flake-module]: https://github.com/terranix/terranix/blob/main/flake-module.nix
11+
12+
## Using OpenTofu
13+
14+
To use [OpenTofu](https://opentofu.org/) instead of Terraform, set the `package` option:
15+
16+
```nix
17+
{
18+
inputs = {
19+
nixpkgs.url = "github:nixos/nixpkgs";
20+
terranix.url = "github:terranix/terranix";
21+
terranix.inputs.nixpkgs.follows = "nixpkgs";
22+
flake-parts.url = "github:hercules-ci/flake-parts";
23+
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
24+
};
25+
26+
outputs = inputs@{ flake-parts, ... }:
27+
flake-parts.lib.mkFlake { inherit inputs; } {
28+
imports = [ inputs.terranix.flakeModules.default ];
29+
systems = [ "x86_64-linux" ];
30+
perSystem = { pkgs, ... }: {
31+
terranix.terranixConfigurations.default = {
32+
terraformWrapper.package = pkgs.opentofu;
33+
modules = [ ./config.nix ];
34+
};
35+
};
36+
};
37+
}
38+
```
39+
40+
This replaces every `terraform` call in the generated scripts (`init`, `apply`, `plan`, `destroy`) with `tofu`.
41+
42+
## Bundling provider plugins
43+
44+
You can pre-bundle provider plugins so that `terraform init` doesn't need to download them:
45+
46+
```nix
47+
terranix.terranixConfigurations.default = {
48+
terraformWrapper.package = pkgs.terraform.withPlugins (p: [
49+
p.aws
50+
]);
51+
modules = [ ./config.nix ];
52+
};
53+
```
54+
55+
This works the same way for OpenTofu:
56+
57+
```nix
58+
terraformWrapper.package = pkgs.opentofu.withPlugins (p: [
59+
p.aws
60+
p.null
61+
p.external
62+
]);
63+
```
64+
65+
## Running commands before or after Terraform
66+
67+
The `prefixText` and `suffixText` options inject shell commands that run before and after
68+
every Terraform invocation. A common use case is exporting secrets:
69+
70+
```nix
71+
terraformWrapper.prefixText = ''
72+
export TF_VAR_hcloud_token="$(cat /run/secrets/hcloud-token)"
73+
'';
74+
```
75+
76+
Or running a cleanup step afterwards:
77+
78+
```nix
79+
terraformWrapper.suffixText = ''
80+
echo "Terraform finished, cleaning up temp files..."
81+
rm -f /tmp/tf-scratch-*
82+
'';
83+
```
84+
85+
## Extra runtime inputs
86+
87+
When your `prefixText` or `suffixText` call external programs, add them to `extraRuntimeInputs` so they're available on `PATH`:
88+
89+
```nix
90+
terraformWrapper.extraRuntimeInputs = [ pkgs.jq pkgs.awscli2 ];
91+
```
92+
93+
For example, to fetch a secret from AWS Secrets Manager before each run:
94+
95+
```nix
96+
terranix.terranixConfigurations.default = {
97+
terraformWrapper = {
98+
extraRuntimeInputs = [ pkgs.jq pkgs.awscli2 ];
99+
prefixText = ''
100+
export TF_VAR_db_password="$(
101+
aws secretsmanager get-secret-value \
102+
--secret-id my-db-password \
103+
--query SecretString \
104+
--output text
105+
)"
106+
'';
107+
};
108+
modules = [ ./config.nix ];
109+
};
110+
```

0 commit comments

Comments
 (0)