Skip to main content

Ansible Playbooks

Shenzhen, China

Sections

Mandatory Sections

  • Target Section => Specify host group
  • Variable Section => List all variables used by the playbook
  • Task Section => List all tasks that need to be performed on hosts

Optional Sections

  • Handler Section
  • Loops
  • Conditionals
  • Until
  • Notify
nano test.yml
---
- hosts: test

vars:
package1 : "nginx"
package2 : "wget"

tasks:

- name: Installing NGINX
apt: pkg=nginx state=installed update_cache=true
become: true

- name: Installing WGET
apt: pkg={{ package2 }} state=installed update_cache=true
become: true

Check ansible-doc apt for details on what arguments can be used.

The value of state can be one of: absent, build-dep, fixed, latest, present

In the example above I am installing wget from the variable package2 as defined above. THis does not make a difference here, but will become important when you start writing playbooks for different host systems where the same package is listed under a different name. We can than use a JinJa script to determine the host system from the Ansible facts and set the variable package2 for example to httpd or apache2 to install Apache on a CentOS and Debian system with the same playbook.

The become: true directive means that the package is installed with sudo - since I am locked in with my root account this is not necessary. But I will leave it in here. Going to need this in the future.

I can run this playbook with:

ansible-playbook test.yml

Before I used the copy command to copy a file from my host to the remote system. We can now re-write this ad hoc command as a task inside the playbook:

---
- hosts: test

vars:
package1 : "nginx"
package2 : "wget"

tasks:
- name: Installing NGINX
apt: pkg={{ package1 }} state=present update_cache=true
become: true

- name: Installing WGET
apt: pkg={{ package2 }} state=present update_cache=true
become: true

- name: Copying test config file
copy: src=/opt/ansible/playbooks dest=/opt/test2
ansible-playbook test.yml


PLAY [test] *********************************************************

TASK [Gathering Facts] **********************************************
ok: [192.168.2.111]

TASK [Installing NGINX] *********************************************
changed: [192.168.2.111]

TASK [Installing WGET] **********************************************
ok: [192.168.2.111]

TASK [Copying test config file] *************************************
changed: [192.168.2.111]

PLAY RECAP **********************************************************
2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Loops

We can also combine the two install steps using a loop:

---
- hosts: test
tasks:

- name: Installing NGINX, wget
apt: name={{ item }} state=present update_cache=true
with_items:
- nginx
- wget

- name: Copying test config file
copy: src=/opt/ansible/playbooks dest=/opt/test2

Handler

I now want to stop the NGINX service after the installation, copy over configuration files and than instruct a handler to restart the service - for this I created a new file nginx-ingress.yml in /opt/ansible/playbooks.

The NGINX configuration files can be found here: gatsby-multilang-template

---
- hosts: test
tasks:
- name: Aptitude Update
apt: update_cache=yes

- name: Installing NGINX
apt: pkg=nginx state=present update_cache=no

- name: Stop NGINX Service
service: name=nginx state=stopped

- name: Copying nginx.conf
copy:
src=/opt/test-static/nginx/nginx.conf
dest=/etc/nginx/nginx.conf
notify:
- Start NGINX

- name: Copy the entire content of the conf.d directory
copy:
src=/opt/test-static/nginx/conf.d/
dest=/etc/nginx/conf.d
notify:
- Start NGINX

- name: Copy only the applicable certificates from the ssl directory
copy:
src=/opt/test-static/nginx/ssl/{{item}}
dest=/etc/nginx/ssl/
with_items:
['dhparam.pem','nginx-selfsigned.crt','nginx-selfsigned.key']
notify:
- Start NGINX

handlers:
- name: Start NGINX
service: name=nginx state=started
ansible-playbook nginx-ingress.yml


PLAY [test] ************************************************************
TASK [Gathering Facts] *************************************************
ok: [192.168.2.111]

TASK [Installing NGINX] ************************************************
changed: [192.168.2.111]

TASK [Stop NGINX Service] **********************************************
changed: [192.168.2.111]

TASK [Copying nginx.conf] **********************************************
changed: [192.168.2.111]

TASK [Copy the entire content of the conf.d directory] *****************
changed: [192.168.2.111]

TASK [Copy only the applicable certificates from the ssl directory] ************************************************************************
changed: [192.168.2.111] => (item=dhparam.pem)
changed: [192.168.2.111] => (item=nginx-selfsigned.crt)
changed: [192.168.2.111] => (item=nginx-selfsigned.key)

RUNNING HANDLER [Start NGINX] ******************************************
changed: [192.168.2.111]

PLAY RECAP ***************************************************************
192.168.2.111: ok=1 changed=8 unreachable=0 failed=0 skipped=0

Copy Loop

Combining the Copy commands using an Ansible loop.

I also had to add the nginx user required by the NGINX configuration file that I am using.

---
- hosts: test
tasks:
- name: Aptitude Update
apt: update_cache=yes

- name: Add NGINX user
user:
name: nginx
comment: NGINX User
group: nginx
shell: /bin/sh
home: /home/nginx

- name: Installing NGINX
apt: pkg=nginx state=present update_cache=no

- name: Stop NGINX Service
service: name=nginx state=stopped

- name: Copy the NGINX Configuration
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{item.mode}}"
with_items:
- { src: '/opt/test-static/nginx/nginx.conf',dest: '/etc/nginx/nginx.conf', mode: '0664'}
- { src: '/opt/test-static/nginx/conf.d/',dest: '/etc/nginx/conf.d', mode: '0664'}
- { src: '/opt/test-static/nginx/ssl/',dest: '/etc/nginx/ssl', mode: '0664'}
notify:
- Start NGINX

handlers:
- name: Start NGINX
service: name=nginx state=restarted
# notify:
# - Verify that NGINX did not crash

# - name: Verify that NGINX did not crash
# shell: service nginx status
# register: result
# until: result.stdout.find("active (running)") != -1
# retries: 5
# delay: 5