Nomad Pack

repository·main·Indexed 19 days ago

https://github.com/hashicorp/nomad-pack

A templating and packaging tool for HashiCorp Nomad that enables users to deploy popular applications, reuse common patterns, and share job specifications via community or private registries. It includes a CLI for managing pack registries, rendering templates, and deploying or destroying resources in Nomad clusters.

Tokens
26.1K
Snippets
90
Records
112
Agent score
65%

What's inside nomad-pack

  1. Parse and validate IP addresses with Network functions

    main

    Nomad Pack includes helper functions based on Go's netip package for handling IP addresses and ports.

    Warning: The parsing functions (parseAddr and parseAddrPort) will cause a template rendering error if provided with an invalid address. To prevent template failure, always validate the address using validAddr or validAddrPort before attempting to parse it.

  2. Provide variables from external sources

    main

    The run, plan, and render commands can fetch variable values from external systems at render time using the --var-source flag.

    Supported source types (determined by URL scheme):

    • Consul KV: consul://<host:port>/<path> (Variables are read from <path>/<variable-name>).
    • Vault KV v2: vault://<host:port>/<mount>/<path> (Variables are fields of the secret at <mount>/<path>).
    • Nomad Variables: nomad://<host:port>/<path> (Variables are items in the Nomad Variable at <path>).

    If the host is omitted (e.g., consul:///path), Nomad Pack uses standard environment configuration (address and token) for that tool. For Unix sockets, use unix:// and set the appropriate environment variable (e.g., NOMAD_ADDR).

    Precedence (Highest to Lowest):

    1. --var
    2. -f/--var-file
    3. Environment variables
    4. --var-source
    5. Pack variable defaults
    # Using multiple external sources
    nomad-pack run hello_world \
      --var-source consul://localhost:8500/nomad-pack \
      --var-source vault://localhost:8200/secret/nomad-pack \
      --var-source nomad://localhost:4646/nomad-pack
    
    # Using standard environment config (no host specified)
    nomad-pack run hello_world --var-source consul:///nomad-pack
    
    # Using a Unix socket for Nomad
    NOMAD_ADDR=unix:///secrets/api.sock \
      nomad-pack run hello_world --var-source nomad:///nomad-pack
  3. Define variables and Nomad Variables in variables.hcl

    main

    The variables.hcl file serves two purposes:

    1. Pack Variables: Standard HCL variables used to render templates (e.g., type, default, description).
    2. Nomad Variables: Using the nomad_variable block, you can define variables that are automatically created in Nomad's native variable storage during deployment. These are useful for secrets and configuration.

    Important: Variable Creation Timing Nomad Variables are created AFTER the job is deployed. If variable creation fails, the job will still be running, but the nomad-pack command will report an error. If this occurs, fix the variables.hcl and run the command again.

    variable "datacenters" {
      description = "A list of datacenters in the region which are eligible for task placement."
      type        = list(string)
      default     = ["dc1"]
    }
    
    nomad_variable "app_secrets" {
      path      = "nomad/jobs/myapp/secrets"
      namespace = "default"
      items = {
        db_password = "secret123"
        api_key     = "key456"
      }
    }
  4. How to use variables in a Nomad Pack

    main

    Nomad Packs allow you to parameterize your Nomad jobs using variables. When running a pack, you can override these variables using the --var flag. This allows you to customize deployments (e.g., changing a message, scaling instance counts, or specifying datacenters) without modifying the underlying job template.

    To override a variable, use the following syntax: nomad-pack run <pack-name> --var <variable-name>="<value>"

    nomad-pack run {{.PackName}} --var message="Hola Mundo!"
  5. How custom debug output formatting works with Spew

    main

    Nomad Pack provides a set of functions to customize how data structures are dumped using the Spew package. To use them, you must first initialize a configuration state using customSpew. This state can then be passed through various with* functions to modify specific printer settings before finally calling .Sdump to output the result.

    Workflow:

    1. Call customSpew to get a default spew.ConfigState.
    2. Pipe the state through customization functions (e.g., withIndent, withSortKeys).
    3. Call .Sdump on the resulting state with the object you want to inspect.
    [[ $cs := ( customSpew | withIndent "  " ) ]][[ $cs.Sdump . ]]
  6. Manage Pack Registries

    main

    Packs are organized into registries. While the Nomad Pack Community Registry is available by default, you can add custom registries (e.g., from Git or GitLab) to access private or specialized packs.

    • registry add <name> <url>: Adds a new registry to your local configuration.
    • registry list: Lists all currently configured registries.
    • list: Lists available packs (use registry list to see which registries are providing them).
    # Add a custom registry
    nomad-pack registry add example gitlab.com/mikenomitch/pack-registry
    
    # List all configured registries
    nomad-pack registry list
    
    # List available packs
    nomad-pack list
  7. Destroy resources deployed by a pack

    main

    To remove the resources (such as Nomad jobs) deployed by a pack, use the destroy command followed by the pack name.

    If you used the --name flag during deployment to assign a specific deployment name, you must provide that same --name to the destroy command.

    If your deployment used variable overrides (--var) that affect the job names within the pack, you must include those same variable overrides in the destroy command to target a specific job. If you omit the variable overrides, nomad-pack will attempt to destroy all jobs associated with that pack and deployment name.

    # Basic destroy
    nomad-pack destroy hello_world
    
    # Destroying a pack deployed with a specific name
    nomad-pack destroy hello_world --name hola-mundo
    
    # Destroying a specific job instance using variable overrides
    nomad-pack destroy hello_world --name hola-mundo --var job_name=spanish
  8. Build and run Nomad Pack locally

    main

    Use make commands to manage the local development lifecycle:

    1. Bootstrap dependencies: Run make bootstrap to install required tools.
    2. Verify code integrity: Run make check to validate Go modules and sums.
    3. Build the binary: Run make dev to compile the project. This generates an executable at ./bin/nomad-pack.
    4. Execute the binary: Run the local binary directly to test it (e.g., ./bin/nomad-pack -h).
    # Install required tools
    make bootstrap
    
    # Check Go mod and Go sum
    make check
    
    # Build a binary from local code (outputs to ./bin/nomad-pack)
    make dev
    
    # Run your code
    ./bin/nomad-pack -h
  9. Test a pack locally

    main

    To test a pack during development, pass the local directory path to the nomad-pack commands (run, plan, render, info, stop, or destroy). When using a local path, the pack is treated as having a dev registry and dev reference.

    # Run the pack from the current directory
    nomad-pack run .
    nomad-pack run .
  10. Configure spinner output with a custom Writer

    main

    To ensure the spinner does not interfere with standard output (e.g., when redirecting stdout to a file), set the spinner's writer to os.Stderr using spinner.WithWriter().

    s := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(os.Stderr))
    s.Suffix = " Encrypting data..."
    s.Start()
    // Now stdout can be safely used for actual data
    fmt.Println(os.Stdout, ciphertext)
  11. Structure a Nomad Pack directory

    main

    A pack directory within a registry must contain the following files:

    • README.md: Human-readable description and dependency info.
    • metadata.hcl: Pack metadata (name, version, description, etc.).
    • variables.hcl: HCL definitions for variables used in templates.
    • templates/: A subdirectory containing .nomad.tpl files for rendering jobspecs.
    • CHANGELOG.md (Optional): Version history.
    • outputs.tpl (Optional): Defines text to print upon successful deployment.

    Note: Pack dependencies must be declared in metadata.hcl using dependency blocks.