Playbooks
-‐
hosts:
all
roles:
-‐
common
-‐
include:
blah.yml
-‐
hosts:
nameservers
roles:
-‐
nameserver
node
/^ns\d+/
{
include
common
include
profiles::nameservers
}
Stick it Together
#
Vars
my_keys:
-‐
"ssh-‐rsa
AA..."
-‐
"ssh-‐rsa
BB..."
#
Task
-‐
authorized_keys:
user:
"app"
key:
"{{
item
}}"
with_items:
my_keys
Slide 22
Slide 22 text
Stick it Together
#
Vars
my_keys:
-‐
"ssh-‐rsa
AA..."
-‐
"ssh-‐rsa
BB..."
#
Task
-‐
authorized_keys:
user:
"app"
key:
"{{
item
}}"
with_items:
my_keys
#
Hiera
Data
my_keys:
-‐
"ssh-‐rsa
AA..."
-‐
"ssh-‐rsa
BB..."
#
Manifest
create_resources(
'ssh_authorized_key',
hiera('my_keys'),
{
user
=>
'app'
}
)
Slide 23
Slide 23 text
Back to Playbooks
-‐
apt:
pkg:
nginx
state:
present
-‐
service:
name:
nginx
enabled:
yes
state:
started
package
{
"nginx":
ensure
=>
present,
}
service
{
"nginx":
ensure
=>
started,
requires
=>
Package["nginx"],
}
Slide 24
Slide 24 text
Back to Playbooks
-‐
apt:
pkg:
nginx
state:
present
-‐
service:
name:
nginx
enabled:
yes
state:
started
package
{
"nginx":
ensure
=>
present,
}
-‐>
service
{
"nginx":
ensure
=>
started,
}
Slide 25
Slide 25 text
Dependencies:
Implicit vs Explicit
Slide 26
Slide 26 text
Dependencies:
Implicit vs Explicit
(Ansible) (Puppet)
Slide 27
Slide 27 text
Ordering:
Implicit vs Explicit
Slide 28
Slide 28 text
Ordering:
Implicit vs Explicit
(Puppet) (Ansible)
Slide 29
Slide 29 text
What Ansible isn't.
Slide 30
Slide 30 text
Ansible is simple
because it uses YAML.
“
Slide 31
Slide 31 text
You may as well say:
C is simple
because it uses
letters, numbers and
some symbols.
Slide 32
Slide 32 text
Ansible is
"Infrastructure as Data",
not
"Infrastructure as Code".
“
Slide 33
Slide 33 text
It's code!
It's code even if you're writing
it in a markup language; it's
loops, variables, conditions, and
functions.
It's about as declarative as my
mum's Shepherd's Pie recipe.
Other Things
• Reusing code is tough and inflexible;
everything needs to be a role that you
then stick together in the meta/main.yml
Slide 44
Slide 44 text
Other Things
• Reusing code is tough and inflexible;
everything needs to be a role that you
then stick together in the meta/main.yml
• Third-party Roles via Ansible Galaxy is
great, ... but a lot of it's new or naïve;
unless you're lucky, you end up modifying
a lot of it.
Looping
#
Vars
my_keys:
-‐
user:
app
key:
"..."
#
Task
-‐
authorized_keys:
user:
"{{
item.user
}}"
key:
"{{
item.key
}}"
with_items:
my_keys
#
Hiera
Data
my_keys:
-‐
"ssh-‐rsa
AA..."
-‐
"ssh-‐rsa
BB..."
#
Manifest
create_resources(
'ssh_authorized_key',
hiera('my_keys'),
{
user
=>
'app'
}
)
Structure of Heira data needs to match closely
to what's consuming it (eg. SshAuthorizedKeys).
Ansible is much more flexible (see above), and
can avoid the massive single-resource-declaration
problem lurking in the bottom-right. :-)
Single Declaration
Package
{
"ntp":
ensure
=>
present,
}
#
...
SomeThing
{
"foo":
#
...
requires
=>
Package['ntp'],
}
Single-declaration-only for resources
makes writing reusable third-party
Puppet modules really hard.
These (long) bug threads explain it well:
• https://projects.puppetlabs.com/
issues/18490
• https://tickets.puppetlabs.com/
browse/PUP-1968
Slide 51
Slide 51 text
• Ansible not as "simple" as touted.
• Ansible has unsafe edge-cases to skirt
around.
• Ansible makes you remember the
dependency ordering yourself, rather
than encoding it.
Summin' up.
Slide 52
Slide 52 text
• Puppet has big problems it's going to find
difficult to solve without breaking everything.
(You can't silently merge two identical Service
definitions if you have globals and could-
change-on-each-call state hanging around.)
• Puppet makes you write the dependency
information, but then squanders it.
• Using generic data is tough without custom
mangling or the experimental syntax engine.
Summin' up.
Slide 53
Slide 53 text
Fin.
Rob Howard
@damncabbage
https://speakerdeck.com/damncabbage/