DevOps Day 93: Using Ansible Conditionals¶
This document outlines the solution for DevOps Day 93. The objective was to create a single Ansible playbook that runs on all hosts but performs different file copy operations depending on the specific server node name using the when conditional statement.
Table of Contents¶
- DevOps Day 93: Using Ansible Conditionals
- Table of Contents
- Task Overview
- Step-by-Step Solution
- Deep Dive: Ansible Concepts Used
- Troubleshooting
Task Overview¶
Objective: Distribute specific files to specific App Servers using a single playbook targeting all hosts.
Requirements:
1. Playbook: Create /home/thor/ansible/playbook.yml.
2. Target: hosts: all.
3. Logic:
* If node is stapp01: Copy blog.txt to /opt/devops/. Owner: tony.
* If node is stapp02: Copy story.txt to /opt/devops/. Owner: steve.
* If node is stapp03: Copy media.txt to /opt/devops/. Owner: banner.
4. Permissions: All files must have mode 0655.
5. Condition: Use ansible_nodename or ansible_hostname variables.
Step-by-Step Solution¶
1. Verify Inventory¶
First, I verified the inventory file to ensure we could connect to all target servers.
Command:
cd /home/thor/ansible
cat inventory
2. Create the Playbook¶
I created the playbook using the copy module combined with the when conditional. This allows me to write one play for hosts: all, but selectively execute tasks.
Command:
vi playbook.yml
Content:
---
- name: Copy files using conditionals
hosts: all
become: yes
tasks:
- name: Show the nodename for debugging
debug:
msg: "Nodename is: {{ ansible_nodename }}"
- name: Copy blog.txt to app server 1
copy:
src: /usr/src/devops/blog.txt
dest: /opt/devops/blog.txt
owner: tony
group: tony
mode: '0655'
when: ansible_nodename == "stapp01.stratos.xfusioncorp.com"
- name: Copy story.txt to app server 2
copy:
src: /usr/src/devops/story.txt
dest: /opt/devops/story.txt
owner: steve
group: steve
mode: '0655'
when: ansible_nodename == "stapp02.stratos.xfusioncorp.com"
- name: Copy media.txt to app server 3
copy:
src: /usr/src/devops/media.txt
dest: /opt/devops/media.txt
owner: banner
group: banner
mode: '0655'
when: ansible_nodename == "stapp03.stratos.xfusioncorp.com"
3. Execute and Validate¶
I ran the playbook against the inventory.
Command:
ansible-playbook -i inventory playbook.yml
Output Analysis: The output clearly shows the conditional logic in action: * stapp01: Executed "Copy blog.txt", skipped "Copy story.txt", skipped "Copy media.txt". * stapp02: Skipped "Copy blog.txt", executed "Copy story.txt", skipped "Copy media.txt". * stapp03: Skipped "Copy blog.txt", skipped "Copy story.txt", executed "Copy media.txt".
Deep Dive: Ansible Concepts Used¶
The when Conditional¶
The when statement is Ansible's version of an if statement. It evaluates a Jinja2 expression. If the expression is true, the task runs. If false, the task is skipped.
* Syntax: when: variable == "value"
* Context: You do not need {{ }} brackets inside a when clause because it is already an implicit Jinja2 context.
Ansible Facts (ansible_nodename)¶
When Ansible runs (specifically the Gathering Facts task), it collects data about the remote system.
* ansible_hostname: Usually just the short hostname (e.g., stapp01).
* ansible_nodename or ansible_fqdn: Often the full Fully Qualified Domain Name (e.g., stapp01.stratos.xfusioncorp.com).
* Debugging: The debug task I added was crucial. It revealed that ansible_nodename returned the full domain name, not just stapp01. This allowed me to fix my when condition to match the exact string.
Troubleshooting¶
Issue: Tasks skipped on all hosts
* Cause: The conditional check didn't match. For example, checking when: ansible_nodename == "stapp01" when the actual value was stapp01.stratos.xfusioncorp.com.
* Fix: Use the debug module to print the variable (msg: "{{ ansible_nodename }}") and copy the exact value into your when statement.
Issue: "Permission denied"
* Cause: Writing to /opt/devops requires root privileges.
* Fix: Ensure become: yes is present at the play level.