top of page

Day 12: Terraform Provisioners

Jan 11

3 min read

0

1

0

Welcome to Day 12 of our 30-day Terraform and Infrastructure as Code (IaC) series! Today, we’re diving into Terraform Provisioners—tools that allow you to execute scripts or commands on your resources once they’re created (or before they’re destroyed).


Introduction

Terraform Provisioners can bridge the gap between simply spinning up a resource (e.g., a virtual machine) and configuring it as needed. They act as a mechanism to run shell commands, or even specialized scripts, after your resource is up and running. This can help install packages, configure services, or run initialization tasks. However, provisioners should be used carefully and sparingly, as heavy reliance on them might complicate your infrastructure code and make it less portable.


Why Provisioners Matter

  1. Configuration Bootstrap: They allow you to run setup scripts to install or configure software on newly launched machines.

  2. Simple Automation: You can automate tasks that might otherwise require manual login and setup.

  3. Integration: In certain scenarios, provisioners can integrate well with other config management tools (e.g., Ansible, Chef, or Puppet).

  4. Cleanup Tasks: There’s also the concept of “destroy provisioners” which run commands before a resource is destroyed, allowing you to perform any final housekeeping.


Key Concepts and Components

1. Local and Remote Provisioners

  • Local Exec: Runs commands on your local machine (where Terraform is running).

  • Remote Exec: Runs commands on the target resource (e.g., an EC2 instance). For remote exec to work, you typically need SSH or WinRM access to the instance.


2. Connection Blocks

For remote exec, you’ll configure a connection block, specifying how Terraform will connect to the remote machine. This often includes:

  • host: IP address or hostname of the instance.

  • user: Username with which to authenticate.

  • private_key or password: Credentials for connecting.


3. Types of Provisioners

  • file: Copy a local file to the target resource.

  • remote-exec: Execute commands on the remote resource over SSH or WinRM.

  • local-exec: Run commands on the local machine.

  • null_resource: A special resource in Terraform used to run provisioners without tying them to a specific infrastructure resource.


4. When to Use Provisioners

  • Bootstrapping: Installing initial packages or configuring system settings before handing off to a more robust configuration management tool.

  • Legacy Environments: Sometimes you might not have a fully automated pipeline, and you just need to run a quick script.


Code Snippet Example

Below is a basic example of using a remote-exec provisioner on an AWS EC2 instance:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update -y",
      "sudo apt-get install -y nginx",
      "sudo systemctl start nginx",
      "sudo systemctl enable nginx"
    ]
    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file("~/.ssh/id_rsa")
      host        = self.public_ip
    }
  }
  tags = {
    Name = "WebServer"
  }
}

Explanation

  • resource "aws_instance" "web": Creates an EC2 instance.

  • provisioner "remote-exec": Runs commands directly on the instance.

  • inline: A list of shell commands executed sequentially.

  • connection: Specifies SSH details—Terraform uses these to connect remotely.


Real-World Applications

  • Quick Setup: Spin up a test server and install a web server (like NGINX) in seconds.

  • Proof-of-Concepts: Rapidly prototype and test cloud configurations without managing another configuration management tool.

  • Minimal Configuration: In ephemeral or short-lived environments, you might rely on Terraform provisioners instead of heavier tooling.


Practical Tips

  1. Use Provisioners Sparingly: The more logic you embed in provisioners, the harder your configuration might become to maintain. Consider dedicated tools like Chef, Ansible, or Puppet for complex setups.

  2. Error Handling: If a provisioner fails, Terraform may mark the resource as “tainted,” which can lead to re-creation on the next apply. Ensure your scripts handle errors gracefully.

  3. Order: If you have multiple provisioners, remember they run in the order they’re declared.

  4. Security: Be cautious with credentials and ensure they’re stored securely (e.g., environment variables, Vault).

  5. Destroy Provisioners: Use when = destroy to clean up data or configurations before Terraform removes a resource.


    Call to Action

    Try adding a simple remote-exec provisioner to a basic EC2 or VM resource today. Experiment with installing a package or configuring a service. Then, destroy the resource and observe how Terraform handles a resource that includes a provisioner. Pay attention to the logs and any error messages—it’s a great way to get a feel for how Terraform orchestrates provisioning logic.


    Conclusion

    Terraform Provisioners can be a convenient way to bootstrap or configure resources post-provisioning. While they shouldn’t replace a dedicated configuration management system for complex tasks, they’re invaluable for quick or lightweight environment setups. By practicing with provisioners, you’ll gain greater flexibility in defining end-to-end infrastructure with Terraform. Stay tuned for Day 13, where we’ll continue exploring more advanced Terraform capabilities!


Jan 11

3 min read

0

1

0

Comments

Share Your ThoughtsBe the first to write a comment.
bottom of page