atvari-eu/nix-skills

terranix

Write OpenTofu/Terraform infrastructure-as-code in Nix with terranix instead of hand-writing HCL — scaffold a terranix project (flake + config.nix), convert existing .tf HCL files to terranix, fix ${} interpolation clashes between Nix and Terraform ("undefi…

Quelltext ansehen

Verwendung

  1. Installationsbefehl kopieren und das Quellpaket vor der Installation in der eigenen Agentenumgebung prüfen.
  2. Benötigte Werkzeuge, Zugangsdaten und Hosts im Original prüfen.
  3. Eingabe und gewünschtes Ergebnis beschreiben und die Ausgabe mit den Quellen abgleichen.
npx skills add https://github.com/atvari-eu/nix-skills --skill terranix

Vor dem Start

  • Die Installation umfasst weder Modellabo noch API-Kontingent oder Dateizugriffsrechte.
  • Sterne und Installationen zeigen Aktivität, keine unabhängige Qualitäts- oder Sicherheitsprüfung.
Originales Skill-Dokument

Aus dem Quell-Repository gerendert; Überschriften, Beispiele, Code, Tabellen, Links und Bilder bleiben erhalten.

Terranix

terranix generates Terraform JSON from Nix modules. You write config.nix; the terranix tool (or a flake build) produces config.tf.json, which OpenTofu (tofu) applies exactly like HCL — same providers, same state, same plan/apply workflow.

Prefer OpenTofu over Terraform when the user hasn't pinned a choice: it's in nixpkgs as pkgs.opentofu, command tofu, reads the same .tf.json files, and resolves providers from its own registry mirror.

Two rules that prevent most mistakes:

  • `config.tf.json` is a build artifact. Never hand-edit it; regenerate it.

Gitignore it along with state (see below).

  • Nix and Terraform share the `${}` syntax (see

Interpolation escaping) — this clash is the single biggest source of broken terranix configs.

Don't convert an existing working HCL project to terranix unasked; offer it if the user is clearly Nix-first, but leave plain .tf repos alone otherwise.

Two ways to run terranix

nixpkgs CLI (pkgs.terranix)flake (github:terranix/terranix)
Invocationterranix -q > config.tf.jsonnix build -o config.tf.json
Reads./config.nix (or path argument)modules = [ ./config.nix ]
Module argslib is empty as of 2.8.0nixpkgs lib extended with lib.tf.ref / lib.tfRef
Best forquick one-offsanything real: pinning, modules, CI

Quick one-off with the CLI

bash
nix run nixpkgs#terranix -- -q > config.tf.json   # evaluates ./config.nix

Useful flags: -q/--quiet prints only the JSON; by default null-valued attributes are stripped (-n / --with-nulls keeps them); --show-trace helps debug evaluation errors.

The flake way (recommended)

nix
# file: flake.nix
{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
    terranix.url = "github:terranix/terranix";
    terranix.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { self, nixpkgs, terranix }: {
    packages.x86_64-linux.default =
      terranix.lib.terranixConfiguration {
        system = "x86_64-linux";
        modules = [ ./config.nix ];
      };
  };
}

terranixConfiguration returns a derivation whose output is the JSON, so ${terraformConfiguration} interpolates directly into wrapper scripts:

bash
nix build -o config.tf.json && tofu init && tofu plan

If the repo has no flake yet, the nix-flake skill covers setting one up. Upstream also ships a template: nix flake init --template github:terranix/terranix-examples.

If resolving a branch ref like nixos-unstable fails with GitHub API errors (timeouts, empty responses — it happens regularly), pin an explicit revision instead: github:nixos/nixpkgs/<rev> fetches the tarball directly and skips the API entirely.

Writing config.nix

The attribute tree mirrors Terraform JSON top-level keys one-to-one:

nix
{ lib, ... }:
let
  region = "nbg1";          # prefer plain Nix lets over Terraform `locals`
in
{
  terraform.required_providers.hcloud = {
    source = "hetznercloud/hcloud";
    version = "~> 1.45";
  };

  variable.hcloud_token = {
    type = "string";
    sensitive = true;
  };

  provider.hcloud.token = "\${var.hcloud_token}";

  resource.hcloud_server.web = {
    name = "web.example.org";
    image = "debian-13";
    server_type = "cx23";
    location = region;
    ssh_keys = [ "\${hcloud_ssh_key.admin.id}" ];
  };

  resource.hcloud_ssh_key.admin = {
    name = "admin";
    public_key = "\${file(\"~/.ssh/id_ed25519.pub\")}";
  };

  output.web_ip.value = "\${hcloud_server.web.ipv4_address}";
}

Mapping from HCL blocks:

HCLterranix
resource "type" "name" { ... }resource.type.name = { ... };
data "type" "name" { ... }data.type.name = { ... };
provider "hcloud" { ... }provider.hcloud = { ... };
variable "x" { ... }variable.x = { ... };
output "x" { value = ... }output.x.value = ...;
module "m" { source = ... }module.m.source = ...;
locals { x = ... }use a Nix let binding instead

Split large configs into modules with imports = [ ./network.nix ]; — these are NixOS-style modules, so they can declare their own options and take module args. Community modules live in terranix-* GitHub repos and are added as flake inputs. Use terranix-doc-json / terranix-doc-man to inspect what options a module provides.

Interpolation escaping

Everything meant for Terraform must survive Nix evaluation. In double-quoted strings, escape ${ with a backslash; escape inner quotes too:

nix
provider.hcloud.token = "\${var.hcloud_token}";
key = "\${file(\"~/.ssh/id_ed25519.pub\")}";

On the flake version of terranix (≥ 2.9), module args include helpers that do the quoting for you — lib.tf.ref "expr" produces "${expr}", lib.tfRef is an alias. Note the version divergence: the nixpkgs CLI package (2.8.0 at the time of writing) passes an empty lib, so those helpers only exist in flake-based setups.

Pitfalls:

  • Inside indented strings (''...''), escape as ''${. But avoid indented

strings for references entirely: the surrounding whitespace/newlines end up inside the JSON value and corrupt the expression. Prefer single-line double-quoted strings for anything containing ${.

  • Forgetting the backslash fails fast ("undefined variable 'var'") — good.

Silently wrong is rarer but worse: check generated JSON when in doubt.

  • Computed values that don't need Terraform interpolation (names, regions,

sizes) should stay plain Nix strings — interpolate only actual cross-references between Terraform entities.

Secrets

Never put API tokens in committed Nix files. Mark variables sensitive = true and inject them through the environment at apply time — OpenTofu picks up TF_VAR_<name> automatically:

bash
TF_VAR_hcloud_token="$(cat ~/.secrets/hcloud)" tofu apply

For a durable entrypoint, wrap tofu in a script that loads secrets (e.g. from a password store or loadCredentials) rather than baking them into the flake.

Verification

Hand back only verified configurations:

  1. Parse: nix-instantiate --parse config.nix
  2. Generate: terranix -q > config.tf.json (or nix build) — evaluation

errors surface here first

  1. Sanity-check the JSON: it parses, and Terraform references appear

literally (grep -F '${var.' config.tf.json)

  1. Validate: tofu init -input=false && tofu validate — catches schema

errors against the pinned provider without touching infrastructure

  1. Leave plan/apply to the user unless asked: plans need credentials and

change real infrastructure.

Gitignore the artifacts; commit only sources and the provider lock file:

gitignore
/.terraform/
*.tfstate*
/config.tf.json

.terraform.lock.hcl should be committed (it pins provider hashes).

Migrating existing HCL to terranix

Only on request. Because Terraform JSON and HCL are equivalent representations, migration preserves resource addresses (hcloud_server.web stays hcloud_server.web) and therefore state continuity — nothing gets recreated. Convert block-by-block per the table above, keep variable/output names identical, delete the old .tf files once tofu plan shows no changes, and keep .terraform.lock.hcl.

Verwandte Aufgaben

aus demselben Repository

Weitere Skills

Alle Skills
atvari-eu
Community

find-skills

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill. Also handles managing existing installs — use it whenever the user wants to update, upgrade, refresh, reinstall, or remove already-installed skills ("update my skills", "upgrade the pdf skill", "i

Installationen
2
GitHub Stars
0
Aktualisiert
26. Aug.
atvari-eu
Community

nix-flake

Set up a reproducible Nix development environment for any Git repository — create a flake.nix with a devshell so nix develop provides the project's toolchain (cargo/clippy, go/gopls, python/pytest/black, node, ...) without global installs, fix a missing or broken flake.nix, port a legacy shell.nix/default.nix to a flake, diagnose nix develop errors such as "does not contain a flake.nix", enforce a policy that every repo must have a flake.nix, or migrate an existing flake away from flake-utils. U

Installationen
2
GitHub Stars
0
Aktualisiert
26. Aug.
atvari-eu
Community

nix-hash

Handles SRI (Subresource Integrity) hashes for Nix, including converting between hash formats (SRI, hex, base32), computing hashes of files and strings, using nix hash commands, and working with fixed-output derivations. Use this skill whenever the user mentions nix hashes, SRI hashes, hash conversion, hash prefetching, fixed-output derivations, fetchFromGitHub hashes, fetchurl hashes, or any task involving Nix hash manipulation.

Installationen
2
GitHub Stars
0
Aktualisiert
26. Aug.
atvari-eu
Community

nix-init

Generates Nix packages from repository URLs using nix-init — hash prefetching, dependency inference, and license detection included. Use this skill whenever the user wants to package a GitHub/GitLab/Gitea repo for Nix, add a tool or library that is missing from nixpkgs to their flake or home-manager config, prepare a pkgs/by-name contribution, or mentions nix-init directly. Also use it when asked to "package X for Nix", "create a derivation from this URL", "add this repo as a Nix package", or to

Installationen
2
GitHub Stars
0
Aktualisiert
26. Aug.