How to use AWS CLI or any Custom Command using Terraform | Raeveen Pasupathy

If you’re currently working on building your own Terraform Module, congratulations 🎉. It is evident that some build-in Terraform Modules…

How to use AWS CLI or any Custom Command using Terraform | Raeveen Pasupathy
Image courtesy of Hashicorp’s Terraform

How to use AWS CLI or any Custom Command using Terraform

If you’re currently working on building your own Terraform Module, congratulations 🎉. It is evident that some build-in Terraform Modules may not be sufficient for your business or personal use-cases — Hence, that is why you’re into building yourself one from scratch. Since the services offered by Cloud Infrastructure Providers such as AWS, GCP, Azure and more are evolving day-by-day, it may be required for you to alter or re-architect your existing solutions so it could be the best, in terms of Cost, Security, Efficiency, Reliability and more.

We all sometimes face issues when trying to create our own IaC Module, so it could be used by you or your Organization itself. It could be stressful, I totally hear you! There could be tons of ideas flowing through your head, and you’d be longing for an answer or ways to fix it. In this story, I’m here to show you an optimal way to completely eliminate the need of you to touch the CLI (Command Line Interface) on your Machine, unless it’s for running the terraform apply or terraform destroy command, well you could still throw these commands onto your GH repo as a pipeline and watch it roll.

So, once again, I’m here to introduce all of you on a most efficient way to run bash scripts using Terraform. It is actually simple, but sometimes we overlook things 😢.

Prerequisites

  • Terraform
  • AWS CLI

Solution

The null_resource acts as any TF resource does, but without doing anything. Weird? You can think of it as a resource so that you can attach provisioners as a last resort for any manual jobs that needs to be executed. And, this is where the local-exec provisioner comes in hand. It allows us to invoke any local shell command / script.

Example:

resource "null_resource" "say_hello_world" { 
  provisioner "local-exec" { 
    command     = "echo 'Hello, world'" 
    interpreter = ["/bin/bash", "-c"] 
  } 
}

However, it is also possible to extend the current script to a newer level.

resource "null_resource" "say_hello_world" { 
  triggers { 
    shell_hash = "${sha256(file("${path.module}/hello.sh"))}" 
  }
provisioner "local-exec" { 
    command     = "./hello.sh" 
    interpreter = ["/bin/bash", "-c"] 
  } 
}

NOTE:
Anything that runs under the local-exec provisioner can’t be stored in the TF state. If you need some changes to be made, make sure to include the triggers argument. Adding variables to triggers will prompt for new deployment on every variable’s value update.

Conclusion

So, what are you waiting for? Dive right into it!

An example could be found here.

#HappyDesigning
#HappyCoding
#HappyArchitecting