Terraform Provisioners Documentation
Introduction
Provisioners in Terraform allow you to execute scripts or commands on a local or remote machine as part of the resource creation, modification, or destruction process. They can be used for bootstrapping, configuration management, or any other setup task that needs to be run after the resource is provisioned.
Types of Provisioners
Local-Exec Provisioner
The local-exec
provisioner executes a command locally on the machine running Terraform. This can be useful for tasks that need to interact with the local environment or when running Terraform on a local machine.
Example
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
provisioner "local-exec" {
command = "echo ${self.public_ip} > instance_ip.txt"
}
}
Remote-Exec Provisioner
The remote-exec
provisioner allows you to execute commands on a remote machine, typically the resource being provisioned. It requires a connection configuration to specify how to connect to the remote machine.
Example
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
key_name = "my-key"
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx",
]
}
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/my-key.pem")
host = self.public_ip
}
}
Null Resource Provisioner
The null_resource
provisioner is a way to define provisioners without associating them with a specific resource. This can be useful for orchestrating complex workflows or for tasks that do not map directly to a single resource.
Example
resource "null_resource" "example" {
provisioner "local-exec" {
command = "echo 'Hello, World!'"
}
}
Provisioner Configuration
Connection Block
When using remote-exec
, you need to define a connection
block that specifies how to connect to the remote resource. This includes details such as the connection type, user, and authentication method.
Example
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/my-key.pem")
host = aws_instance.example.public_ip
}
On-Failure Behavior
Provisioners can be configured to control what happens if the provisioner fails. The default behavior is to fail the resource creation, but you can change this using the on_failure
argument.
Example
provisioner "local-exec" {
command = "exit 1"
on_failure = "continue"
}
When Configuration
Provisioners can be set to run at different stages of the resource lifecycle: create
(default) or destroy
.
Example
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
provisioner "local-exec" {
command = "echo 'Creation time provisioner'"
}
provisioner "local-exec" {
when = "destroy"
command = "echo 'Destruction time provisioner'"
}
}
Common Use Cases
Bootstrapping Instances
Provisioners can be used to bootstrap instances with necessary software and configurations. For example, installing web servers, configuring databases, or setting up application environments.
Running Configuration Management Tools
Provisioners can invoke configuration management tools like Ansible, Chef, or Puppet to further manage the resource after it's provisioned.
Executing Custom Scripts
For tasks that do not fall under traditional infrastructure management, custom scripts can be run to perform specialized operations.
Best Practices
- Idempotency: Ensure that the commands or scripts you run via provisioners are idempotent, meaning they can be run multiple times without causing adverse effects.
- Error Handling: Use the
on_failure
configuration wisely to handle errors gracefully. - Security: Securely manage and pass sensitive data, such as SSH keys and passwords, to avoid exposing them in your Terraform configurations.
- Debugging: Use verbose logging and detailed error messages to make troubleshooting easier.
Conclusion
Provisioners in Terraform are powerful tools that extend the functionality of your infrastructure-as-code by allowing custom commands and scripts to be run during the resource lifecycle. Understanding how to configure and use them effectively can help automate complex workflows and ensure your infrastructure is provisioned correctly and consistently.
For more detailed information, refer to the Terraform Provisioners Documentation (opens in a new tab).