IT 3110: System Automation

Ansible Playbooks

Ansible Playbooks (YAML)

  • similar to JSON
  • start of file has 3 dashes at beginning ---
  • comments start with #
  • strings can be quoted or not
  • booleans can be True or Yes

Ansible Playbooks Indentation

Indentation is very important. Here is a simple .vimrc file that can help indent for you

    syntax on
    filetype indent plugin on
    set modeline
    set paste
    filetype plugin indent on
    " On pressing tab, insert 2 spaces
    set expandtab
    " show existing tab with 2 spaces width
    set tabstop=2
    set softtabstop=2
    " when indenting with '>', use 2 spaces width
    set shiftwidth=2
    autocmd FileType yaml setlocal ai ts=2 sw=2 et colorcolumn=1,3,5,7,9,11,13 nu

Ansible Playbooks (YAML)

  • Lists (are like lists in Python)

      ---
      # A list of tasty fruits
      fruits:
          - Apple
          - Orange
          - Strawberry
          - Mango
    
  • Abbreviated form

    • fruits: ['Apple', 'Orange', 'Strawberry', 'Mango']

Ansible Playbooks (YAML)

  • Dictionaries (are like Python dictionaries)

      # An employee record
      martin:
          name: Martin D'vloper
          job: Developer
          skill: Elite
    
  • Abbreviated form

    • martin: {name: Martin D'vloper, job: Developer, skill: Elite}

Ansible Playbooks

  • Each playbook is composed of one or more ‘plays’ in a list.
  • The goal of a play is to execute some tasks against a group of hosts
  • A task is essentially a call to an ansible module
  • By composing a playbook of multiple ‘plays’, it is possible to orchestrate multi-machine deployments, running certain steps on all machines in the webservers group, then certain steps on the database server group, then more commands back on the webservers group, etc.

Ansible Playbooks

IN other words, a playbook consists of one or more plays. A play consists of one or more tasks.

Ansible will execute plays in order of hosts file. Can use sorted option if you want to execute alphabetically. (shuffle, reverse_sorted, etc...)

Ansible Playbooks (One play)

    ---
    - hosts: webservers
      vars:
        http_port: 80
        max_clients: 200
      remote_user: root
      tasks:
      - name: ensure apache is at the latest version
        yum: name=httpd state=latest
      - name: write the apache config file
        template: src=/srv/httpd.j2 dest=/etc/httpd.conf
        notify:
        - restart apache
      - name: ensure apache is running (and enable it at boot)
        service: name=httpd state=started enabled=yes
      handlers:
        - name: restart apache
          service: name=httpd state=restarted

Ansible Playbooks (multiple plays)

    ---
    - hosts: webservers
      remote_user: root
    
      tasks:
      - name: ensure apache is at the latest version
        yum: name=httpd state=latest
      - name: write the apache config file
        template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    
    - hosts: databases
      remote_user: root
    
      tasks:
      - name: ensure postgresql is at the latest version
        yum: name=postgresql state=latest
      - name: ensure that postgresql is started
        service: name=postgresql state=started

Ansible Playbooks (Example) (How many plays?)

    - name: Configure webserver with nginx
      hosts: webservers
      become: True
      tasks:
        - name: install nginx
          apt: name=nginx update_cache=yes
    
        - name: copy nginx config file
          copy: src=files/nginx.conf dest=/etc/nginx/sites-available/default
    
        - name: enable configuration
          file: >
            dest=/etc/nginx/sites-enabled/default
            src=/etc/nginx/sites-available/default
            state=link
    
        - name: copy index.html
          template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
            mode=0644
    
        - name: restart nginx
          service: name=nginx state=restarted

Ansible Playbooks (basics)

For each play, we can choose what target hosts the tasks should be executed on.

    ---
    - hosts: webservers
      remote_user: root  #who to do this as on remote system
  • Remote users can also be defined on a per-task basis

Ansible Playbooks (remote users)

Can become another user (on a play, or on individual task)

    ---
    - hosts: webservers
      remote_user: yourname
      become: yes
      become_user: fred #default value here is root

Ansible Playbooks (tasks)

  • Tasks will be executed sequentially against all the hosts indicated.
  • Within a play, all hosts will have same tasks
  • If a host fails a task, they are taken out of play for the remainder of playbook.
  • Modules should be idempotent, that is, running a module multiple times in a sequence should have the same effect as running it just once. (rerunning a playbook shouldn't hurt things)

Ansible Playbooks (example task)

    tasks:
      - name: make sure apache is running
        service: name=httpd state=started

Ansible Playbooks (task handler)

A task handler will run when notified. A notification is sent when a previous task has caused a change.

    - name: template configuration file
      template: src=template.j2 dest=/etc/foo.conf
      notify:
         - restart memcached  #this is a handler
         - restart apache     #another handler

The two services will be restarted if the contents of the above file has changed.

Ansible Playbooks (handler section)

To run the aforementioned handlers, you have to have a handler section:

    handlers:
        - name: restart memcached
          service: name=memcached state=restarted
        - name: restart apache
          service: name=apache state=restarted

Ansible Playbooks (other handler example)

    handlers:
        - name: restart memcached
          service: name=memcached state=restarted
          listen: "restart web services"
        - name: restart apache
          service: name=apache state=restarted
          listen: "restart web services"
    
    tasks:
        - name: restart everything
          command: echo "this task will restart the web services"
          notify: "restart web services"

Ansible Playbooks (How to run)

    ansible-playbook playbook.yml