terranix

terranix is a terraform.json generator with a nix-like feeling.

Installation

To use these options, add to your flake inputs:

terranix.url = "github:terranix/terranix";

and inside the mkFlake:

imports = [
  inputs.terranix.flakeModule
];

Run nix flake lock and you're set.

Options

perSystem.terranix.setDevShell

Whether to set default devShell or not. By default enabled. You can disable this if you want to customize the devShell creation youself or otherwise wanting to avoid output definition conflicts.

The devShell are still available at terranix.terranixConfigurations.<name>.result.devShell, should you want to incorporate them using pkgs.mkShell.inputsFrom or similar.

Type: boolean

Default: true

Declared by:

perSystem.terranix.terranixConfigurations

A submodule of all terranix configurations.

Type: attribute set of (submodule)

Default: { }

Declared by:

perSystem.terranix.terranixConfigurations.<name>.modules

Modules of the Terranix configuration.

Type: list of path

Default: [ ]

Declared by:

perSystem.terranix.terranixConfigurations.<name>.result

A collection of useful read-only outputs by this configuration. For debugging or otherwise.

Type: submodule (read only)

Default: { }

Declared by:

perSystem.terranix.terranixConfigurations.<name>.result.app

The exposed default app. Made from result.scripts.apply.

Yes, only a single app, and simply running it as nix run .#foo would yield a terraform apply for the config foo.

But then how does random terraform invocations like nix run .#foo.destroy work? It’s actually still using the same app as before - you’re still in the apply derivation, as strange as it sounds.

The magic lies in the use of derivation passthru which (simplified) lets you namespace other derivations inside a main derivation. In other words, nix run .#foo runs the apply derivation named foo like normally. nix run .#foo.destroy runs the destroy script inside of the apply derivation.

This workaround is required because the flake schema outputs have no concept of nesting derivations like this - i.e. apps.x86_64-linux.foo HAS to resolve to a derivation and NOT an attrset.

The legacyPackages output is an exception to this rule. It was created because nixpkgs constantly nest derivations (consider package sets like python311Packages), so an escape hatch was needed for flakes who needed to refer to these nested derivations. But having scripts reside in this output made no semantic sense, so this was done instead as a conceptual simplication.

Type: unspecified value

Default: "The default app which defaults to the `apply` script."

Declared by:

perSystem.terranix.terranixConfigurations.<name>.result.devShell

The exposed devShell.

Note that you have to re-enter/ your devShell when your configuration changes! The invocation scripts will still target your old configuration otherwise.

For those who want devShell-based access like

$ nix develop .#foo
$ apply
$ destroy

As opposed to app-based access like

$ nix run .#foo
$ nix run .#foo.destroy

Type: unspecified value

Default: "The final devShell with scripts and terraform wrapper."

Declared by:

perSystem.terranix.terranixConfigurations.<name>.result.scripts

The exposed Terraform scripts (apply, etc). result.terraformWrapper included for convenience.

Type: unspecified value

Default:

''
  {
    init = mkTfScript "init" '''
      terraform init
    ''';
    apply = mkTfScript "apply" '''
      terraform init
      terraform apply
    ''';
    plan = mkTfScript "plan" '''
      terraform init
      terraform plan
    ''';
    destroy = mkTfScript "destroy" '''
      terraform init
      terraform destroy
    ''';
    terraform = submod.config.result.terraformWrapper;
  }
''

Declared by:

perSystem.terranix.terranixConfigurations.<name>.result.terraformConfiguration

The exposed Terranix configuration as created by lib.terranixConfiguration.

Type: unspecified value

Default: "The final Terraform configuration JSON."

Declared by:

perSystem.terranix.terranixConfigurations.<name>.result.terraformWrapper

The exposed, wrapped Terraform.

Type: package

Default: "The Terraform wrapper."

Declared by:

perSystem.terranix.terranixConfigurations.<name>.terraformWrapper

How to invoke terraform for this terranix configuration.

Type: submodule

Default: { }

Declared by:

perSystem.terranix.terranixConfigurations.<name>.terraformWrapper.extraRuntimeInputs

Extra runtimeInputs for the terraform invocations.

Type: list of package

Default: [ ]

Declared by:

perSystem.terranix.terranixConfigurations.<name>.terraformWrapper.prefixText

Prefix text

Type: string

Default: ""

Declared by:

perSystem.terranix.terranixConfigurations.<name>.terraformWrapper.suffixText

Suffix text

Type: string

Default: ""

Declared by:

perSystem.terranix.terranixConfigurations.<name>.workdir

Working directory of the terranix configuration. Defaults to submodule name.

Type: string

Default: "‹name›"

Declared by: