Loading...
Loading...
Homelab infrastructure management with Terragrunt, OpenTofu, and Terraform patterns. Use when: (1) Planning or applying infrastructure changes to dev/integration/live clusters, (2) Adding/modifying machines in inventory.hcl, (3) Creating or updating units and stacks, (4) Working with feature flags, (5) Running validation (fmt, validate, test, plan), (6) Understanding the units→stacks→modules architecture, (7) Working with HCL configuration files, (8) Bare-metal Kubernetes provisioning or Talos configuration. Triggers: "terragrunt", "terraform", "opentofu", "tofu", "infrastructure code", "IaC", "inventory.hcl", "networking.hcl", "HCL files", "add machine", "add node", "cluster provisioning", "bare metal", "talos config", "task tg:", "infrastructure plan", "infrastructure apply", "stacks", "units", "modules architecture" Always use task commands (task tg:*) instead of running terragrunt directly.
npx skill4agent add ionfury/homelab terragrunt# Validation (run in order)
task tg:fmt # Format HCL files
task tg:test-<module> # Test specific module (e.g., task tg:test-config)
task tg:validate-<stack> # Validate stack (e.g., task tg:validate-integration)
# Operations
task tg:list # List available stacks
task tg:plan-<stack> # Plan (e.g., task tg:plan-integration)
task tg:apply-<stack> # Apply (REQUIRES HUMAN APPROVAL)
task tg:gen-<stack> # Generate stack files
task tg:clean-<stack> # Clean generated filesterragrunttofutaskinventory.hclnode50 = {
cluster = "live"
type = "worker"
install = {
selector = "disk.model == 'Samsung'"
architecture = "amd64"
}
interfaces = [{
id = "eth0"
hardwareAddr = "aa:bb:cc:dd:ee:ff" # VERIFY correct
addresses = [{ ip = "192.168.10.50" }] # VERIFY available
}]
}task tg:plan-livecluster == "live"versions.hclmodules/config/main.tflocals {
new_feature_enabled = contains(var.features, "new-feature")
}features = ["gateway-api", "longhorn", "new-feature"]units/new-unit/terragrunt.hclinclude "root" {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "../../../.././/modules/new-unit"
}
dependency "config" {
config_path = "../config"
mock_outputs = { new_unit = {} }
}
inputs = dependency.config.outputs.new_unitmodules/new-unit/variables.tfmain.tfoutputs.tfversions.tfunitmodules/<name>/tests/*.tftest.hcl# Top-level variables set defaults for ALL run blocks
variables {
name = "test-cluster"
features = ["gateway-api"]
machines = {
node1 = {
cluster = "test-cluster"
type = "controlplane"
# ... complete machine definition
}
}
}
run "feature_enabled" {
command = plan
variables {
features = ["prometheus"] # Only override what differs
}
assert {
condition = output.prometheus_enabled == true
error_message = "Prometheus should be enabled"
}
}task tg:test-configtask tg:test--auto-approveinventory.hcl.terragrunt-cache/.terragrunt-stack/this["rpi4"]xargswhile# WRONG - xargs mangles quotes in resource names
terragrunt state list | xargs -n 1 terragrunt state rm
# CORRECT - while loop preserves quotes
terragrunt state list | while read -r resource; do terragrunt state rm "$resource"; donedata.talos_machine_configuration.this["rpi4"]task tg:fmttask tg:testtask tg:validatetask tg:plan-<stack>