The null_resource with provisioners is deprecated in modern Terraform. Upgrade to Terraform 1.4+ and use terraform_data instead, or migrate to native provider features for better reliability and maintainability.
The "null_resource.provisioner not supported" error occurs when you're using an older pattern in Terraform that relies on the null provider's null_resource to run provisioners. This error typically appears in Terraform 1.4 or later, where HashiCorp has transitioned to a built-in terraform_data resource that replaces null_resource. The null_resource was originally created as a workaround to execute provisioners without managing real infrastructure. However, HashiCorp moved away from this pattern and introduced terraform_data as a built-in, maintained replacement. The error indicates that your configuration uses the deprecated null_resource, which may not be fully supported in your current Terraform version or environment. This change is part of HashiCorp's broader initiative to discourage provisioners in favor of more reliable alternatives like cloud-native features, external tools, or configuration management systems.
First, verify which version of Terraform you're running:
terraform versionIf you're on Terraform 1.4 or later, null_resource is deprecated in favor of terraform_data. Ensure your version is fully up to date.
Convert your null_resource blocks to terraform_data. The syntax is nearly identical, with two key changes:
- Change resource "null_resource" to resource "terraform_data"
- Change the trigger argument from triggers to triggers_replace
Before (deprecated):
resource "null_resource" "example" {
triggers = {
instance_id = aws_instance.web.id
}
provisioner "local-exec" {
command = "echo 'Instance created'"
}
}After (current best practice):
resource "terraform_data" "example" {
triggers_replace = aws_instance.web.id
provisioner "local-exec" {
command = "echo 'Instance created'"
}
}Since terraform_data is built into Terraform, you no longer need to require the null provider. Remove or update your required_providers block:
Remove this:
terraform {
required_providers {
null = {
source = "hashicorp/null"
version = "~> 3.0"
}
}
}The terraform_data resource uses the built-in terraform provider, which is always available.
After updating your configuration, reinitialize to apply the changes:
terraform initThis will remove the null provider from your lock file and state if it's no longer referenced.
Verify that your updated configuration is valid and plan your changes:
terraform validate
terraform planReview the plan to ensure Terraform recognizes your terraform_data resources correctly and doesn't attempt to destroy and recreate your infrastructure.
Before applying, consider whether provisioners are necessary. HashiCorp recommends exhausting alternatives first:
- AWS: Use user_data scripts, Systems Manager Run Command, or CloudFormation templates
- Azure: Use Custom Script Extension or Azure Automation
- GCP: Use startup scripts or Cloud Build
- General: Use cloud-init, Ansible, Chef, or other configuration management tools
Provisioners are inherently less reliable than native cloud features and should be a last resort.
Destroy-time Provisioners: Destroy provisioners only run if the resource block remains in your configuration at destroy time. If you remove a resource with a destroy provisioner entirely, the provisioner won't execute. Plan your resource lifecycle accordingly.
terraform_data Limitations: terraform_data is lightweight and stateless. It doesn't authenticate with cloud providers or manage infrastructure. It exists purely for running provisioners and storing trigger-based state transitions. If you need actual resource management, use provider-specific resources instead.
Migration from Older Versions: If upgrading from Terraform 0.12 or earlier, the transition is straightforward. The main difference is the resource name and trigger argument. State migration typically happens automatically during terraform init.
Why Provisioners Are Discouraged: Provisioners run outside Terraform's normal provider plugins and lack proper error handling, retry logic, and idempotency guarantees. They're difficult to debug and often hide infrastructure configuration in scripts. Use them only when no native alternative exists.
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform