Terraform: How to execute shell/bash scripts

Updated: February 3, 2024 By: Guest Contributor Post a comment

Overview

Terraform, an open-source infrastructure as code software tool by HashiCorp, provides a consistent CLI workflow to manage hundreds of cloud services. Terraform codifies cloud APIs into declarative configuration files. However, situations arise when executing a shell or bash script within Terraform is necessary, either to bootstrap resources, configure settings, or clean up resources. This tutorial covers how to execute shell/bash scripts in Terraform, from basic to more advanced examples.

Prerequisites:

  • Basic understanding of Terraform
  • Terraform installed on your machine
  • Basic Shell/Bash scripting knowledge

Basic Execution Using null_resource

The null_resource in Terraform is a versatile tool for executing scripts. Here’s a straightforward example:

resource "null_resource" "example" {
  provisioner "local-exec" {
    command = "echo Hello, World!"
  }
}

This script simply prints “Hello, World!” on your console. The local-exec provisioner invokes a local executable, in this case, echo. Applying this Terraform configuration results in:

Applying plan...

null_resource.example: Creating...
null_resource.example: Provisioning with 'local-exec'...
null_resource.example (local-exec): Executing: [/bin/sh -c "echo Hello, World!"]
null_resource.example (local-exec): Hello, World!
null_resource.example: Creation complete after 0s

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Advanced Usage: Passing Variables and Output

Let’s take it a step further by incorporating variables and capturing the output:

variable "greeting" {
  description = "Greeting to display"
  type        = string
  default     = "Hello, Terraform!"
}

resource "null_resource" "advanced_example" {
  provisioner "local-exec" {
    command = "echo ${var.greeting} > greeting.txt"
    environment = {
      GREETING = var.greeting
    }
  }
}

This script writes the greeting message to a file named greeting.txt. Additionally, it demonstrates how to pass environment variables to your script.

Executing Scripts From Files

Often, you’ll have bash scripts stored as files. Here’s how to execute a script file:

resource "null_resource" "script_file" {
  provisioner "local-exec" {
    command = "bash ${path.module}/setup.sh"
  }
}

Assuming setup.sh is a script in the same directory as your Terraform script, it will be executed. Ensure your bash script is executable (chmod +x setup.sh).

Using remote-exec for Remote Execution

In scenarios where you need to execute a script on a remote server provisioned by Terraform, you can utilize the remote-exec provisioner. An example:

resource "aws_instance" "web" {
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y nginx",
    ]

    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file("~/mykey.pem")
      host        = self.public_ip
    }
  }
}

This example updates the package lists and installs Nginx on an AWS EC2 instance. Make certain your EC2 instance allows SSH access from your IP address.

Conclusion

Executing shell/bash scripts in Terraform extends its functionality, enabling custom setup, configuration, or cleanup steps as part of your infrastructure deployment process. This article detailed methods from simple echo commands to more complex scenarios involving scripts and remote execution. Mastering these techniques can significantly enhance your Terraform projects.