- Slides
-
Labs
- 1.0 - Setting up Ansible
- 2.0 - Documentation
- 3.0 - Setup and AdHoc Commands
- 4.0 - Ansible Playbooks - Basics
- 4.1 - Ansible Playbooks - Variables and Loops
- 4.2 - Ansible Playbooks - Templates
- 4.3 - Ansible Playbooks - Output
- 5.0 - Ansible Roles - Basics
- 5.1 - Ansible Roles - Handlers and Blocks
- 6.0 - Managing Secrets with Ansible Vault
- 7.0 - Ansible Galaxy and more
- About
- Setup
4.3 - Ansible Playbooks - Output
In this lab we learn how to handle output of tasks.
Task 1
- Write a playbook
output.yml
that uses the command module to find all config files of postfix. These files are located under/etc/postfix/
and end with.cf
. Targeted server isnode1
. - Register the result to a variable called
output
by using theregister
keyword. - Include a task using the debug module to print out all content of the variable
output
. If unsure, consult the documentation about the debug module.
Task 2
- Add another task to the playbook
output.yml
using the debug module and print out the resulting filenames of the search above.
Use an appropriate return value to show the output. Information about return values can be found here: Ansible Docs - Common Return Values
- Now, loop over the results and create a backup file called
<filename.cf>.bak
for each file<filename.cf>
that was found. Use the command module. Remember, that the result is probably a list with multiple elements.
Task 3 (Advanced)
- Now we enhance our playbook
output.yml
to only create the backup if no backup file is present. - Solve this task by searching for files ending with
.bak
and registering the result to a variable. Then do tasks only if certain conditions are met.
Have a look at the documentation about conditionals: Ansible Docs - Playbook Conditionals
Task 4 (Advanced)
- Ensure
httpd
is stopped by using an ansible ad hoc command. - Write a play
servicehandler.yml
that does the following: - Install
httpd
by using theyum
module - Start the service
httpd
with thecommand
module. Don’t useservice
orsystemd
module. - Start the service only if it is not started and running already. (The output of
systemctl status httpd
doesn’t contains the stringActive: active (running)
)
systemctl status
returns status failed
when a service is not running. Therefore we use ignore_errors: true
in the corresponding task to let Ansible continue anyways.
Task 5 (Advanced)
- Rewrite the playbook
servicehandler.yml
and ensure that theignore_errors: true
line is removed. Instead set the state of the task to failed when and only when the output ofsystemctl status httpd
contains the string “failed”.
Have a look at the documentation about error handling: Ansible Docs - Playbooks Error Handling
- Rerun your playbook and ensure it still runs fine.
- By using an ansible ad hoc command, place an invalid configuration file
/etc/httpd/conf/httpd.conf
and backup the file before. Use the copy module to do this in ad hoc command. - Restart
httpd
by using an ansible ad hoc command. This should fail since the config file is not vaild. - Rerun your playbook and ensure it fails.
- Fix the errors in the config file, restart httpd on node1 and rerun your playbook. Everything should be fine again.
Solutions
Documentation about debug module
Example output.yml
:
---
- hosts: node1
become: true
tasks:
- name:
command: "find /etc/postfix -type f -name *.cf"
register: output
- debug:
var: output
Example output.yml
:
---
- hosts: node1
become: true
tasks:
- name:
command: "find /etc/postfix -type f -name *.cf"
register: output
- debug:
var: output.stdout_lines
- name: create backup
command: "cp {{ item }} {{ item }}.bak"
with_items: "{{ output.stdout_lines }}"
Example output.yml
:
---
- hosts: node1
become: true
tasks:
- name:
command: "find /etc/postfix -type f -name *.cf.bak"
register: search
- name:
command: "find /etc/postfix -type f -name *.cf"
register: output
- name: create backup only when no backupfile is present
command: "cp {{ item }} {{ item }}.bak"
with_items: "{{ output.stdout_lines }}"
# only do this if there is no .bak for file: item
when: search.stdout.find(item) == -1
Stop the httpd service with Ansible:
$ ansible web -b -a "systemctl stop httpd"
Content of servicehandler.yml
:
---
- hosts: web
become: yes
tasks:
- name: install httpd
yum:
name: httpd
state: present
- name: check state of service httpd
command: 'systemctl status httpd'
register: status
ignore_errors: true
- debug:
var: status.stdout
- name: start httpd
command: 'systemctl start httpd'
when: "'Active: active (running)' not in status.stdout"
Example servicehandler.yml
:
---
- hosts: web
become: yes
tasks:
- name: install httpd
yum:
name: httpd
state: present
- name: check state of service httpd
command: 'systemctl status httpd'
register: status
failed_when: "'failed' in status.stdout"
- debug:
var: status.stdout
- name: start httpd
command: 'systemctl start httpd'
when: "'Active: active (running)' not in status.stdout"
$ ansible web -b -m copy -a "content='bli bla blup' dest=/etc/httpd/conf/httpd.conf backup=yes"
$ ansible web -b -m service -a "name=httpd state=restarted"