terraform-policy

Write, test, or convert Terraform Policy files (.policy.hcl, .policytest.hcl, Sentinel→tfpolicy). Triggers: policy.hcl, policytest, convert sentinel, tfpolicy, write a policy.

By hashicorp · 994 installs

npx skills add hashicorp/agent-skills --skill terraform-policy

Source repository · Upstream listing

terraform policy UTILITY SKILL — INVOKES: [tfpolicy author](references/tfpolicy author.md) [tfpolicy test](references/tfpolicy test.md) USE FOR: Writing a new .policy.hcl policy from a description or requirement Converting a .sentinel policy to Terraform Policy Writing or debugging a .policytest.hcl test file Migrating a Sentinel policy library to Terraform Policy Before giving authoring or testing instructions, check the installed tfpolicy CLI version and tailor guidance accordingly. This skill maintains guidance for the two most recent minor lines, 0.4.x and 0.5.x . The 0.3.x bullet below is baseline guidance that applies to every supported line. When a new minor ships, drop the oldest line and add the new one. Inline notes for versions earlier than 0.3.0 are retained only for older CLIs. If the CLI is 0.3.x (baseline), include a top level policy { required providers { ... } } block when authoring .policy.hcl files containing resource or provider policies. It is mandatory for tfpolicy validate ; version range validation is best effort, and wildcard targets such as resource policy " " are not schema validated. Every mock resource {} block in .policytest.hcl files must declare attrs or prior attrs ; if both evaluate to empty, the test case is skipped ( provider {} and module {} mocks are unaffected) (see [tfpolicy test](references/tfpolicy test.md every resource mock must declare a non empty state block tfpolicy 030)). tfpolicy test reuses the target .policy.hcl 's existing top level policy { required providers { ... } } block (there is no separate .policytest.hcl level declaration) to validate provider, resource, and data source policies and core::getdatasource() / core::getresources() arguments against resolved provider schemas before any test runs, failing the whole run on a schema mismatch (see [tfpolicy test](references/tfpolicy test.md test execution behavior)). core::alltrue(list) and core::anytrue(list) are available — prefer them over the core::length() list comprehension workaround (see [tfpolicy author](references/tfpolicy author.md core functions common idioms)). meta.tfe stack and meta.tfe workspace.tags are available to resource, provider, and module policies; Stack fields are empty strings outside Stack evaluations on 0.3.x and 0.4.x ( null on 0.5.x+, see below). On 0.3.x only, the no op operation does not exist: resource policies evaluate only resources that the run creates, updates, or deletes, and the default operations is ["create", "update"] . If the CLI is 0.4.x or newer, all 0.3.x guidance still applies except the operations default, plus the no op operation, which evaluates resources that the run leaves unchanged (the entire state). operations accepts "create" , "update" , "delete" , and "no op" . For policies that do not reference prior attrs , the default operations is now ["create", "update", "no op"] , so omitting it evaluates every resource in state. Use operations = ["create", "update"] to evaluate only changed resources. no op exposes the existing values through attrs , and prior attrs is unavailable. delete cannot be combined with create or no op ( ["update", "delete"] is valid), and prior attrs policies must set operations explicitly. Attrs only policies (no prior attrs ) calling core::getresources whose operations omit no op load with a warning; do not add no op to a prior attrs policy, which fails validation. In tests, set meta.operation = "no op" explicitly because it is never inferred (see [tfpolicy author](references/tfpolicy author.md operation scoping and prior attrs) and [tfpolicy test](references/tfpolicy test.md testing operation aware policies)). If the CLI is 0.5.x or newer, all 0.4.x guidance still applies, with two changes. (1) Absent meta attributes are exposed as null instead of an empty string: meta.alias (no alias), meta.version (no version specified, including modules), and meta.tfe stack.deployment group / deployment name / stack name (workspace evaluations or not set). meta.tfe workspace.tags is still an empty map. Passing null to a function such as core::semverconstraint , or interpolating it into a string such as error message , fails, and && does not short circuit, so guard with a conditional: meta.version != null ? core::semverconstraint(meta.version, " = 2.0.0") : false . Equality checks are null safe ( meta.alias == "secondary" is false when there is no alias), but checks like meta.tfe stack.stack name == "" no longer match (use == null ). (2) prior attrs is rejected at parse time in provider policy and module policy blocks; it is valid only in resource policy (update and delete operations). Use attrs. for provider attributes (see [tfpolicy author](references/tfpolicy author.md meta attributes nullable on 050)). If the CLI version is unknown, ask the user to check it first or provide guidance that clearly distinguishes the 0.3.x , 0.4.x , and 0.5.x paths. DO NOT USE FOR: Writing .tftest.hcl files for Terraform modules — use terraform test General Terraform HCL authoring — use terraform style guide Routing Task Sub skill Write or convert a .policy.hcl policy [tfpolicy author](references/tfpolicy author.md) Write or debug a .policytest.hcl test [tfpolicy test](references/tfpolicy test.md) Examples "Block EC2 instances without encryption" → [tfpolicy author](references/tfpolicy author.md) "Convert this Sentinel policy to tfpolicy" → [tfpolicy author](references/tfpolicy author.md) "Write a policytest for my EBS policy" → [tfpolicy test](references/tfpolicy test.md) Troubleshooting Wrong skill triggered? Load the sub skill directly from the routing table above.