Tabla de Contenidos

Best Practices

Inventory

Inventory - Use Human Meaningful Names

Poor                       Better
10.1.2.75                   db1 ansible_host=10.1.2.75
10.1.5.45                   db2 ansible_host=10.1.5.45

w14301.acme.com             web1 ansible_host=w14301.acme.com
w17802.acme.com             web2 ansible_host=w17802.acme.com

Inventory - Group Hosts Generously

[db]            
db[1:4]                      
                            
[web]            
web[1:4]                     

[east]
db1
web1
db3
web3

[dev]
db1
web1
                                 
[west]         
db2
web2            
db4            
web4
           
[testing]                              
db3
web3                                  
                                  
[prod]
db2
web2
db4
web4

--limit (see also --tags)

$ ansible-playbook site.yml --limit 'web'         # Only group web
$ ansible-playbook site.yml --limit 'web,db3'     # Group web and db3
$ ansible-playbook site.yml --limit 'all:!prod'   # All non group prod

Plays and Tasks

$ ls
acme_corp/
├── configure.yml
├── provision.yml
└── site.yml
$ cat site.yml
---
- import_playbook: provision.yml
- import_playbook: configure.yml

Blocks and Handlers

Handlers

Handlers Example

tasks:

  - name: Copy example conf to apache servers
    copy
      src: /var/lib/templates/demo.example.conf.template
      dest: /etc/httpd/conf.d/demo.example.conf
    notify:
      - restart_apache

handlers:

  - name: restart_apache
    service:
      name: httpd
      state: restarted

Plays and Tasks - Blocks

Block error handling example

tasks:
  - name: Attempt and gracefully roll back demo
    block:
      - debug:
        msg: "I execute normally"
      - command: /bin/false
      - debug:
        msg: "I never execute, due to the above task failing"
    rescue:
      - debug:
        msg: "I caught an error"
      - command: /bin/false
      - debug:
        msg: "I also never execute :-("
    always:
      - debug:
        msg: "this always executes"

Block run handlers in error handling

Another example is how to run handlers after an error occurred :

 tasks:

   - name: Attempt and gracefull roll back demo
     block:
       - debug:
           msg: "I execute normally"
         notify: run me even after an error
       - command: /bin/false
     rescue:
       - name: make sure all handlers run
         meta: flush_handlers
  handlers:
    - name: run me even after an error
      debug:
        msg: "this handler runs even on error"
        

Roles

Shared Roles Structure

myapp/
├── config.yml
├── provision.yml
├── roles
│   └── requirements.yml
└── setup.yml
$ ansible-galaxy install -r requirements.yml
$ cat requirements.yml

# from galaxy
- src: yatesr.timezone

# from GitHub
- src: https://github.com/bennojoy/nginx
  version: v1.4

# from a webserver, where the role is packaged in a tar.gz
- src: https://some.webserver.example.com/files/master.tar.gz
  name: http-role

Tasks - Order of Execution

Order of Execution Example

---
- hosts: remote.example.com
  pre_tasks:
    - shell: echo 'hello'
  roles:
    - role1
    - role2
  tasks:
    - shell: echo 'still busy'
  post_tasks:
    - shell: echo 'goodbye'

Templates

 {{ ansible_managed | comment }} 

Ansible Vault

[student@demo ~]$ ansible-playbook --ask-vault-pass site.yml
Vault password: redhat

Misc

Variables

Proper variable names can make plays more readable and avoid variable name conflicts

haproxy_max_keepalive: 25
haproxy_port: 80
tomcat_port: 8080

Smoke Tests

- name: check for proper response
  uri:
    url: http://localhost/myapp
    return_content: yes
  register: result
  until: '"Hello World" in result.content'
  retries: 10
  delay: 1

Plays and Tasks - Debugging

- debug:
   msg: "This always displays"

- debug:
   msg: "This only displays with ansible-playbook -vv+"
   verbosity: 2