Skip to main content

Locals and Functions

This file is used to define specific values that can be based on a variable or build another one.

Observe the block below. For example, the timestamp variable receives a value at runtime from a function. Extra tags was defined based on a variable.

I like to separate this file to avoid polluting the main file. Usually interpolation to generate a new variable I prefer to do in this file and reference these variables in main.pkr.hcl in a simple and more readable way.

Think of locals as your variable manipulation space.

The file below is exactly what we will use in our project.

locals {
timestamp = formatdate("DD-MMM-YYYY-hh-mm-ZZZ", timestamp())

extra_tags = {
Name = var.project_name
Environment = var.environment
}
}

A variable is referenced as var.itsname and a local variable is referenced as local.itsname.

Taking advantage of this moment, it's good to talk about functions that help a lot to manipulate variables. Follow the documentation and see everything we have ready to use.

If you are already familiar with Terraform, it's the same thing.

List of the ones I use most:

  • env: Transform an environment variable into an input value.

    env("AWS_DEFAULT_REGION")
  • vault: Fetches a value from a vault vault, as long as you are logged in.

    vault("/secret/data/hello", "foo")
  • join: Joins several strings with a separator, great for forming names.

    join("_", [var.project_name, var.environment, var.region]) \
    centos_dev_us-east-1
  • split: Separates a string through a delimiter and delivers a list of strings. It's the inverse of join

  • lower, upper and title: Converts all letters to all lowercase, uppercase or only the first letter uppercase in the case of title.

    lower("HELLO") \
    hello
  • regex and regex_replace: Two wildcard functions that for those who know how to use regex, replace many other functions

  • coalesce: and coalestlist: From a list of arguments takes the first non-null.

  • concat: Combines two lists into one list

    concat(["a", ""], ["b", "c"]) \
    ["a","","b","c",]
  • contains: Within a list checks if an item exists and returns true or false.

    contains(["a", "b", "c"], "a")
    true
  • Index and element: They are the inverse of each other. element() you pass the list and the index it returns the value at the list position. index() you pass the list and the value it returns at which position of the list it is.

    element(["a", "b", "c"], 1) \
    b
    index(["a", "b", "c"], "b") \
    1
  • lookup: Retrieves the value of a single element from a map, given its key. If the provided key does not exist, the provided default value will be returned.

    lookup({a="ay", b="bee"}, "a", "DefaultValue") \
    ay
    lookup({a="ay", b="bee"}, "c", "DefaultValue")
    DefaultValue
  • merge: Takes an arbitrary number of maps and returns a single map that contains a merged set of elements from all maps. If more than one given map defines the same key, the one that is later in the argument sequence will take precedence.

    merge({"a"="b", "c"="d"}, {"e"="f", "c"="z"}) \
    {"a" = "b" "c" = "z" "e" = "f"}
  • jsondecode and yamldecode: Are functions that also have encode, but usually we have the file and want to decode.

  • file: reads the contents of a file passed in the relative path. fileexists() is another function that returns true or false.

    file("${path.folder}/hello.txt") \
    Hello World
  • timestamp: returns the date and time. Usually used with formatdate to customize the time according to what you need.

There are many others, worth checking out.

Extra

path.cwd: the directory from which Packer was started.

path.root: the directory of the input HCL file or the input folder.