Skip to content

Commit

Permalink
new post!
Browse files Browse the repository at this point in the history
  • Loading branch information
parsec committed Feb 17, 2023
1 parent 27b018d commit b53ab60
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions content/posts/packer-vars.md
@@ -0,0 +1,135 @@
---
author: "parsec"
date: 2023-02-16
linktitle: Packer Variable Files, and How to Write Them
type:
- post
- posts
title: Packer Variable Files, and How to Write Them
subtitle: A Missing Docs Mystery
weight: 10
series:
- "Missing Docs"
tags:
- packer
- gitops
---

---

## Backstory

So, I had to create some AMIs.

"Sure, no big deal", I thought, "I'll use Packer!"

The Packer templates themselves aren't too bad. It kind of sucks to parse through Hashicorp's documentation, but sometimes I just need some really explicit instructions. So I write my templates, they work after some debugging, life is good.

New problem: I need to set passwords for various accounts on these AMIs. Time to use some variables!

Except... [the Hashicorp documentation](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/variables#assigning-values-to-input-variables) on variables is... a little lacking, to be honest. It explains under the **Standard Variable Definitions Files** heading that the format should look like such:

```hcl
image_id = "ami-abc123"
availability_zone_names = [
"us-east-1a",
"us-west-1c",
]
```

Easy enough, right? It's just some variables being set in a separate file, then you bring it in with a command like so:

```hcl
$ packer build -var-file="testing.pkrvars.hcl"
Error: Failed preparing provisioner-block "shell" ""
on jenkins.pkr.hcl line 44:
(source code not available)
jenkins.pkr.hcl:46,27-40: Unsupported attribute; This object does not have an
attribute named "jenkins_pass"., and 3 other diagnostic(s)
```

So... that error points us to the **Important do not skip** block in the docs:

> Important: Unlike legacy JSON templates the input variables within a variable definitions file must be declared via a variables block within a standard HCL2 template file *.pkr.hcl before it can be assigned a value. Failure to do so will result in an unknown variable error during Packer's runtime.
Okay, sure... I was a little confused here, to be honest. It sounded like I should be changing the name of the variable file to something like `vars.pkr.hcl`, but that didn't work. Then it just asked me to set up `variables` blocks. And putting everything in the variable definition files in a `variables` block didn't work, so what gives?

## The Solution

Now that I read back on it, it makes sense. It did not when I was looking at it. So, dear reader, I hope this will help!

### Defining Your Variables

So now we have some variable definitions; how do we get those values into our Packer templates?

`vars.pkr.hcl` - it can technically be named anything, but this name means I don't get it confused with other stuff.

```hcl
variable "web_pass" {
type = string
default = ""
sensitive = true
}
variable "user_pass" {
type = string
default = ""
sensitive = true
}
```

Notice that we left the `default` value set to `nil`. Also, since my use case was for passwords, I set the `sensitive` flag. This means when the variable is consumed, it won't be printed in the console or log.

### The Variable Definition File

This file should be named something with the extension `.pkrvars.hcl`. If you want it to be really fancy, as long as you're only using one `pkrvars` file you can do `.auto.pkrvars.hcl`, and Packer will automagically pick up the variables file.

Your file should look something like this:

```hcl
var1 = "hello"
var2 = 12345
var3 = ["a","b","c"]
...
```

Now, this file's purpose is to assign values to existing variables, hence the warning they gave us. So, to make this work for us, we *also* need to define the variables in some kind of `.pkr.hcl` file. For me, this was just a `vars.pkr.hcl` file, like we discussed above.

So, we have two pieces of the puzzle now. Variable declarations, and variable definitions. These definitions will overwrite the default value of our declared variables. But how do we consume them?

### Consuming Variables in Packer Templates

To call a variable in packer, you encapsulate it in `${var.x}`. Not too bad, right?

Example:

```hcl
... ${var.var1}
... ${var.var2}
... ${var.var3}
```

This part is actually way easier than it sounds, especially if you used [Auto-loaded Variable Definitions Files](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/variables#auto-loaded-variable-definitions-files). If you did, when you run `packer build .` it should Just Work.

If not, you'll want to specific your variables file like so:

```shell
$ packer build -var-file=./vars.pkrvars.hcl

[build_output_here]
```

## In Closing

And now, assuming nothing weird happened, you should have a Packer template consuming custom variables at runtime! The beautiful thing about doing vairables this way instead of `locals` is that they can be overwritten at runtime. So, for example:

```hcl
packer build -var="key":"value" .
```

This would overwrite whatever variable name you give it (or create a new one if it doesn't exist, at runtime).

Pretty nifty, right? I think so. But I'll probably be writing a few more of these in the future... These docs could use some help, and if I'm using the tools anyway, I might as well help other people use them :)

0 comments on commit b53ab60

Please sign in to comment.