0
0
Terraformcloud~5 mins

Why provisioners are a last resort in Terraform - Why It Works

Choose your learning style9 modes available
Introduction
Provisioners in Terraform let you run scripts or commands on a resource after it is created. However, they can cause problems and make your infrastructure less reliable. It's better to avoid them unless absolutely necessary.
When you need to run a one-time setup script on a new virtual machine that cannot be done through the cloud provider's native features.
When you want to install software or configure a server immediately after it is created and no other Terraform resource supports this.
When you must perform a manual step that cannot be automated through Terraform providers or modules.
When you want to trigger a command on a resource that is not supported by Terraform's built-in resources.
When you have legacy infrastructure that requires specific commands to be run after provisioning.
Commands
Initializes the Terraform working directory and downloads necessary provider plugins.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v4.0.0... - Installed hashicorp/aws v4.0.0 (signed by HashiCorp) Terraform has been successfully initialized!
Applies the Terraform configuration to create or update infrastructure, including running any provisioners defined.
Terminal
terraform apply
Expected OutputExpected
Terraform used the selected providers to generate the following execution plan. Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Terraform will perform the following actions: # aws_instance.example will be created + resource "aws_instance" "example" { + ami = "ami-0c55b159cbfafe1f0" + instance_type = "t2.micro" + provisioner "local-exec" { + command = "echo Hello from provisioner" } } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Enter a value: yes aws_instance.example: Creating... aws_instance.example: Provisioning with 'local-exec'... Hello from provisioner aws_instance.example: Creation complete after 10s [id=i-1234567890abcdef0] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Destroys all resources managed by Terraform, cleaning up the infrastructure.
Terminal
terraform destroy
Expected OutputExpected
Terraform used the selected providers to generate the following execution plan. Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy the following resources: # aws_instance.example will be destroyed - resource "aws_instance" "example" { - id = "i-1234567890abcdef0" -> null } Plan: 0 to add, 0 to change, 1 to destroy. Do you want to perform these actions? Terraform will destroy all your managed infrastructure. Enter a value: yes aws_instance.example: Destroying... aws_instance.example: Destruction complete after 5s Destroy complete! Resources: 1 destroyed.
Key Concept

If you remember nothing else from this pattern, remember: provisioners can cause unpredictable failures and should only be used when no other Terraform resource or provider feature can do the job.

Common Mistakes
Using provisioners for routine configuration tasks that can be handled by cloud-init or configuration management tools.
Provisioners run during apply and can fail, causing the whole Terraform run to fail and making infrastructure less stable.
Use cloud-init, user data scripts, or configuration management tools like Ansible or Chef instead of provisioners.
Relying on provisioners to fix resource dependencies or ordering.
Provisioners do not guarantee order beyond the resource they are attached to, leading to race conditions or partial failures.
Use Terraform resource dependencies and explicit depends_on to control resource creation order.
Ignoring errors from provisioners and assuming resources are fully configured.
Provisioner failures can leave resources in a partially configured state, causing runtime errors later.
Handle errors properly and consider retry mechanisms outside Terraform or avoid provisioners if possible.
Summary
terraform init prepares Terraform to manage infrastructure by downloading providers.
terraform apply creates resources and runs provisioners, but provisioners can cause failures.
terraform destroy cleans up resources, including those created with provisioners.