jkisolo.com

Mastering Terraform: Understanding Provisioners and Null Resources

Written on

Introduction to Provisioners

In Terraform, provisioners serve a distinct purpose separate from providers. They enable the execution of commands or scripts on either a local or remote machine and facilitate the transfer of files from a local environment to a remote one. Provisioners are encapsulated within resources, meaning you must include a provisioner block within the specific resource to utilize it.

It's important to note that while provisioners cannot reference their parent resource by name, they can utilize the self object, which represents that resource. Provisioners are regarded as a last resort, as they do not conform to Terraform's declarative model.

Three Main Types of Provisioners

There are three primary types of provisioners:

  1. local-exec (should be used alongside a connection block)
  2. remote-exec (should be used alongside a connection block)
  3. file (should also be used with a connection block)

All provisioners come with two notable options: when and on_failure. By default, provisioners run during resource creation, but they can also be configured to execute upon resource destruction if your scenario requires it. The on_failure option defaults to failing the apply process if the provisioner encounters an error, but it can be adjusted to continue despite failure.

From personal experience, I've observed that provisioners may fail unexpectedly or seem to operate without yielding the desired results. Nevertheless, understanding how to implement them is crucial, as there may be instances where no alternatives exist.

Exploring Null Resources

Before diving deeper into each provisioner type, let’s discuss null resources. A null resource is essentially a construct that does not generate anything independently. However, it can be employed to define provisioner blocks and includes a "trigger" attribute, which facilitates the recreation of the resource, thus allowing the provisioner block to execute again if the trigger condition is met.

Local-Exec Block

The local-exec block, as the name implies, executes a script on your local machine. Besides the when and on_failure options, several other parameters can be specified:

  • command — the command to run (mandatory)
  • working_dir — the directory where the command runs
  • interpreter — the interpreter to utilize (e.g., /bin/bash; Terraform determines this based on your OS)
  • environment — key/value pairs representing the environment

By using a null resource, you can execute various scripts before or after applying a specific resource by utilizing depends_on (which will be elaborated on in a future article).

Connection Block

Before examining the other two provisioners—remote-exec and file—let’s take a moment to grasp the connection block. To execute commands or copy files on a remote VM, establishing a connection is necessary. Connection blocks can support both SSH and WinRM, making it easy to connect to Linux or Windows VMs. You can even connect through a bastion host or proxy, but here’s a simple connection block example for a Linux VM:

Example of a connection block for a Linux VM

File Provisioner

The file provisioner is specifically designed for transferring files from your local machine to a remote VM. It supports three arguments:

  • source — the file to be copied
  • content — the direct content to be transferred to the destination
  • destination — the target location for the file

As previously mentioned, the file provisioner necessitates a connection block to function correctly. Let’s look at an example involving an EC2 instance.

Remote-Exec Provisioner

The remote-exec provisioner allows you to execute commands or scripts on a remote VM. It accepts the following arguments:

  • inline — a list of commands to run on the VM
  • script — a single script to execute on the VM
  • scripts — multiple scripts to run on the VM

Only one of these arguments should be provided, as they cannot be used simultaneously. Similar to the file provisioner, you'll need to include a connection block.

To implement the code described above, simply replace the null resource for copying files on the VM with this one, and you’ll be set. Ensure you have a security rule in place that permits SSH access in your security group.

Though I don't typically advocate for the use of provisioners, it's essential to recognize that they can sometimes be a necessary, albeit imperfect, solution.

In the next article, we will explore how to create multiple resources of the same type and conditionally assign values to specific parameters. We will also delve into the application of complex variables, so stay tuned!

Key Resources for Further Learning

  • Local-Exec Documentation
  • Remote-Exec Documentation
  • File Provisioner Documentation
  • Null Resource Overview

Understanding Terraform Null Resources and Their Usage

This video explains the concept of Terraform's null_resource and how to effectively utilize it in your projects.

Exploring Terraform's Null Resource in Depth

This video provides an in-depth look at Terraform's null resource, highlighting its practical applications.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Harnessing the Impact of Positivity in Business Leadership

Discover how a positive leadership style can transform organizational culture, boost employee motivation, and drive business success.

Understanding Caffeine: The Science Behind Your Daily Boost

An exploration of how caffeine influences the brain, its effects on energy levels, and the science behind tolerance and withdrawal.

Understanding Saudi Arabia's Workforce Crisis and Aspirations

Exploring the employment challenges in Saudi Arabia, the reliance on oil, and the government's strategies for economic reform.