diff --git a/command/deploy.go b/command/deploy.go index 68f23b2d..352a4dec 100644 --- a/command/deploy.go +++ b/command/deploy.go @@ -74,7 +74,7 @@ General Options: -var-file= Used in conjunction with the -job-file will deploy a templated job to your Nomad cluster. You can repeat this flag multiple times to supply multiple var-files. - [default: levant.(yaml|yml|tf)] + [default: levant.(json|yaml|yml|tf)] ` return strings.TrimSpace(helpText) } diff --git a/command/render.go b/command/render.go index 414456a7..c2fa1026 100644 --- a/command/render.go +++ b/command/render.go @@ -45,7 +45,7 @@ General Options: -var-file= The variables file to render the template with. You can repeat this flag multiple - times to supply multiple var-files. [default: levant.(yaml|yml|tf)] + times to supply multiple var-files. [default: levant.(json|yaml|yml|tf)] ` return strings.TrimSpace(helpText) } diff --git a/docs/templates.md b/docs/templates.md index 72ccdec3..9f419912 100644 --- a/docs/templates.md +++ b/docs/templates.md @@ -4,54 +4,98 @@ Alongside enhanced deployments of Nomad jobs; Levant provides templating functio ### Template Substitution -Levant currently supports `.tf`, `.yaml` and `.yml` file extensions for the declaration of template variables and uses opening and closing double squared brackets `[[ ]]` within the templated job file. This is to ensure there is no clash with existing Nomad interpolation which uses the standard `{{ }}` notation. +Levant currently supports `.json`, `.tf`, `.yaml`, and `.yml` file extensions for the declaration of template variables and uses opening and closing double squared brackets `[[ ]]` within the templated job file. This is to ensure there is no clash with existing Nomad interpolation which uses the standard `{{ }}` notation. -Example Job Template: +#### JSON + +JSON as well as YML provide the most flexible variable file format. It allows for descriptive and well organised jobs and variables file as shown below. + +Example job template: +```hcl +resources { + cpu = [[.resources.cpu]] + memory = [[.resources.memory]] + + network { + mbits = [[.resources.network.mbits]] + } +} +``` + +Example variable file: +```json +{ + "resources":{ + "cpu":250, + "memory":512, + "network":{ + "mbits":10 + } + } +} +``` + +#### Terraform + +Terraform (.tf) is probably the most inflexible of the variable file formats but does provide an easy to follow, descriptive manner in which to work. It may also be advantageous to use this format if you use Terraform for infrastructure as code thus allow you to use a consistant file format. + +Example job template: ```hcl resources { - cpu = [[.cpu]] - memory = [[.memory]] + cpu = [[.resources_cpu]] + memory = [[.resources_memory]] network { - mbits = [[.mbits]] + mbits = [[.resources_network_mbits]] } } ``` -`.tf` variables file: +Example variable file: ```hcl -variable "cpu" { - default = 250 +variable "resources_cpu" { + description = "the CPU in MHz to allocate to the task group" + type = "string" + default = 250 } -variable "memory" { - default = 512 +variable "resources_memory" { + description = "the memory in MB to allocate to the task group" + type = "string" + default = 512 } -variable "mbits" { - default = 10 +variable "resources_network_mbits" { + description = "the network bandwidth in MBits to allocate" + type = "string" + default = 10 } ``` -`.yaml` or `.yml` variables file: -```yaml -cpu: 250 -memory: 512 -mbits: 10 -``` +#### YAML -Render: +Example job template: ```hcl resources { - cpu = 250 - memory = 512 + cpu = [[.resources.cpu]] + memory = [[.resources.memory]] network { - mbits = 10 + mbits = [[.resources.network.mbits]] } } ``` +Example variable file: +```yaml +--- +resources: + cpu: 250 + memory: 512 + network: + mbits: 10 +``` + ### Template Functions Levant's template rendering supports a number of functions which provide flexibility when deploying jobs. As with the variable substitution, it uses opening and closing double squared brackets `[[ ]]` as not to conflict with Nomad's templating standard. Levant parses job files using the [Go Template library](https://golang.org/pkg/text/template/) which makes available the features of that library as well as the functions described below. diff --git a/helper/files.go b/helper/files.go index d92beab0..b5b882d3 100644 --- a/helper/files.go +++ b/helper/files.go @@ -31,6 +31,10 @@ func GetDefaultVarFile() (varFile string) { log.Debug().Msg("helper/files: using default var-file `levant.yml`") return "levant.yml" } + if _, err := os.Stat("levant.json"); !os.IsNotExist(err) { + log.Debug().Msg("helper/files: using default var-file `levant.json`") + return "levant.json" + } if _, err := os.Stat("levant.tf"); !os.IsNotExist(err) { log.Debug().Msg("helper/files: using default var-file `levant.tf`") return "levant.tf" diff --git a/template/render.go b/template/render.go index 7f81f8c4..b5d542ab 100644 --- a/template/render.go +++ b/template/render.go @@ -2,6 +2,7 @@ package template import ( "bytes" + "encoding/json" "fmt" "io/ioutil" "path" @@ -70,6 +71,8 @@ func RenderTemplate(templateFile string, variableFiles []string, addr string, fl variables, err = t.parseTFVars(variableFile) case yamlVarExtension, ymlVarExtension: variables, err = t.parseYAMLVars(variableFile) + case jsonVarExtension: + variables, err = t.parseJSONVars(variableFile) default: err = fmt.Errorf("variables file extension %v not supported", ext) } @@ -98,6 +101,21 @@ func RenderTemplate(templateFile string, variableFiles []string, addr string, fl return } +func (t *tmpl) parseJSONVars(variableFile string) (variables map[string]interface{}, err error) { + + jsonFile, err := ioutil.ReadFile(variableFile) + if err != nil { + return + } + + variables = make(map[string]interface{}) + if err = json.Unmarshal(jsonFile, &variables); err != nil { + return + } + + return variables, nil +} + func (t *tmpl) parseTFVars(variableFile string) (variables map[string]interface{}, err error) { c := &config.Config{} diff --git a/template/template.go b/template/template.go index b7667565..5de87ddc 100644 --- a/template/template.go +++ b/template/template.go @@ -16,6 +16,7 @@ type tmpl struct { } const ( + jsonVarExtension = ".json" terraformVarExtension = ".tf" yamlVarExtension = ".yaml" ymlVarExtension = ".yml"