Skip to content

No Provisioners

Removes all provisioner blocks from resources. Provisioners bypass the declarative model and are a supply chain risk in shared modules.

When to use this rule

Use this when: You use community Terraform modules from public registries and want to ensure no arbitrary code runs during terraform apply. Or your platform team has banned provisioners as a policy.

Do not use this when: Your modules intentionally use provisioners for bootstrapping that cannot be replaced with user_data, cloud-init, or configuration management tools. This is rare in terraform-aws-modules.


Why this rule exists

Terraform provisioners run arbitrary commands during terraform apply. They don't appear in terraform plan output. In a module sourced from a public registry, provisioner blocks are a supply chain risk: local-exec can modify local files, call APIs, or exfiltrate data.

HashiCorp's own documentation says "provisioners are a last resort." Many platform teams ban them entirely. This rule enforces that ban at the module level by removing all provisioner blocks before the module reaches the developer.


Affected resources

ResourceServiceWhy
*All resourcesAny resource that contains provisioner blocks (local-exec, remote-exec, file)

Known limits

  • Only removes provisioner blocks from resource definitions. Does not remove null_resource resources that contain provisioners (the entire resource remains).
  • Does not affect local-exec or remote-exec in root module code — only in the downloaded module source.
  • Does not detect or remove provisioner-like behavior implemented through external data sources or Lambda functions.

What this rule does

Removes all provisioner blocks from every resource in the module.


Before and after

resource "aws_instance" "this" {
  ami           = var.ami_id
  instance_type = var.instance_type

  provisioner "local-exec" {
    command = "echo ${self.private_ip} >> hosts.txt"
  }

  provisioner "remote-exec" {
    inline = ["sudo apt-get update"]
  }
}
resource "aws_instance" "this" {
  ami           = var.ami_id
  instance_type = var.instance_type
}

The only change is the rule transformation. All existing arguments, outputs, and module behavior remain identical.

Real-world scenario

A community module included a local-exec provisioner that ran curl to an external API during terraform apply. The API was decommissioned, causing every apply to hang for 30 seconds before timing out. The provisioner was not visible in terraform plan output.


Compliance framework support

This rule is not a compliance control. It supports these framework objectives as an operational safeguard:

FrameworkControlsRole
SOC 2CC8.1Supports change management by removing unreviewed imperative code from modules
NIST 800-53CM-3, SI-7Supports configuration management and software integrity

Default configuration

This rule ships with the following defaults. Custom parameterization via the registry is planned for a future release.

ParameterTypeDefaultDescription
resource_typeslist(string)["*"]Target resource type patterns

How to enable

Add ?rules=pofix/no_provisioners to your HTTPS module source:

module "example" {
  source = "https://soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws?version=5.0.0&rules=pofix/no_provisioners"
}

Configure via the compliance.tf API. See Getting Started with Operational Rules.


Failure modes

ScenarioResult
Module relies on a provisioner for essential setupThe module may not function correctly after provisioner removal. This is rare in terraform-aws-modules. Test in non-production first.
null_resource with provisioner is not removedThe null_resource itself is not deleted. Only provisioner blocks inside regular resources are removed. null_resource removal requires the block_delete transformer (not used by this rule).

Terraform and OpenTofu compatible

This rule works with both Terraform (1.x+) and OpenTofu (1.6+). The generated HCL uses standard lifecycle meta-arguments supported by all versions.

Help us improve this page

Operational Rules are a new feature. We'd love your feedback on this rule page — what's useful, what's missing, what's confusing. Share feedback.