Use HCL, not YAML.
# Ensure blocks group actions
ensure "Foo service" {
package "foo" {
version = "1.0.0" # No version means install latest available
}
file "/etc/foo.conf" {
source = file.conf.tmpl
user = "foo"
group = "foo"
mode = 0644
validate = "/usr/bin/foo validate" # Some way of running a command to validate the template?
}
# Or explicitly create a new action?
exec {
command = ["/usr/bin/foo", "validate", "/etc/foo.conf"]
}
service "foo" {
state = "running"
enable = true # Ensure started at boot
# Should requirements be explicit or purely based on ordering?
require = {
package: "foo",
file: "/etc/foo.conf",
}
}
}
ensure "Some external condition" {
# This group needs another group to have completed
require = {ensure: "Foo service"}
# Alternatively, run this group when another changes
when = {changed: "Foo service"}
exec {
command = ["/usr/bin/echo", "one", "two"]
expect = "one two" # Ensure this output
}
exec {
command = ["/usr/bin/touch", "/tmp/foo"]
creates = "/tmp/foo" # Ensure this file is created
}
The equivalent in Salt would be:
# Salt lets you group states, although they all have the same "name" which may need to be overridden in the state
Foo service:
pkg.installed:
- name: foo
- version: 1.0.0
file.managed:
- name: /etc/foo.conf
- source: salt://foo.conf.tmpl
service.running:
- name: foo
- enable: true
- require:
- pkg: foo
- file: /etc/foo.conf
Some external condition:
cmd.run:
- name: /usr/bin/echo one two
# Note you can't have two cmd.run in the same block so this one must be separate
Some second condition:
cmd.run:
- name: /usr/bin/touch /tmp/foo
- creates: /tmp/foo
And in Ansible:
# Ansible groups tasks too.
- name: Setup foo service
tasks:
- name: Install foo package
pkg:
name: foo
- name: Install foo config
template:
src: foo.conf.j2
dest: /etc/foo.conf
- name: Ensure foo is running
service:
name: foo
state: started
- name: Some external condition
tasks:
- name: echo one two
command: /usr/bin/echo one two
- name: touch /tmp/foo
command:
cmd: /usr/bin/touch /tmp/foo
creates: /tmp/foo
Oh god not Jinja. Nor Go text/template. There must be something better? HCL2 has its own basic templating although the docs are vague.
Variables could be injected in a similar way to Ansible.
How should loops / repeated actions work? Maybe instead of templating inside the file, you have a template file that gets repeated N times
package "${package.name}" {
version = "${package.version}"
}
service "${service.name}" {
state = "${service.state}"
}
The package
and service
vars could be populated by a map elsewhere, which calls that template each time. No more messy generated loops?