Templates

Vigo uses Go template syntax for dynamic content in resource definitions. Templates are rendered agent-side during policy evaluation.

Where Templates Are Allowed

Templates are rendered in all string attributes on every resource. This includes content:, source:, target_path:, command:, repo:, key_url:, url:, owner:, group:, mode:, when:, and any other string field.

# All of these support {{ .Traits.* }} and {{ .Vars.* }}
- name: docker-repo
  type: repository
  key_url: "https://download.docker.com/linux/{{ .Traits.os.upstream_id }}/gpg"
  repo: "deb https://download.docker.com/linux/{{ .Traits.os.upstream_id }} {{ .Traits.os.upstream_codename }} stable"

- name: install-consul
  type: source_package
  url: "https://releases.hashicorp.com/consul/{{ .Vars.consul_version }}/consul_{{ .Vars.consul_version }}_linux_{{ .Traits.os.arch }}.zip"

For small templates, use content: directly. For larger config files, put the template in the templates/ directory and reference it with source:. The content: and source: attributes are mutually exclusive.

Template Data

Templates have access to two namespaces:

.Vars

Module variables (after resolution):

vars:
  app_port: 8080
  app_name: myapp

resources:
  - name: app-config
    type: file
    target_path: /etc/app/config.yaml
    content: |
      name: {{ .Vars.app_name }}
      port: {{ .Vars.app_port }}

.Traits

Envoy traits (auto-discovered facts):

resources:
  - name: motd
    type: file
    target_path: /etc/motd
    content: |
      ==========================================
      Hostname: {{ .Traits.network.hostname }}
      OS:       {{ .Traits.os.distro }} {{ .Traits.os.version }}
      Arch:     {{ .Traits.os.arch }}
      CPUs:     {{ .Traits.hardware.cpu_count }}
      Memory:   {{ .Traits.hardware.memory_mb }} MB
      ==========================================

Go Template Syntax

Variable Output

{{ .Vars.key }}
{{ .Traits.os.family }}

Conditionals

{{ if eq .Traits.os.family "debian" }}
apt is the package manager
{{ else }}
yum/dnf is the package manager
{{ end }}

Iteration

{{ range .Vars.allowed_users }}
AllowUser {{ . }}
{{ end }}

Where allowed_users is a list variable:

vars:
  allowed_users: [alice, bob, charlie]

Nested Map Access

{{ .Traits.os.distro }}
{{ index .Traits.network.ip_addresses 0 }}
{{ .Traits.network.fqdn }}

Default Values

{{ .Vars.log_level | default "info" }}

Note: Go templates don't have a built-in default filter. Use if instead:

{{ if .Vars.log_level }}{{ .Vars.log_level }}{{ else }}info{{ end }}

Examples

SSH Configuration

- name: sshd-config
  type: file
  target_path: /etc/ssh/sshd_config
  content: |
    Port {{ .Vars.ssh_port }}
    PermitRootLogin no
    PasswordAuthentication no
    {{ range .Vars.allowed_users }}
    AllowUsers {{ . }}
    {{ end }}
  notify: [sshd-service]

Nginx Virtual Host

- name: vhost
  type: file
  target_path: /etc/nginx/sites-available/app
  content: |
    server {
        listen {{ .Vars.nginx_port }};
        server_name {{ .Vars.server_name }};

        location / {
            proxy_pass http://127.0.0.1:{{ .Vars.app_port }};
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }

System Information

- name: node-info
  type: file
  target_path: /etc/vigo-node-info
  content: |
    hostname={{ .Traits.network.hostname }}
    os={{ .Traits.os.distro }}
    version={{ .Traits.os.version }}
    arch={{ .Traits.os.arch }}
    ip={{ index .Traits.network.ip_addresses 0 }}
    managed_by=vigo

Common Mistakes

Template in targetpath (won't work):

# WRONG — templates not allowed in targetpath
- name: config
  type: file
  target_path: "/etc/{{ .Vars.app_name }}/config.yaml"

Fix: Use a literal path or set it via vars at the node level.

Template in command (won't work):

# WRONG — templates not allowed in command
- name: restart
  type: exec
  command: "systemctl restart {{ .Vars.service_name }}"

Fix: Use vars to set the service name directly as a resource attribute.

Related

  • Config Format — Vars and environment_overrides
  • Trait Collectors — Available .Traits data
  • Executors — Which attributes each executor uses