.agents/skills/terraform-station-test/SKILL.md
Write and maintain Terraform tests for the Station module. Use this skill whenever the user asks to add, update, fix, or run Station tests in tests/*.tftest.hcl, validate module behavior across minimum/maximum configurations, wire setup-* modules into test runs, or align test changes with Station CI selective test execution.
npx skillsauth add blinqas/station terraform-station-testInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill for testing this repository's root Terraform module (Station) with Terraform's built-in test framework.
Station is consumed as a module. Tests must validate behavior through module inputs and outputs, not by treating the root as a standalone deployment.
tests/*.tftest.hclapplication, group, tfe, connectivity, identity, user_assigned_identities)tests/setup-*/run outputsterraform test / terraform test -filter=...variables.tfvariables.applications.tfvariables.identity.tfrun block in a test file instead of creating new blocks unless logic is meaningfully different.run blocks in Station tests should be setup/bootstrap runs (for dynamic IDs/resources needed by main runs).variables block(s).terraform fmt -recursive before finishing.terraform validate for this repository (module + provider alias limitation).Use this shape unless a feature needs a justified variation:
provider "tfe" {}provider "azuread" {}provider "azurerm" { features {} }provider "azurerm" { alias = "connectivity" ... }test { parallel = true }run blocksvariables with placeholders such as "# Overridden" or "This has to be overridden"run block(s) with:
module { source = "./" }variables overrides using merge(...) and values from setup runsassert blocks with clear error_messagetests/setup-common:
tests/setup-tfe-project:
id is used to override var.tfe.project.idtests/setup-application:
required_resource_accesstests/setup-groups:
tests/setup-entraid:
tests/setup-peering-networks:
tests/setup-uai:
Use these exact ideas when placeholders exist in file-level variables.
In main runs:
tfe = merge(var.tfe, { project = merge(var.tfe.project, { id = run.bootstrap_create_tfc_test_project.id }) })
For app tests and similar cases, map outputs from setup runs into nested feature objects with merge(...).
Examples:
required_resource_access.*.resource_object_id from setup run outputsremote_virtual_network_id from setup network outputvariables to include:
variables, override placeholders from setup outputs.alltrue([...]) when validating repeated patterns across maps.value == "") and sensitive == true.var.applications or var.groups is set).tests/tfe.tftest.hcl)..agent.test.env file (copy from .agent.test.env.example)To avoid polluting shell state, never rely on globally exported variables for test runs.
Use this policy:
./.agent.test.env (repo root)..agent.test.env inside a short-lived shell.export ... directly in the interactive terminal session.Agent workflow when asked to run tests:
./.agent.test.env exists../.agent.test.env.example../.agent.test.env before continuing..agents/skills/terraform-station-test/scripts/check-az-context.sh) before Terraform commands.Existence/bootstrap command:
if [ ! -f ./.agent.test.env ]; then cp ./.agent.test.env.example ./.agent.test.env; echo "Created .agent.test.env from template. Fill values and re-run."; exit 1; fi
Azure context preflight command:
sh ./.agents/skills/terraform-station-test/scripts/check-az-context.sh ./.agent.test.env
This check ensures all of the following before tests proceed:
az is installedTF_VAR_tenant_idTF_VAR_subscription_idTF_VAR_subscription_id equals ARM_SUBSCRIPTION_IDTFE_TOKEN is set for Terraform Cloud operations (including teardown)Important: this does not force re-login each test. It only validates current context and fails fast when mismatched.
Preferred command pattern:
sh -c '. ./.agent.test.env; terraform <command>'
This keeps the environment scoped to that command only.
sh ./.agents/skills/terraform-station-test/scripts/check-az-context.sh ./.agent.test.env
sh -c '. ./.agent.test.env; terraform init'
sh -c '. ./.agent.test.env; terraform fmt -recursive'
sh -c '. ./.agent.test.env; terraform test -filter=tests/<feature>.tftest.hcl'
Run all tests only when needed:
sh -c '. ./.agent.test.env; terraform test'
Quick preflight check:
sh -c '. ./.agent.test.env; env | grep -E "^(ARM_SUBSCRIPTION_ID|TF_VAR_subscription_id|TF_VAR_tenant_id|TFE_ORGANIZATION|TF_VAR_tfc_organization_name|TF_VAR_tfc_project_name)="'
# Optional explicit check for TFE token presence
sh -c '. ./.agent.test.env; test -n "${TFE_TOKEN:-}" && echo "TFE_TOKEN set" || (echo "TFE_TOKEN missing"; exit 1)'
CI uses selective test execution (.github/scripts/determine-tests.sh).
Implications:
/test-all or /test all.Reference mapping docs:
.github/scripts/README.md.github/workflows/terraform.yamltests/*.tftest.hclterraform fmt -recursive has been runterraform test -filter=... command has been run (or command provided if execution is not possible)Ask before implementation only if one of these is unclear:
Use these as starting points and adjust names/variables/assertions to your feature.
provider "tfe" {}
provider "azuread" {}
provider "azurerm" {
features {}
}
provider "azurerm" {
alias = "connectivity"
features {}
}
test {
parallel = true
}
run "bootstrap_create_tfc_test_project" {
variables {
tfc_project_name = "tests_<feature>"
}
module {
source = "./tests/setup-tfe-project"
}
}
run "setup" {
module {
source = "./tests/setup-common"
}
}
variables {
tfe = {
project = {
id = "# Overridden"
name = "tests_<feature>"
}
organization_name = "<org>"
workspace_name = "<feature>-test"
workspace_description = "Station test for <feature>"
workspace_settings = {
execution_mode = "remote"
}
}
<feature> = {
minimum = {
# required fields only
}
maximum = {
# required + optional fields
}
}
}
run "<feature>-main" {
variables {
tfe = merge(var.tfe, {
project = merge(var.tfe.project, {
id = run.bootstrap_create_tfc_test_project.id
})
})
}
module {
source = "./"
}
assert {
condition = true
error_message = "Replace with real assertion for minimum scenario"
}
assert {
condition = true
error_message = "Replace with real assertion for maximum scenario"
}
}
Use this pattern when file-level values must be replaced by IDs from setup runs.
run "<feature>-main" {
variables {
<feature> = merge(var.<feature>, {
maximum = merge(var.<feature>.maximum, {
owners = [run.setup.azuread_client_config.current.object_id]
required_resource_access = merge(var.<feature>.maximum.required_resource_access, {
graph = merge(var.<feature>.maximum.required_resource_access.graph, {
resource_object_id = run.bootstrap_application.MicrosoftGraph.object_id
})
})
})
})
tfe = merge(var.tfe, {
project = merge(var.tfe.project, {
id = run.bootstrap_create_tfc_test_project.id
})
})
}
module {
source = "./"
}
}
Use when you intentionally verify input validation behavior.
run "<feature>-invalid-input" {
command = plan
variables {
<feature> = {
minimum = {
# intentionally invalid value
}
}
}
module {
source = "./"
}
expect_failures = [
var.<feature>
]
}
After adapting a skeleton:
sh -c '. ./.agent.test.env; terraform fmt -recursive'sh -c '. ./.agent.test.env; terraform test -filter=tests/<feature>.tftest.hcl'testing
Comprehensive guide for writing and running Terraform tests. Use when creating test files (.tftest.hcl), writing test scenarios with run blocks, validating infrastructure behavior with assertions, mocking providers and data sources, testing module outputs and resource configurations, or troubleshooting Terraform test syntax and execution.
development
Maintain the Station Terraform module itself (not test authoring). Use this skill whenever the user asks to add, change, refactor, or troubleshoot Station module behavior in root *.tf files or child module folders (application/, group/, user_assigned_identity/, hashicorp/tfe/), update variables/outputs/validations, or adjust provider/resource wiring for module consumers.
testing
Create, edit, improve, or audit AgentSkills. Use when creating a new skill from scratch or when asked to improve, review, audit, tidy up, or clean up an existing skill or SKILL.md file. Also use when editing or restructuring a skill directory (moving files to references/ or scripts/, removing stale content, validating against the AgentSkills spec). Triggers on phrases like "create a skill", "author a skill", "tidy up a skill", "improve this skill", "review the skill", "clean up the skill", "audit the skill".
testing
Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).