A Policy Assignment that Actually Denies
enforce = false is Azure DoNotEnforce: the assignment appears, resources are evaluated, a compliance percentage is charted - and every violating resource is created anyway. From the portal compliance view that is indistinguishable from an enforced policy. Also refuses a silent not_scopes exclusion and an unexplained denial.
Verification
Static-verifiedPassed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).
Conformance
- Static validation (fmt · validate · tflint)
- No applicable security policies for this provider
- Plan tests (mocked: validation rules · outputs)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live test pending (no cloud run yet)
Last verified 2026-09-13 · how we verify
Use it from the registry
terraform · opentofumodule "policy" {
source = "www.iac-bazaar.com/iac-bazaar/azure-policy/azure"
version = "1.0.0"
}Needs a registry token from /account/tokens. The module itself is free; the account is what identifies you. Full setup: registry docs.
Inputs & outputs
Create a free account to read this module's contract
The declared contract - every input name, type, default and description, plus every output - is shown to signed-in accounts, not to anonymous visitors.
A free account sees the contract of every module in the catalogue. There is no subscription and nothing to buy - the modules are free to download, and they run under Vizier.
Documentation
azure-policy
An Azure Policy assignment that actually denies. Works with Terraform and
OpenTofu (>= 1.6), azurerm provider >= 4.0, < 5.0.
enforce = false makes an assignment evaluate and deny nothing. Azure calls
it DoNotEnforce; the portal calls it "Enforcement: Disabled". The assignment
still appears in the policy blade, resources are still evaluated against it, the
compliance percentage is still computed and charted - and a resource that
violates the policy is created anyway. It is the difference between a policy and
a report, and from the portal's compliance view the two look identical. A
precondition refuses it unless accept_audit_only states that a report is
what you wanted, and actually_denies is an output so a test can assert on it.
A deployIfNotExists or modify policy needs an identity and a location.
Without both, the assignment is created successfully and the remediation never
runs: no error, no deployment, and a compliance state that stays non-compliant
while the thing meant to fix it sits there unable to act. Set
remediation_identity and location; principal_id is an output so you can
grant it the role it needs.
not_scopes is a hole in the policy, and it is silent. An excluded scope
does not report as non-compliant - it reports as nothing at all, so an exclusion
added for one migration six months ago is indistinguishable from a scope the
policy never covered. A precondition refuses a non-empty exclusion list
unless accept_exclusions says it is current, and excluded_scopes is an
output worth reviewing on a schedule.
Without a non_compliance_message the denial is generic. Somebody whose
deployment is refused gets a policy id and no explanation, which is how a
correct policy ends up disabled by whoever happens to be on call.
Verification
Static validation runs tofu fmt, init, validate, tflint and checkov.
This module has not yet had a live test, so it is published as statically
validated with its live test pending and does not carry the live-tested mark.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Usage