# Define variables across job definitions

**URL:** <https://discuss.hashicorp.com/t/define-variables-across-job-definitions/25284>\
**Category:** Nomad\
**Created:** [June 10, 2021, 8:30am UTC](https://discuss.hashicorp.com/t/define-variables-across-job-definitions/25284 "2021-06-10T08:30:04Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![bert2002](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/bert2002/32/16382_2.png) [@bert2002](https://discuss.hashicorp.com/u/bert2002)\
**Post date:** [June 10, 2021, 8:30am UTC](https://discuss.hashicorp.com/t/define-variables-across-job-definitions/25284/1 "2021-06-10T08:30:04Z")

</div>

Hi,  
we are running a nomad cluster with multiple jobs on it. These jobs are defined in separate files. E.g.

```auto
job1.nomad
job2.nomad

```

The job description looks like this:

```auto
job "job1" {

  datacenters = var.datacenters
  type = "service"

  group "job1" {

    network {
      mode = "bridge"
    }

    task "job1" {
      driver = "docker"

      config {
        image = var.docker_image_job1
      }
    }

  }
}

variable "datacenters" {}
variable "docker_image_job1" {}
variable "docker_image_job2" {}

```

Its a simple docker job which is using two variables for one job (datacenters and jobX). `job1` is using docker\_image\_job1 and `job2` (another file) is using `docker_image_job1`.

Normally you would only define the variable of the same job in the job file, but we are using a var file to set the value of the variables. This looks like this (`version.vars`):

```auto
datacenters = ["local"]
docker_image_job1 = "somedocker:1.2.3"
docker_image_job2 = "somedocker:1.2.4"

```

The problem with `version.vars` is when we are using it when deploying the job it always expects the defined variable for each job. E.g.

```auto
nomad job plan -var-file="version.vars" job1.nomad

```

This works when all defined variables are in the nomad job file and in the variables file.

The problem is that we have more than 50 jobs and we dont want to maintain 50 variables in each job file (which will not be used) to satisfy `version.vars`.

I was looking for options to e.g. include a file that contains the variable definitions and that can be injected into job files, but I could not find any solution yet.

Is there any way to do this or is my solution not suitable at all?

Thanks,  
bert

---

<div class="post-metadata">

**Author:** ![runeron](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/runeron/32/19832_2.png) [@runeron](https://discuss.hashicorp.com/u/runeron)\
**Post date:** [June 10, 2021, 5:43pm UTC](https://discuss.hashicorp.com/t/define-variables-across-job-definitions/25284/2 "2021-06-10T17:43:53Z")

</div>

You could use terraform & for\_each for the nomad jobs. E.g. define your map or array, and loop through it.

Ex. if using only different images

```auto
#nomad.tf
locals {
  jobs = {
    "job1" = "dockerimage1",
    "job2" = "dockerimage2",
    "job3" = "dockerimage3",
  }
}

resource nomad_job "JOB" {
  for_each = local.jobs

  jobspec = templatefile("myjobtemplate.nomad",{
    NAME = each.key
    IMAGE = each.value
  })
}

```

Then you use the variables in your job-template where you want to:

```auto
#myjobtemplate.nomad
job "${NAME}" {
...
image = "${IMAGE}"
...
}

```

You can pass any number of variables to the template this way. I usually pass two maps; required & optional values.

Probably possible using levant as well, but i use terraform.

Sorry if the syntax is not exact (and for not providing links to resources), but typing on mobile.

---

<div class="post-metadata">

**Author:** ![angrycub](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/angrycub/32/925_2.png) [@angrycub](https://discuss.hashicorp.com/u/angrycub)\
**Post date:** [June 11, 2021, 12:32am UTC](https://discuss.hashicorp.com/t/define-variables-across-job-definitions/25284/3 "2021-06-11T00:32:10Z")

</div>

Hey Bert,

This is a great question, and it got me in testing and writing mode. I did a little creative play and found a couple of solutions for this sort of problem using HCL2. Here are the techniques I found to work around this constraint.

- [Provide HCL2 variable values using environment variables](https://github.com/angrycub/nomad_example_jobs/blob/main/HCL2/variable_jobs/env-vars)
- [Use more than one `-var-file` flag](https://github.com/angrycub/nomad_example_jobs/blob/main/HCL2/variable_jobs/var-files)
- [Decode the contents of an external file into a `local` variable](https://github.com/angrycub/nomad_example_jobs/blob/main/HCL2/variable_jobs/decode-external-file)

The links go to example solutions I wrote based on your original question sample HCL.

Hope this gives you some ideas and gets you unstuck.

Best,  
Charlie

---

<div class="post-metadata">

**Author:** ![bert2002](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/bert2002/32/16382_2.png) [@bert2002](https://discuss.hashicorp.com/u/bert2002)\
**Post date:** [June 16, 2021, 7:57am UTC](https://discuss.hashicorp.com/t/define-variables-across-job-definitions/25284/4 "2021-06-16T07:57:28Z")

</div>

Hi @angrycub,  
it seems that your first solution is working and the only one that will actually work.  
Would be nice if its possible without bash, but maybe HCL3 will be able to do it 😃

Thanks a lot.
