hashicorp / levant

An open source templating and deployment tool for HashiCorp Nomad jobs
Mozilla Public License 2.0
829 stars 125 forks source link

Named ports not working in Levant #448

Open brettplarson opened 2 years ago

brettplarson commented 2 years ago

Description Cannot plan or deploy jobs using levant that otherwise work when I render them and use the nomad CLI.

I have a go template which renders ports from a yaml file however I get the following error when trying to use levant deploy / plan.

[ERROR] levant/command: error parsing 'job': group: network, ports -> Port label does not conform to naming requirements ^[a-zA-Z0-9_]+$

Rendering the output and then planning / running works fine, it's something with levant itself that is causing this issue.

even though it seems like levant is no longer maintained, I figure it wouldn't hurt to post this.

Relevant Nomad job specification file YAML:


job:
  job_name: comejob
  region: nonprod
  periodic:
    cron: 0 06 * * MON-FRI *
  type: batch
  datacenters:
  - DC1
  constraint:
    host: somehost
  group:
    restart:
      attempts: 0
    reschedule:
      attempts: 0
      unlimited: false
    network:
      ports:
      - name: server
        static: 39399
        to: 9999
      - name: server-pub
        static: 39398
        to: 9998

Template:

    port [[ .name | quote ]] {
      [[if .to ]] to  = [[ .to ]] [[ end ]]
      [[if .static ]] static = [[ .static ]] [[ end ]]
      }
    [[- end ]]

What the port section looks like rendered:

      port "server" {
        to     = 9999
        static = 39399
      }
      port "server-pub" {
        to     = 9998
        static = 39398
      }

Output of levant version:

Levant v0.3.1

Output of consul version:

n/a

Output of nomad version:

Nomad v1.2.6 (a6c6b475db5073e33885377b4a5c733e1161020c)

Additional environment details:

n/a

Debug log outputs from Levant:

[ERROR] levant/command: error parsing 'job': group: network, ports -> Port label does not conform to naming requirements ^[a-zA-Z0-9_]+$
jrasell commented 2 years ago

Hi @brettplarson.

This is due to a difference between HCLv1 and HCLv2 parsing. Levant currently only supports the former whereas running nomad job run using the 1.2.6 Nomad binary will use the latter.

I confirmed this using the following example job and commands.

job "example" {
  type        = "service"
  datacenters = ["dc1"]

  group "cache" {
    network {
      port "server" {
        to     = 9999
        static = 39399
      }
      port "server-pub" {
        to     = 9998
        static = 39398
      }
    }

    task "redis" {
      driver = "docker"

      config {
        image = "redis:3.2"
      }
    }
  }
}
$ nomad run -hcl1 -hcl2-strict=false  example.nomad                                                                                                                                               1 ✘  09:07:22
Error getting job struct: Error parsing job file from example.nomad:
error parsing 'job': group: network, ports -> Port label does not conform to naming requirements ^[a-zA-Z0-9_]+$
$ nomad run -detach  example.nomad                                                                                                                                                              INT ✘  09:09:22
Job registration successful
Evaluation ID: da68d7e0-f0da-7d52-5f7f-346aa7423119

The fix on the Levant side would be to update it to support both HCL1/2, although we don't currently have this roadmapped due to other commitments. The linked Nomad issue is orthogonal to this one and regards the consistency of port validation across the HCL versions.

As an immediate workaround, it is possible to change the port label to use underscores rather than dashes such as port "server_pub" {.