DevOps Day 88: Ansible Blockinfile Module¶
This document outlines the solution for DevOps Day 88. The objective was to use Ansible to install a web server (httpd) and deploy a sample index.html file using the blockinfile module, ensuring specific content, ownership, and permissions.
Table of Contents¶
- DevOps Day 88: Ansible Blockinfile Module
- Table of Contents
- Task Overview
- Step-by-Step Solution
- Deep Dive: Ansible Concepts Used
- Troubleshooting
Task Overview¶
Objective: Install httpd on all app servers and create /var/www/html/index.html with specific multi-line content using Ansible.
Requirements:
1. Playbook: Create /home/thor/ansible/playbook.yml.
2. Package: Install httpd and ensure the service is running/enabled.
3. Content: Use blockinfile to add the welcome message to index.html.
4. Permissions: File owner/group: apache, Mode: 0744.
5. Constraints: Do not use custom markers.
Step-by-Step Solution¶
1. Verify Inventory¶
Before writing the playbook, I ensured the inventory file existed and was correct.
Command:
cd /home/thor/ansible
ls -l
# Expected output: inventory file exists
2. Create the Playbook¶
I created the playbook to handle three main tasks: installing the package, starting the service, and managing the file content.
Command:
vi playbook.yml
Content:
---
- name: setup and configure httpd server
hosts: all
become: true
tasks:
- name: install httpd package
yum:
name: httpd
state: present
- name: start and enable httpd service
service:
name: httpd
state: started
enabled: yes
- name: add content to index.html using blockinfile
blockinfile:
path: /var/www/html/index.html
create: yes
block: |
Welcome to XfusionCorp!
This is Nautilus sample file, created using Ansible!
Please do not modify this file manually!
owner: apache
group: apache
mode: '0744'
3. Execute and Validate¶
I ran the playbook using the standard command.
Command:
ansible-playbook -i inventory playbook.yml
Output Analysis:
TASK [install httpd package] ********************************************************
ok: [stapp03]
ok: [stapp01]
changed: [stapp02]
TASK [add content to index.html using blockinfile] **********************************
changed: [stapp02]
ok: [stapp03]
ok: [stapp01]
Deep Dive: Ansible Concepts Used¶
The blockinfile Module¶
This module inserts, updates, or removes a block of multi-line text surrounded by marker lines.
* create: yes: If the file doesn't exist, create it. This effectively creates our index.html.
* block: |: The | character allows us to define a multi-line string in YAML, preserving newlines.
* Markers: By default, Ansible wraps the content in # BEGIN ANSIBLE MANAGED BLOCK and # END ANSIBLE MANAGED BLOCK. This makes it easy for Ansible to find and update this specific section later without overwriting the rest of the file.
Service Management¶
The service module ensures the web server is actually running.
* state: started: Starts the service immediately.
* enabled: yes: Ensures the service starts automatically if the server reboots.
Troubleshooting¶
Issue: "Shared connection closed" (rc 137)
* Context: In the provided logs, stapp02 initially failed with this error.
* Cause: This is often a transient SSH connection issue or resource limit (OOM kill) on the remote host during package installation.
* Fix: Re-running the playbook usually resolves it, as seen in the successful second run. Ansible is idempotent, so it picks up right where it left off.
Issue: "Destination directory /var/www/html does not exist"
* Cause: The httpd package creates this directory. If the install task fails or runs out of order, the directory won't exist for the blockinfile task.
* Fix: Ensure the yum task runs before the blockinfile task.