Ansible 101

Luke Sneeringer

Part 1: Exposition

  • Playbooks
    • A collection of tasks (but more)
    • If you have 10 servers and want to do them all at the same time, you need to specify which hosts you’ll do what
    • “inventory” is a way to specify what hosts are available
      • There are plugins for dynamic inventory (e.g. getting server lists from EC2)
      • Can also tag things based on the tag in EC2
    • Facts
      • Information about a machine (e.g. your IP addresss… you need this to write an /etc/hosts file or whatever)
      • nearly always start with “ansible_” (e.g. ansible_os_family: Debian, RedHat, etc.)
    • Exercise: create a playbook
  • Tasks
    • The fundamental building block of Ansible
    • Describes the state which shall have obtained (past perfect tense: happened in the past and is still in effect) on the machine
    • Idempotency!
      • Is NOT “machine, go thou and do X”.
      • Does mean, “machine, go thou and ensure that X is done”.
    • It’s not useful to us to have an orchestration layer that can only run once and then errors any time thereafter. That’s bad.
    • Described in YAML in a list
      • Each item is executed in sequence
      • If any task fails, Ansible ends
    ----
    - name: Ensure that my user exists. (This is like a comment)
      user:
        home: /home/luke
	name: luke
	shell: /bin/bash
	state: present
	system: no
  • Tasks (cont)
    • Can be run in any language and returns JSON
    • Modules take arguments
    • debug takes a msg argument, user takes about 20
    • Arguments are required, optional, or mutually exclusive
    • Language is idempotent language. e.g. “state: present”
    • Sometimes tasks are conditional
      • …only if the OS is Debian/Ubuntu
      • …only if it hasn’t run before
    • the when key takes an expresssion and runs it if it’s true
    ----
    - name Install Python 3.
      apt:
        pkg: python3
	state: present
      when: ansible_os_family == 'Debian'
  • Tasks (cont)
    • Idempotency
      • Should be idempotent whenever possible
      • Most provided Ansible modules are idepmotenet with little or no effort on your part
      • shell isn’t (obviously) because it cannot be
    • Opinions
      • Use the indented form for modules, not the long string form (Readability counts).
        • Doing this with shell requires args
      • When applicable, provide state explicitly
        • “started/loaded/stopped/latest”
      • Be consistent about the name
        • The name shows up in the Ansible run. It is your documentation and comments
    • Exercise
      • Create a user for you on the machine
      • Install python3 package from apt
      • Copy a file containing the text “Hello, world!” from your local machine to /home/you/hi.txt (copy module)
    • Conditional Execution
    ---
    - name: Install Python 3 (Debian)
      apt:
        pkg: python3
	state: present
      when: ansible_os_family == 'Debian'
  • Loops
    • Usually, loops perform the task a separate time for each item in the list
    ---
    - name: Say hello to all the places.
      debug:
        msg: Hello
      with:
        - foo
	- bar
	- blah
	- Canada
  • Exercise
    • Create a user for you and for me on the machine
    • install the python3, python3-dev and python3-pip packages from apt
    • in both cases, this should be a single task, using with_items
  • Roles
    • Ansible’s mechanism to provide reusable content
    • Roles must contain tasks
    • Roles may contain handlers, files, templates, etc.
    • They exists for encapsulation, and putting groups of tasks together and moving them around
    • Anatomy of a role
      • tasks
      • handlers
      • defaults, vars (vars gets preferences over defaults)
      • files, templates
      • Most of these directories should contain main.yml if they exist at all. (Exceptions: files, templates)
    • Relative paths look for things within the role, where you expect them
    • E.g. when using copy omdule, Ansible looks for files within the file dir
    • Reusability
      • Mix of reusable and non-reusable
      • Common uses for reusable roles:
        • compile and install software
        • configure utilities
        • e.g. install Python3 on every server we have
      • Application specific roles usually tie everything together at the end
      • Usually one non-reusable role per project that has all of the reusable ones as dependencies
      • “What is the scope where the role should be usable?” (E.g. what OS?)
      • “What configuration does the role require / allow?”
  • Templates
    • Mechanism to write files to a machine that include….
    • Variables look like: $$
    • Control block look like this:
    • Common blocks are if and for
    • Exercise
      • Write a file to /tmp/ with the following:
      • The machine hostname (ansible_hostname)
      • Each IPv4 address, one per line (ansible_all_ipv4_addresses)
      • Each IPv6 address one per line (ansible_all_ipv6_addresses)
  • Handlers
    • A way of having tasks be triggered at the end of a run (e.g. restarting services)
    • Special tasks using ‘notify’ and the handler’s name
    • Handlers are triggered ony if the triggering task causes a change
    • Use –force-handlers to still run handlers in the event of a failure
---
- name: apache.restart
  service:
    name: apache2
    state: restarted
  • Modules
    • You can write it in any language. Emits JSON on standard out.
    • Inheritance isn’t a thing. That’s not how it works.
    • There are common args that need to be used in lots of modules (e.g. owner, mode)
    • Exercise? Skipped
  • Plugins
    • Run on the machine running Ansible, not on the machine being orchestrated
    • Most of plugins you will never, ever use. Unless you’re doing really high-level orchestration.
    • Callback Plugins
    • Lookup Plugins
      • Author uses these the most
      • Custom ways to loop over things (e.g. with_)
      • E.g. wrote a custom plugin to loopup all of the users that were available on the system. Then you can say with_users in any playbook.
      • Module must have init and run methods
    • Filter Plugins
      • E.g. the default filter plugin where if a variable isn’t defined, it sets a default
      • You can define your own

Part 2: Project



blog comments powered by Disqus

Published

28 May 2016

Category

work

Tags