Skip to content

Instantly share code, notes, and snippets.

@nitrocode
Last active February 12, 2024 22:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitrocode/cf40a24054a66afe2b19ca54b7be5d68 to your computer and use it in GitHub Desktop.
Save nitrocode/cf40a24054a66afe2b19ca54b7be5d68 to your computer and use it in GitHub Desktop.
Template terraform provider for darwin arm

Template terraform provider for darwin arm

Provider registry.terraform.io/hashicorp/template v2.2.0 does not have a package available for your current platform, darwin_arm64

why

The templatefile function only works with files. If you're working with files then switch to templatefile.

The hashicorp/template provider's template_file data source works with template strings and files (converted to strings) but was archived/deprecated before creating an arm release forcing people to look into other options if using Apple M1 (based on ARM).

These instructions are for people who want to continue to use template strings.

One of the edge cases when this is necessary is when the template is passed in as a variable input, it contains variables that contain variable or other interpolated references, and interpolation must be done at runtime.

how

@gxben and @cloudposse forked the template provider and rebuilt it for arm architectures.

Using cloudposse/template (registry).

# versions.tf
terraform {
  required_providers {
    template = {
      source  = "cloudposse/template"
      version = "~> 2.2.0"
    }
  }
}

Or using gxben/template (registry).

# versions.tf
terraform {
  required_providers {
    template = {
      # Custom provider forks the original provider.
      # https://registry.terraform.io/providers/gxben/template/latest
      # Only difference is the darwin arm binary.
      source  = "gxben/template"
      # version has to be set explicitly instead of using a > sign
      version = "= 2.2.0-m1"
    }
  }
}

Here is a simple example.

# providers.tf
provider "template" {}

# variables.tf
variable "template" {
  default = {
    template = "my name is $${name}"
    vars = {
      name = "bob"
    }
  }
}

# data.tf
data "template_file" "greeting" {
  template = var.template["template"]
  vars     = var.template["vars"]
}

# outputs.tf
output "greeting" {
  value = data.template_file.greeting.rendered
}

returns

Changes to Outputs:
  + greeting = "my name is bob"

FAQ

Why can't I use simple string interpolation instead?

In the above example, yes this can be used instead.

output "greeting" {
  value = "my name is ${var.template["vars"]["name"]}"
}

This is a bit hard to scale and this template cannot be passed in as a variable due to interpolation denied in variable inputs.

The other way is to string together replace functions and that's also hard coded as this cannot easily scale up or down the replacements based on the inputs if reusing the code is desired.

How can you trust the fork?

Create your own fork by forking the original hashicorp/template repo and add the same commits as @gxben. He simply added a gorelease github action to release the arm binary. Make sure to bump the version and use a semantic version. gxben unfortunately used a -m1 suffic which is only compatible with a = 2.2.0-m1 qualifier.

Why won't hashicorp release a version with an arm binary?

Good question. Idk. They archived it and do not want to unarchive I suppose.

Why isnt there a templatestring function?

There were a couple attempts.

https://github.com/hashicorp/terraform/pulls?q=is%3Apr+is%3Aopen+templatestring

The best issue to track is hashicorp/terraform #28700

Why can't the template_file data source be copied into another provider?

The hashicorp team moved the terraform functions into the dreaded internal/ golang directory so the templated string portion can be recreated but it would be unable to run any of the terraform functions within the template. So the latest language version hclv2 sdk cannot be used which is why the cloudposse/awsutils provider could not be used for this which leads back to using a custom fork.

cloudposse/terraform-provider-utils#55

Are there other options?

Here are numerated alternative options to using the custom provider above

  1. Use raw string interpolation. This could work when the template isn't provided by a variable.
  2. String together multiple replace() functions for each use-case
    • This will be different for each use-case
  3. Find a way to create a file before terraform init so templatefile() function can be used instead of the deprecated provider
  4. Use the official provider or your own fork
    1. Use the deprecated provider without arm support
    2. Fork the deprecated provider yourself and rebuild for m1 instead of using gxben's version
      • You will have to maintain this yourself

How to convert an existing terraform dir to use the m1 provider

Add the cloudposse versions.tf code from above and then run the following command

terraform state replace-provider hashicorp/template cloudposse/template -auto-approve

alternative

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment