Skip to content

Instantly share code, notes, and snippets.

@angrycub
Last active September 8, 2022 15:12
Show Gist options
  • Save angrycub/bdcae9f2655bd527d74610e780bdcd6a to your computer and use it in GitHub Desktop.
Save angrycub/bdcae9f2655bd527d74610e780bdcd6a to your computer and use it in GitHub Desktop.
Nomad `var` Shenanigans

Nomad Variable CLI Shenanigans

First steps

Create a variable as key-value pairs.

nomad var put my/first/var user=me password=passW0rd thoughts=awesome 

Get a variable.

nomad var get my/first/var
Namespace   = default
Path        = my/first/var
Create Time = 2022-09-01 15:40:25.600373 -0400 EDT
Check Index = 1457

Items
password = passW0rd
thoughts = awesome
user     = me

Get the variable in a more machine friendly format.

nomad var get -out=pretty-json my/first/var
{
  "Namespace": "default",
  "Path": "my/first/var",
  "CreateIndex": 1457,
  "ModifyIndex": 1457,
  "CreateTime": 1662061225600373000,
  "ModifyTime": 1662061225600373000,
  "Items": {
    "password": "passW0rd",
    "thoughts": "awesome",
    "user": "me"
  }
}

While the default of the nomad var put command is not to output the variable, you can set the -out flag to have it output the variable that it created.

nomad var put -out pretty-json my/second/var status="getting the flow"
{
  "Namespace": "default",
  "Path": "my/second/var",
  "CreateIndex": 1468,
  "ModifyIndex": 1468,
  "CreateTime": 1662061717905426000,
  "ModifyTime": 1662061717905426000,
  "Items": {
    "status": "getting the flow"
  }
}

Updating a variable

Using simple key values

Using command piping, you can use the nomad var get and nomad var put to update a variable in place.

nomad var get my/second/var | \
  nomad var put -out=pretty-json - status="getting updates"
{
  "Namespace": "default",
  "Path": "my/second/var",
  "CreateIndex": 1468,
  "ModifyIndex": 1479,
  "CreateTime": 1662061717905426000,
  "ModifyTime": 1662062162982630000,
  "Items": {
    "status": "getting updates"
  }
}

You can add more Items to a variable in the same way.

nomad var get my/second/var | \
  nomad var put -out=pretty-json - new=niiice 
{
  "Namespace": "default",
  "Path": "my/second/var",
  "CreateIndex": 1468,
  "ModifyIndex": 1483,
  "CreateTime": 1662061717905426000,
  "ModifyTime": 1662062312002302000,
  "Items": {
    "new": "niiice",
    "status": "getting updates"
  }
}

To remove an item, set the Item key's value to ""

nomad var get my/second/var | \
nomad var put -out=pretty-json - new="" 
{
  "Namespace": "default",
  "Path": "my/second/var",
  "CreateIndex": 1468,
  "ModifyIndex": 1486,
  "CreateTime": 1662061717905426000,
  "ModifyTime": 1662062477731007000,
  "Items": {
    "status": "getting updates"
  }
}

However, you can not remove all of the Items in a variable. To completely remove a variable, you should use the nomad var purge command.

Using references as values

In the previous examples, you might have noticed that when performing the updates with pipelines that the commands included a hyphen character for the path. This character is a reference to standard input (STDIN). Here are the possible references and where they might occur.

Reference Path Data Value Notes
- ✅(1) ✅(1) This reference can only be used once
(1) When used as the path or data parameter, the format must be supplied using the -in flag.
@«filename» ✅(2) ✅(2) (2) When used as the path or data parameter, the file extension must be .hcl or .json OR the format must be supplied using the -in flag.

For the next few examples, create a file named items.json using the following command.

echo '{"Items":{"item1":"value1", "item2":"value2"}}' > items.json

You can use this in as a file reference as the data parameter to create a variable with the items contained in the file.

nomad var put -out=pretty-json my/third/var @items.json
{
  "Namespace": "default",
  "Path": "my/third/var",
  "CreateIndex": 1516,
  "ModifyIndex": 1516,
  "CreateTime": 1662064037167150000,
  "ModifyTime": 1662064037167150000,
  "Items": {
    "item1": "value1",
    "item2": "value2"
  }
}

You can also pass key-value pairs when using a file reference for the variable data.

nomad var put -out pretty-json my/fourth/var @items.json item2="overridden"  
{
  "Namespace": "default",
  "Path": "my/fourth/var",
  "CreateIndex": 1521,
  "ModifyIndex": 1521,
  "CreateTime": 1662064246116265000,
  "ModifyTime": 1662064246116265000,
  "Items": {
    "item1": "value1",
    "item2": "overridden"
  }
}

You can even delete items from the data reference before they are committed to the variable's data.

nomad var put -out pretty-json my/fifth/var @items.json item2=""
{
  "Namespace": "default",
  "Path": "my/fifth/var",
  "CreateIndex": 1524,
  "ModifyIndex": 1524,
  "CreateTime": 1662064354522447000,
  "ModifyTime": 1662064354522447000,
  "Items": {
    "item1": "value1"
  }
}

Check and set

You might have noticed in the previous examples that each command created a different variable. The nomad var put command defaults to a "check and set" strategy when performing updates. This strategy requires that the incoming variable has the same Modify Index as the variable on the server, which helps to reduce the danger of concurrent modifications to a variable's value

In the earliest examples in this guide, the output of nomad var get was piped into the nomad var put command. This provides the nomad var put command with the current ModifyIndex of the variable on the server.

There are two options for directly updating a variable without fetching the value as part of the update process.

  • Use the -check-index flag

  • Use the -force flag

What happens if I forget?

If your request does not have the proper ModifyIndex, you will receive a cas conflict error. The error text will show the ModifyIndex you passed and the server-side ModifyIndex.

nomad var put my/fifth/var item1="updated"
Error creating variable: cas conflict: expected ModifyIndex 0; found 1524

Using -check-index

You can provide the expected ModifyIndex with the -check-index flag. Recall from earlier, the output generated when you put my/fifth/var contained a ModifyIndex value. The sample output in this guide has a ModifyIndex of 1524.

Use the correct check-index value based on the output generated from when you created my/fifth/var and set item2="new"

nomad var put -check-index 1524 my/fifth/var item2="new"
{
  "Namespace": "default",
  "Path": "my/fifth/var",
  "CreateIndex": 1524,
  "ModifyIndex": 1540,
  "CreateTime": 1662064354522447000,
  "ModifyTime": 1662065159344723000,
  "Items": {
    "item2": "new"
  }
}

Note: When putting a variable without a fetch, the Items array is OVERWRITTEN with the new values. If you want to update the variable's existing Items, you should get the existing state first—either as piped data or to a file that you then reference in the put.

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