Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Puppet vs. Ansible: Shoot

Victor Volle
December 09, 2015
350

Puppet vs. Ansible: Shoot

devops meetup Munich, Dec. 9 2015

Victor Volle

December 09, 2015
Tweet

Transcript

  1. Puppet vs. Ansible 3 Disclaimer 1) Open Source versions only

    2) Master-less 3) RedHat partner 4) Ansible Fan
  2. configuration management 5 Provision, Configure, Deploy, … OS Packages Application

    Configuration Provision Deploy Configure Orchestrate
  3. configuration management 6 Provision, Configure, Deploy, … OS Packages Application

    Configuration Provision Deploy Configure there is no clean cut definition of “provision”, “deploy”, “configure” (that I know of)
  4. Puppet vs. Ansible 7 In on sentence … Puppet models

    the target state Ansible is remote script execution on steroids
  5. Puppet vs. Ansible 8 Commonalities Repeatability (“Idempotence”) You can apply/execute

    a manifest/playbook multiple times: nothing will change after the “target state” is reached Separation of configuration and “script” Configuration data can be separated from manifests/ playbooks (passwords) Modularisation and Extension You can modularise (and reuse) manifests/playbooks and extend both tools (Puppet: Ruby; Ansible: Python)
  6. Configuration Management Tools 9 Basic Info Puppet Ansible Created 2005

    2012 Execution Order declarative* sequential DSL external (Ruby) DSL YAML Template ERB
 (Ruby) jinja2 Push/Pull
 (default) client pull server push setup rather
 difficult simple * since 4.0 (April 15 2015): “manifest ordering”
  7. Node Configuration Management Tools 10 Push vs. Pull Server Initiator

    Server pull push - each “Node” must have a running daemon that asks the server for changes - Setting up the server can be daunting - each “Node” must have sshd running and an SSH key installed - The server just needs Ansible (+ Python and some SCM) Node Node Node Node Node
  8. Puppet vs. Ansible 11 Criteria Puppet Ansible Configuration (variables) Execution

    Model Orchestration Maturity Initial Setup Ease of Use
  9. Core Concepts 13 Ansible 1. Inventory 2. Facts & Variables

    3. Playbooks - which hosts? - “groups” of hosts? db:
 ram: 2GB "ansible_distribution_version":
 "14.04" - “facts”: the current state of my hosts - “variables”: properties of hosts (future state, config files, …) - hosts: a00 tasks: - apt: name=nginx - service: ... - what should be “done” on my hosts (future state)
  10. Ansible 14 Core Concepts: Inventory # Inventory [app]
 a01 [db]


    a02 a01 a02 application database “group” “host” # Inventory [app]
 a01 ansible_ssh_host=188.166.106.189 [db]
 a02 ansible_ssh_host=188.166.106.190 “(special) variable”
  11. variables on the host level Modularisation & Reuse 15 Variables

    workspace/ ├── files/ ├── group_vars/ │ ├── app/ │ │ └── app.yml │ ├── db/ │ │ └── db.yml │ └── all.yml ├── host_vars/ │ ├── app01.yml │ ├── app02.yml │ └── db01.yml ├── ansible.cfg ├── ansible_inventory ├── java.yml … variables on the group level # group_vars/app/app.yml jetty_dir: /opt/jetty jetty_base: "{{ jetty_dir }}/base” …
  12. Ansible 16 Playbooks --- - name: Install “Mysql” hosts: db

    tasks: - name: ensure user mysql exists user: name=mysql - name: install mysql packages apt: name= mysql-server update_cache=yes … - name: create DB user mysql_user: > name=media password=“{{db_password}}” … - name: start service service: name=mysql A “script” that describes the steps to the target state of the machine for which “hosts” (from the inventory) shall the Playbook be applied the list of target states (tasks/ changes) each task (should have) has a name all tasks are implemented by “modules”
 (“user”, “apt”, …)
  13. Puppet 18 Manifest class mysql ( root_password => 'default_value', port

    => '3306', ) { package { 'mysql-server': ensure => present, } service { 'mysql': ensure => running, require => Package[“mysql-server”], } [...] } class { “mysql”: root_password => “uncle”, } this is called a declaration (only once!) this is called a class definition a class is a collection of resources these are called resources declaration of ordering variables may be given directly
  14. class mysql ( root_password => 'default_value', port => '3306', )

    { package { 'mysql-server': ensure => present, } service { 'mysql': ensure => running, require => Package[“mysql-server”], } [...] } include mysql Puppet 19 Manifest safely declare multiple times variables are retrieved from “external data source” (hiera)
  15. Puppet 20 Hiera # hiera.yml --- … :hierarchy: - "systems/%{::clientcert}"

    - "locations/%{::location}" - "roles/%{::role}" - common common location role system priority
  16. Puppet 21 Hiera # hiera.yml --- … :hierarchy: - "systems/%{::clientcert}"

    - "locations/%{::location}" - "roles/%{::role}" - common hiera/ ├── locations/ │ ├── munich.yml │ └── berlin.yml ├── roles/ │ ├── app.yml │ └── db.yml ├── systems/ │ ├── app01.yml │ ├── app02.yml │ └── db01.yml ├── common.yml … snmp::agentaddress: - 'udp:161' - 'udp6:161' timezone::timezone: Etc/UTC
  17. Variables Hiera allows me to model my system landscape as

    the project needs it http://www.istockphoto.com/photo/colored-pencil-bar-graph-lined-paper-gives-successful-result-5143796
  18. Variables Ansible’s group vars, separated inventories, etc. are mostly sufficient,

    but it is lacking the power and elegance of Hiera https://pixabay.com/en/bread-food-olives-mediterranean-228939/
  19. class mysql Execution Model 25 Basic Model package mysql-server service

    mysql require class { “mysql” class mysql ( root_password => 'default_value', port => '3306', ) { package { 'mysql-server': ensure => present, } service { 'mysql': ensure => running, require => Package[“mysql-server”], } [...] } class { “mysql”: root_password => “uncle”, } definition declaration
  20. class app { class { “mysql”: } include postgresql contain

    ntp::service file { … } } class app Execution Model 26 class? include? contain? class mysql class { “app” class postgresql class ntp::service definition resource-like declaration include-like declaration resource-like declaration + containment resource (implies containment)
  21. # app.pp class app { class { “mysql”: } }

    Execution Model 27 class? include? contain? # main.pp class { “app “: } when will “mysql” be applied? 1. “mysql” 2. “app” 1 1. “app” 2. “mysql” 2 1. begin “app” 2. “mysql” 3. end “app” 3
  22. class app { class { “mysql”: } include postgresql contain

    ntp::service file { … } } Execution Model 28 class? include? contain? definition resource-like declaration include-like declaration resource-like declaration + containment 1.will not be applied before container is applied 2.will be applied before container is finished resource (implies containment) no promise whatsoever when the classes will be applied
  23. class app { exec { "init postgres master/slave": command =>

    "postgres-master-slave-init.sh", unless => “postgres-master-slave.sh —check" … } } Execution Model 29 Resources: exec exec is a “resource”?
  24. Execution Model 30 Script --- - name: Install “Mysql” hosts:

    db tasks: - name: ensure user mysql exists user: name=mysql - name: install mysql packages apt: name= mysql-server update_cache=yes … - name: create DB user mysql_user: > name=media password=“{{db_password}}” … - name: start service service: name=mysql Execute the tasks in the given order
  25. Execution Model 31 Using Result/Output of (shell) tasks tasks: -

    shell: mv /tmp/foo.txt /tmp/bar.txt ignore_errors: True register: mv_result - debug: var="mv_result" - debug: msg="{{ mv_result.stderr }}" when: mv_result|failed
  26. 32 Execution Models powerful but complex model based on the

    notion of resources and a target state — developed over 10 years http://www.istockphoto.com/vector/white-background-three-dragons-on-the-ring-of-mebius-18666111
  27. Execution Models Execution Models • regular puppet runs — the

    whole catalog every N minutes • continuously update all servers (when a manifest has changed) • execute regularly or execute when needed (deployment) • execute “everything” or a single playbook
  28. Application Database master configuration management 36 Orchestrate OS Packages Application

    Configuration OS Packages Application Configuration OS Packages Application Configuration OS Packages Application Configuration slave OS Packages Application Configuration OS Packages Application Configuration 1.0 1.0 㱺 1.1 1. create DB backup 2. apply DB scripts on master DB 3. configure haproxy not to use the ‘right’ to nodes (not shown) 4. wait 30 minutes 5. stop service 6. deploy version 1.1 on the ‘right’ nodes 7. start service 8. run smoke tests 9. manually check that everything is okay 10.configure haproxy … 11.start over at 3. for left nodes
  29. configuration management 37 Orchestrate 1. create DB backup 2. apply

    DB scripts on master DB 3. configure haproxy not to use the ‘right’ to nodes (not shown) 4. wait 30 minutes 5. stop service 6. deploy version 1.1 on the ‘right’ nodes 7. start service 8. run smoke tests 9. manually check that everything is okay 10.configure haproxy … 11.start over at 3. for left nodes the notion of a target state makes things like stopping a service and starting it later difficult to achieve (you have to use “exec” a lot)
  30. Orchestration 38 Puppet Application Orchestration (1) application shop( $db_user, $db_password

    ) { shop::pql { $name: user => $db_user, password => $db_password, export => Sql[$name], } shop::app { $name: consume => Sql[$name], export => Http["shop-web-$name"], } } Puppet Enterprise 2015.3 will have a new “Orchestration Model”
  31. site { shop { "simple": $db_user => 'simple', $db_password =>

    'test', nodes => { Node[node1] => Shop::Web['simple'], Node[node2] => Shop::Pql['simple'], } } shop { “test": … } } Orchestration 39 Puppet Application Orchestration (2) ❯ puppet job run Shop['simple']
  32. # mysql.pp class mysql ( root_password => 'default_value', port =>

    '3306', ) { package { 'mysql-server': ensure => present, } service { 'mysql': ensure => running, require => Package[“mysql- server”], } [...] } class { “mysql”: root_password => “uncle”, } Inventory 41 Node classification db01 Roll your own (“Facts” on node) #!/bin/… # ENC script … LDAP Puppet Master
  33. Inventory 42 Playbooks & Inventory db01 --- - name: Install

    “Mysql” hosts: db tasks: - name: ensure user mysql exists user: name=mysql - name: install mysql packages apt: name= mysql-server … … - name: create DB user mysql_user: > name=media password=“{{db_password}}” … - name: start service service: name=mysql # Inventory … [db]
 db01
  34. • Large(r) Community • hearsay: “Puppet breaks existing manifests even

    on minor versions” • an incredible amount of modules (quite some are not maintained and incompatible with Puppet 4.0) • using the “future parser” delivers error messages that are plain wtf? Maturity http://www.istockphoto.com/photo/favela-11677973
  35. • “New Kid on the block” (just bought by RedHat

    for 100M) • Ansible 2.0 is 99% backward compatible (though a complete rewrite internally) • a rather big amount of modules (but not as many as for Puppet) Maturity http://www.mikestimpson.com/photography/
  36. Setup 47 • You probably do not want to use

    master/slave • Install puppet on all nodes (or the agent) • Install git and check out your puppet manifests on all nodes (or register the agent with the master) • Install Ansible on one machine • Add an SSH key to the nodes and you are good to go
  37. Ease of Use “An advantage with Puppet is its large

    and mature community. Puppet was a great option for many years, however its user experience is now well behind that of Ansible and Salt. The learning curve is high and it feels heavy and over-engineered, but not quite as bad as Chef.” https://valdhaus.co/books/taste-test-puppet-chef-salt-stack-ansible.html cc-by licensed Flickr photo by Inha Leex Hale (http://www.flickr.com/photos/sixmilliondollardan/)
  38. Ease of Use http://www.istockphoto.com/photo/gears-19237781 “Love Ansible for its simplicity. For

    some reason it "just clicked" whereas I really struggled with Puppet / Chef / or old-school shell scripts. (That says more about me than Puppet and Chef) For me, YAML files and fantastic documentation made more sense than the DSLs of the other two.” https://news.ycombinator.com/item?id=9327970
  39. Ease of Use 51 Learning Curve “An advantage with Puppet

    is its large and mature community. Puppet was a great option for many years, however its user experience is now well behind that of Ansible and Salt. The learning curve is high and it feels heavy and over-engineered, but not quite as bad as Chef.” “Love Ansible for its simplicity. For some reason it "just clicked" whereas I really struggled with Puppet / Chef / or old-school shell scripts. (That says more about me than Puppet and Chef) For me, YAML files and fantastic documentation made more sense than the DSLs of the other two.” https://valdhaus.co/books/taste-test-puppet-chef-salt-stack-ansible.html https://news.ycombinator.com/item?id=9327970
  40. Ease of Use 52 Missing 1) Security 2) Enterprise features


    (Ansible Tower, Puppet Enterprise) 3) …
  41. 56