DEV Community

Janak Shrestha
Janak Shrestha

Posted on

Ansible Blockinfile Module

The Nautilus DevOps team wants to install and set up a simple httpd web server on all app servers in Stratos DC. Additionally, they want to deploy a sample web page for now using Ansible only. Therefore, write the required playbook to complete this task. Find more details about the task below.

We already have an inventory file under /home/thor/ansible directory on jump host. Create a playbook.yml under /home/thor/ansible directory on jump host itself.

  1. Using the playbook, install httpd web server on all app servers. Additionally, make sure its service should up and running.

  2. Using blockinfile Ansible module add some content in /var/www/html/index.html file. Below is the content:

    Welcome to XfusionCorp!

    This is Nautilus sample file, created using Ansible!

    Please do not modify this file manually!

  3. The /var/www/html/index.html file's user and group owner should be apache on all app servers.

  4. The /var/www/html/index.html file's permissions should be 0644 on all app servers.

Note:

i. Validation will try to run the playbook using command ansible-playbook -i inventory playbook.yml so please make sure the playbook works this way without passing any extra arguments.

ii. Do not use any custom or empty marker for blockinfile module.


📋 Introduction

In the world of DevOps, automation is the cornerstone of efficiency and consistency. The Nautilus DevOps team recently needed to deploy a simple HTTPD web server across all application servers in the Stratos DC with a sample web page. Instead of manually configuring each server, we leveraged Ansible's powerful automation capabilities—specifically the blockinfile module—to complete this task seamlessly.

This blog post documents the complete process, from understanding the requirements to successful deployment and verification.


🎯 The Challenge

The team had specific requirements for all application servers:

Component Requirement
Web Server HTTPD (Apache) installed
Service Status Running and enabled on boot
Web Page Location /var/www/html/index.html
Content Specific welcome message
File Owner apache:apache
File Permissions 0644 (rw-r--r--)
Content Module blockinfile with default markers

Content to Deploy

Welcome to XfusionCorp!

This is  Nautilus sample file, created using Ansible!

Please do not modify this file manually!
Enter fullscreen mode Exit fullscreen mode

🛠️ The Solution: Ansible Playbook

Complete Playbook

---
- name: Deploy HTTPD web server with sample page
  hosts: all
  gather_facts: yes

  tasks:
    # Task 1: Install httpd web server
    - name: Install httpd web server
      package:
        name: httpd
        state: present
      become: yes

    # Task 2: Start and enable httpd service
    - name: Start and enable httpd service
      service:
        name: httpd
        state: started
        enabled: yes
      become: yes

    # Task 3: Create web root directory
    - name: Create web root directory
      file:
        path: /var/www/html
        state: directory
        mode: '0755'
        owner: apache
        group: apache
      become: yes

    # Task 4: Add content using blockinfile module
    - name: Add content to index.html using blockinfile
      blockinfile:
        path: /var/www/html/index.html
        block: |
          Welcome to XfusionCorp!

          This is  Nautilus sample file, created using Ansible!

          Please do not modify this file manually!
        create: yes
        owner: apache
        group: apache
        mode: '0644'
        state: present
      become: yes
Enter fullscreen mode Exit fullscreen mode

Playbook Breakdown

1. Package Installation

- name: Install httpd web server
  package:
    name: httpd
    state: present
  become: yes
Enter fullscreen mode Exit fullscreen mode

Uses the package module to install HTTPD. The package module intelligently chooses the appropriate package manager (yum, apt, etc.) based on the target system.

2. Service Management

- name: Start and enable httpd service
  service:
    name: httpd
    state: started
    enabled: yes
  become: yes
Enter fullscreen mode Exit fullscreen mode

Ensures the HTTPD service is both running (state: started) and configured to start automatically on boot (enabled: yes).

3. Web Root Directory Setup

- name: Create web root directory
  file:
    path: /var/www/html
    state: directory
    mode: '0755'
    owner: apache
    group: apache
  become: yes
Enter fullscreen mode Exit fullscreen mode

Creates the web root directory with proper permissions and ownership.

4. Content Management with Blockinfile

- name: Add content to index.html using blockinfile
  blockinfile:
    path: /var/www/html/index.html
    block: |
      Welcome to XfusionCorp!

      This is  Nautilus sample file, created using Ansible!

      Please do not modify this file manually!
    create: yes
    owner: apache
    group: apache
    mode: '0644'
    state: present
  become: yes
Enter fullscreen mode Exit fullscreen mode

The blockinfile module:

  • Inserts a block of text into a file
  • Uses default markers (# BEGIN ANSIBLE MANAGED BLOCK and # END ANSIBLE MANAGED BLOCK)
  • Creates the file if it doesn't exist (create: yes)
  • Sets ownership and permissions in one task
  • Is idempotent—won't duplicate content if re-run

🚀 Execution and Results

Running the Playbook

cd /home/thor/ansible
ansible-playbook -i inventory playbook.yml
Enter fullscreen mode Exit fullscreen mode

Successful Output

PLAY [Deploy HTTPD web server with sample page] *********************************

TASK [Gathering Facts] **********************************************************
ok: [stapp01]
ok: [stapp02]
ok: [stapp03]

TASK [Install httpd web server] *************************************************
changed: [stapp01]
changed: [stapp02]
changed: [stapp03]

TASK [Start and enable httpd service] *******************************************
changed: [stapp01]
changed: [stapp02]
changed: [stapp03]

TASK [Create web root directory] ************************************************
changed: [stapp01]
changed: [stapp02]
changed: [stapp03]

TASK [Add content to index.html using blockinfile] *****************************
changed: [stapp01]
changed: [stapp02]
changed: [stapp03]

PLAY RECAP *********************************************************************
stapp01 : ok=5 changed=4 unreachable=0 failed=0 skipped=0
stapp02 : ok=5 changed=4 unreachable=0 failed=0 skipped=0
stapp03 : ok=5 changed=4 unreachable=0 failed=0 skipped=0
Enter fullscreen mode Exit fullscreen mode

🔍 Verification

File Existence and Permissions

$ ansible -i inventory all -m shell -a "ls -la /var/www/html/index.html" --become

stapp01 | CHANGED | rc=0 >>
-rw-r--r-- 1 apache apache 179 Aug 30 13:55 /var/www/html/index.html

stapp02 | CHANGED | rc=0 >>
-rw-r--r-- 1 apache apache 179 Aug 30 13:55 /var/www/html/index.html

stapp03 | CHANGED | rc=0 >>
-rw-r--r-- 1 apache apache 179 Aug 30 13:55 /var/www/html/index.html
Enter fullscreen mode Exit fullscreen mode

✅ Permissions: 0644 (rw-r--r--)
✅ Owner: apache:apache

File Content with Markers

$ ansible -i inventory all -m shell -a "cat /var/www/html/index.html" --become

stapp01 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
Welcome to XfusionCorp!

This is  Nautilus sample file, created using Ansible!

Please do not modify this file manually!
# END ANSIBLE MANAGED BLOCK
Enter fullscreen mode Exit fullscreen mode

✅ Content: Matches requirements exactly
✅ Markers: Default markers added automatically by blockinfile

Service Status

$ ansible -i inventory all -m shell -a "systemctl status httpd" --become

stapp01 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
   Active: active (running) since Sun 2026-08-30 13:55:49 UTC
Enter fullscreen mode Exit fullscreen mode

✅ Service: Active (running)
✅ Enabled: Boot startup configured


📊 Comparison: Before vs After

Aspect Before After
HTTPD Installed ❌ Not installed ✅ Installed on all servers
Service Running ❌ Not running ✅ Active and running
Web Root Directory ❌ Not present ✅ Created with correct permissions
index.html ❌ Missing ✅ Created with correct content
File Owner N/A ✅ apache:apache
File Permissions N/A ✅ 0644
Content Markers N/A ✅ Default markers present

💡 Key Learnings

1. The Power of Blockinfile

The blockinfile module is perfect for managing configuration files or content blocks. Key benefits:

  • Idempotent: Safe to run multiple times
  • Default Markers: Provides clear boundaries for managed content
  • Single Task: Handles creation, content insertion, and permissions in one go

2. Idempotency in Action

Running the playbook multiple times won't cause issues:

  • First Run: Creates everything (changed=4)
  • Second Run: Verifies everything (ok=5, changed=0)

3. Host Pattern Flexibility

Using hosts: all ensures the playbook works regardless of inventory group structure.

4. Service State Management

Combining state: started and enabled: yes ensures both immediate availability and persistence across reboots.


📋 Complete Verification Commands

# Check file exists and permissions
ansible -i inventory all -m shell -a "ls -la /var/www/html/index.html" --become

# Check content with markers
ansible -i inventory all -m shell -a "cat /var/www/html/index.html" --become

# Check ownership
ansible -i inventory all -m shell -a "stat -c '%U:%G' /var/www/html/index.html" --become

# Check permissions
ansible -i inventory all -m shell -a "stat -c '%a' /var/www/html/index.html" --become

# Check service status
ansible -i inventory all -m shell -a "systemctl status httpd" --become

# Test web server response
ansible -i inventory all -m shell -a "curl -s http://localhost/ | head -3" --become
Enter fullscreen mode Exit fullscreen mode

🎉 Conclusion

The Ansible playbook successfully automated the HTTPD web server deployment across all application servers with:

Simple Setup: Just one playbook file
Consistent Results: Same configuration on all servers
Proper Permissions: apache:apache ownership with 0644 permissions
Correct Content: The exact message with default markers
Service Management: Running and enabled on boot
Idempotency: Safe to run multiple times

Business Benefits

  • Time Savings: Automated what would be a 15-minute manual task per server
  • Consistency: No configuration drift between servers
  • Reliability: Idempotent execution ensures predictable results
  • Maintainability: Easy to update content or configuration
  • Documentation: Playbook serves as living documentation

Next Steps

  1. Add SSL/TLS Configuration for secure connections
  2. Implement Virtual Hosts for multiple websites
  3. Add Health Checks for monitoring
  4. Integrate with CI/CD for automated deployments
  5. Add Content Security Policies

📚 Resources


"Automation is not about eliminating human effort, but about maximizing human potential." 🚀


Top comments (0)