Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use variables or locals on block labels #9522

Open
ivantopo opened this issue Dec 4, 2020 · 21 comments
Open

Can't use variables or locals on block labels #9522

ivantopo opened this issue Dec 4, 2020 · 21 comments
Labels
stage/accepted Confirmed, and intend to work on. No timeline committment though. theme/hcl type/enhancement

Comments

@ivantopo
Copy link

ivantopo commented Dec 4, 2020

Nomad version

Nomad v1.0.0-rc1 (afea734)

Operating system and Environment details

Ubuntu 20.04.1 LTS

Issue

I was trying to use locals/vars to customize the name of a job, following the example in the docs but I'm getting this error:

Error getting job struct: Error parsing job file from locals-bug.nomad:
locals-bug.nomad:10,6-8: Invalid string literal; Template sequences are not allowed in this string. To include a literal "$", double it (as "$$") to escape it., and 2 other diagnostic(s)

Reproduction steps

  • Define variables and/or locals in a job file
  • Try to interpolate any variable and/or locals on the job name label.

Job file (if appropriate)

variables {
  name = "app"
  suffix = "cluster"
}

locals {
  job_name = "${var.name}_${var.suffix}"
}

job "${local.job_name}" {
  datacenters = [ "FSN" ]

  group "app-nodes" {
    count = 3

    task "app-node" {
      driver = "docker"

      config {
        network_mode = "host"
        image = "hello-world:latest"
      }
    }
  }
}

@notnoop notnoop added stage/accepted Confirmed, and intend to work on. No timeline committment though. theme/hcl type/enhancement labels Dec 4, 2020
@notnoop
Copy link
Contributor

notnoop commented Dec 4, 2020

Thank @ivantopo for highlighting it. It's indeed a limitation that we want to eliminate in next few releases. We'll update the docs to call this out for now.

For context, the limitation is built into HCL2 parser: https://github.com/hashicorp/hcl/blob/v2.7.2/hclsyntax/parser.go#L1637-L1638 ; and we are discussing internally removing it and how it may affect other products using HCL2.

@ivantopo
Copy link
Author

ivantopo commented Dec 4, 2020

Thanks for the insights, @notnoop! I'll stay alert for any updates and move on without these interpolations in the meantime.

@tgross
Copy link
Member

tgross commented Dec 4, 2020

@ivantopo by the way, there is a workaround if you're willing to have dynamic blocks in your jobspec. See https://www.nomadproject.io/docs/job-specification/volume#volume-interpolation where we have an example for volume. The labels field is what gets used for the generated volume block's label.

notnoop pushed a commit that referenced this issue Dec 7, 2020
Mainly note that block labels need to be string literals, and that decimals without a leading significant digits aren't acceptable anymore (e.g. .9 are required to be 0.9).

Dynamic blocks can be used here, but feels too much of a hack, or a hammer to highlight it here, specially given the error reporting and debugging isn't so straightforward. I'd advocate internally for relaxing the restriction and allowing expressions in block labels instead.

Related to #9522
@sofixa
Copy link
Contributor

sofixa commented Jan 13, 2021

@tgross that doesn't work with the "job" stanza:

dynamic "job" {
    for_each = var.job_name
    labels = [var.job_name]
    content {
...
x.nomad:21,1-8: Unsupported block type; Blocks of type "dynamic" are not expected here.

The only way to have dynamic job names seems to be to pass through levant

@traceypooh
Copy link

traceypooh commented Feb 19, 2021

but. not to be too uppity... (divulges cards, being uppity...)

the only thing not dynamic / interpolation friendly AFAICT is the job "[[NAME]]"
and that seems like... a shame (rhymes)

we loved levant - but aren't going to use it anymore for just a single string swapout, eg:
sed -i "s/NOMAD_VAR_SLUG/$NOMAD_VAR_SLUG/" project.hcl
https://gitlab.com/internetarchive/nomad/-/blob/master/.gitlab-ci.yml#L52

here's the project.nomad / project.hcl general template for GitLab + Nomad:
https://gitlab.com/internetarchive/nomad/-/blob/master/project.nomad#L118

there's just that single string substitution needed now.

can live with sed - but if we all didn't have to.... 🙌

@traceypooh
Copy link

perhaps worth pointing out (am sure it's known) that you can't use dynamic blocks inside docker driver config. not the end of the world and can workaround. but perhaps worth mentioning.

i'm super chuffed w/ hcl v2 overall - it's super powerful and great. thanks for the behind the scenes wizardry getting that into nomad.

@tgross
Copy link
Member

tgross commented Feb 19, 2021

the only thing not dynamic / interpolation friendly AFAICT is the job "[[NAME]]"
and that seems like... a shame (rhymes)

Yeah, totally agree with you here. We even have to do silly things in our end-to-end testing to work around this. I don't think there's anything inherent to HCL2 that prevents block labels from being interpolated, it's a matter of spending some time to rework how we're doing the decoding a little bit. Definitely will get on the roadmap.

perhaps worth pointing out (am sure it's known) that you can't use dynamic blocks inside docker driver config. not the end of the world and can workaround. but perhaps worth mentioning.

Thanks! That also got reported in #9871 and the fix will ship in the upcoming Nomad 1.0.4 #9921

@traceypooh
Copy link

thanks @tgross !

@pscheit
Copy link

pscheit commented Apr 15, 2021

since this isnt added right now, this example in the docs is very confusing:

https://www.nomadproject.io/docs/job-specification/hcl2/locals#examples

@JanMa
Copy link
Contributor

JanMa commented Apr 19, 2021

Hey,

can you give an estimate if this will be fixed in the next release(s)? Being
able to set dynamic Job, Task and Group names using HCL2 would allow me to write
generic Job templates without the need for external tooling. Currently I always
need some additional tooling to render a job template before passing it to
Nomad. Using only the built-in features would simplify my deployment pipelines
quite a bit :-)

@nepeat
Copy link

nepeat commented May 4, 2021

I would like to note that this is especially an issue with container labels, both quoted and unquoted.

job "sample" {
    datacenters = ["dc1"]
    group "redacted_group" {
        task "redacted_task" {
            driver = "docker"

            config {
                labels {
                    traefik.enable = "true"
                }
                image = "nginx:1.19.10-alpine"
            }
        }
    }
}
Error getting job struct: Failed to parse using HCL 2. Use the HCL 1 parser with `nomad run -hcl1`, or address the following issues:
sample:9,21-28: Argument or block definition required; An argument or block definition is required here. To set an argument, use the equals sign "=" to introduce the argument value.

job "sample" {
    datacenters = ["dc1"]
    group "redacted_group" {
        task "redacted_task" {
            driver = "docker"

            config {
                labels {
                    "traefik.enable" = "true"
                }
                image = "nginx:1.19.10-alpine"
            }
        }
    }
}
Error getting job struct: Failed to parse using HCL 2. Use the HCL 1 parser with `nomad run -hcl1`, or address the following issues:
sample:9,21-22: Invalid argument name; Argument names must not be quoted.

@lemon-li
Copy link

lemon-li commented May 13, 2021

version: 1.0.4
I was trying to HCL2 example , but I'm getting this error:

Error getting job struct: Error parsing job file from foobar.nomad:
foobar.nomad:12,6-8: Invalid string literal; Template sequences are not allowed in this string. To include a literal "$", double it (as "$$") to escape it.
foobar.nomad:4,31-43: Unsupported attribute; This object does not have an attribute named "name_prefix".

@pznamensky
Copy link

Also tried to use local variables and use locals example from the documentation, but it still doesn't work.

~ $ nomad plan example.nomad 
Error getting job struct: Error parsing job file from example.nomad:
example.nomad:4,31-43: Unsupported attribute; This object does not have an attribute named "name_prefix".
~ $ nomad version
Nomad v1.1.3 (8c0c8140997329136971e66e4c2337dfcf932692)

job file:

# A computed default name prefix
locals {
  default_name_prefix = "${var.project_name}-web"
  name_prefix         = "${var.name_prefix != "" ? var.name_prefix : local.default_name_prefix}"

  # unlike variables, locals don't have type constraints, so if you use
  # functions that take maps but not objects, you may need to convert them
  number_of_ports = length(convert({"www" = "80"}, map(string)))
}

job "example" {

  name = "${local.name_prefix}_loadbalancer"

  datacenters = ["dc1"]

  group "cache" {
    network {
      port "db" {
        to = 6379
      }
    }

    task "redis" {
      driver = "docker"

      config {
        image = "redis:3.2"

        ports = ["db"]
      }

      resources {
        cpu    = 500
        memory = 256
      }
    }
  }
}

@xeroc
Copy link

xeroc commented Dec 14, 2021

We are currently using sed, but as noted also by others in this thread, we don't really like this solution.

@zhujinhe
Copy link

zhujinhe commented Mar 1, 2022

We are also using sed right now, looking for a more native way to do this.

job "foo" {
  name = var.bar
}

btw, it will create a job with "foo" as it's ID and the value of bar as it's Name.
If you modify the value of bar, the job with ID eques foo will be update in-place, NO new job will be created.

@vvarga007
Copy link

Any update on this? Three years later, there is still no solution.

@Yethal
Copy link
Contributor

Yethal commented Sep 6, 2023

If variables in block labels are a nogo can we at least get the option of using an unlabeled job block and specifying the id the same way we can specify the name?

@hashworks
Copy link

It might make sense to allow a syntax like job { and expect a job id definition using CLI flags when one runs nomad run?

@josvegit
Copy link

josvegit commented May 7, 2024

this basically makes nomad-pack useless XD

@tgross
Copy link
Member

tgross commented May 7, 2024

@josvegit except that Pack is able to interpolate HCL labels? There's examples in the community registry that demonstrate this exactly: https://github.com/hashicorp/nomad-pack-community-registry/blob/main/packs/democratic_csi_nfs/templates/controller.nomad.tpl#L1

Label interpolation just isn't available in Nomad natively (and as noted, it's a HCL2 parser issue, so it's non-trivial to fix without making changes that potentially impact all other HashiCorp products). If you're finding otherwise, that's probably a Pack bug. And in any case, the editorization without detail isn't particularly productive.

@Yethal
Copy link
Contributor

Yethal commented Aug 23, 2024

@tgross Would it be possible to interpolate the job label by using a dynamic block to construct the job block?
EDIT: nvm I see this is not possible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stage/accepted Confirmed, and intend to work on. No timeline committment though. theme/hcl type/enhancement
Projects
Status: Needs Roadmapping
Development

No branches or pull requests