Terraform OS Detection



In some rare cases it is important to know on which Operating System Terraform is being executed. Since there is (yet) no functionality that solves this, this small hack can help in these situations.

It is important to note that once there hopefully will be an official function by Terraform this hack will become unnecessary.

The situation is the following: We have a functionality in our Terraform code which runs perfectly fine on our build servers which run on Linux.

However, some users run the code on Windows where it fails.

We have found a fix for this, but now we need Terraform to know whether or not it is being run on Linux or Windows.

Let’s get into it.

Create a printf.cmd file with this content:

@echo off
echo {"os": "Windows"}

We want Terraform to run this file when under Windows which clearly returns to Terraform that we are on Windows. Linux should somehow ignore this file. More on that now:

Create a data.tf file with this content:

data "external" "os" {
  working_dir = path.module
  program = ["printf", "{\"os\": \"Linux\"}"]
}

Now comes the magic:

We created a external data resource in Terraform which allows us to run commands outside of Terraform.

working_dir sets the working directory of the program. It is required for this scenario and tells Windows that it should look for a program here in this folder.

program This is the essential hack: Under Windows the OS will look for an executable called printf in the working directory, which it finds as printf.cmd. Remember Windows ignores file extensions! It will pass the second argument ({\"os\": \"Linux\"}) of program = ["printf", "{\"os\": \"Linux\"}"] to the executable printf.cmd, which simply ignores them because it does not expect any. Instead, printf.cmd will simply return "{os": "Windows}" as we defined in the first code snippet.

Now here is the catch: Linux will before looking for a program printf in the working directory look for a program called printf under its binaries. Et voilà Linux has its binary printf which simply prints what you give it as an argument (printf). As we have defined here (program = ["printf", "{\"os\": \"Linux\"}"]) we give to printf the argument {\"os\": \"Linux\"} and therefore it will print exactly that: That we are under Linux, ignoring the printf.cmd file in the working directory.

Now all that is left is to access the results:

Create a locals.tf file with this content:

locals {
  os = data.external.os.result.os
  check = local.os == "Windows" ? "We are on Windows" : "We are on Linux"
}

As you can see with defining the local variable os we execute our data resource data "external" "os" from before and by using result we can get its result. os by now should be either Windows or Linux. With check we can then check if the underlying OS is either Windows or Linux.

In the scenario it is now possible to detect on which OS Terraform is being run and we can implement the fix.

Credits:

Janos Pasztor for the idea and concept.

To my colleague Philipp , who impresses me with his sharpness every other day and with whom I came up with this solution.


tl;dr:

printf.cmd:

@echo off
echo {"os": "Windows"}

data.tf:

data "external" "os" {
  working_dir = path.module
  program = ["printf", "{\"os\": \"Linux\"}"]
}

locals.tf:

locals {
  os = data.external.os.result.os
  check = local.os == "Windows" ? "We are on Windows" : "We are on Linux"
}

Similar Posts You Might Enjoy

Containers! Containers everywhere!

The newly introduced ECS Anywhere feature lets us use our existing resources as Compute Power in Amazon ECS. Let’s talk about some basics and see how ECS Anywhere can be set up in Terraform! - by Antonia Berg

(Prevent) Hacking into a CloudService - About security, ECS and terraform AWS UserGroup Hannover Online Meetup Feb, 4th 2021

Yoni: Oftentimes, when we think about protecting resources in the cloud, we immediately think about the typical ways in - via public-facing applications or abuse of credentials. In this talk, we will look at one additional way: through the work unit parameters of a service. During the development of Indeni’s Cloudrail SaaS product, Yoni was responsible for trying to find ways to hack into the service. One of the ways he found, raises questions about how secure ECS workloads really are. - by Yoni Leitersdorf , Gernot Glawe , Malte Walkowiak

Enhancing Security in Terraform with AWS Secrets Manager

Keeping track of your passwords is already challenging in your personal life. It can be more difficult when you want to build and deploy secure applications in the cloud. Today we’ll show you a few ways of managing secrets in your Terraform deployment. We’ll teach you about common pitfalls like the random_password resource and more appropriate alternatives. - by Alexey Vidanov