Sling Academy
Home/DevOps/Terraform: How to execute shell/bash scripts

Terraform: How to execute shell/bash scripts

Last updated: February 03, 2024

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.

Next Article: Terraform: How to sync files and folders

Previous Article: How to filter a map in Terraform

Series: Terraform Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide