Introduction to Ansible Playbooks
Ansible playbooks are YAML-formatted configuration files that define a series of tasks to be executed on managed nodes. Unlike ad hoc commands, playbooks provide a repeatable, reusable way to automate complex system configurations and deployments. They are the foundation of Ansible’s infrastructure-as-code approach.
📑 Table of Contents
- Introduction to Ansible Playbooks
- Understanding the HTTPD Installation Playbook
- Playbook Component Breakdown
- Task 1: Installing HTTPD Package
- Task 2: Starting and Enabling HTTPD Service
- Running the Playbook
- Verifying the Installation
- Enhanced Playbook with Firewall Configuration
- Playbook Best Practices
- Common Issues and Troubleshooting
- Conclusion
In this tutorial, we’ll create a simple but practical playbook that installs and starts the Apache HTTP Server (httpd) on a target system. This example demonstrates fundamental playbook concepts that you can apply to more complex automation scenarios.
Understanding the HTTPD Installation Playbook
Basic playbook structure and syntax
Below is a complete playbook that installs the httpd package and ensures the service is started and enabled at boot:
--- - hosts: ansiblenode2 become: yes tasks: - name: install httpd yum: name: httpd state: latest - name: start and enable httpd service: name: httpd state: started enabled: yes
Playbook Component Breakdown
Understanding each section of the playbook:
1. YAML Header (—)
The three dashes indicate the start of a YAML document. This is standard YAML syntax and should begin every playbook.
2. Hosts Declaration
- hosts: ansiblenode2
This line specifies which hosts or host groups the playbook will target. In this example, we’re targeting a single host named “ansiblenode2”. You could also use:
all
– Target all hosts in inventorywebservers
– Target a specific groupweb*
– Use wildcards for pattern matching
3. Privilege Escalation
become: yes
This directive tells Ansible to execute tasks with sudo privileges (become root). Installing packages and managing services requires root access, so this is essential for our playbook.
4. Tasks Section
The tasks section contains an ordered list of actions to be performed. Each task should have a descriptive name and use an Ansible module.
Task 1: Installing HTTPD Package
Using the yum module to install Apache
- name: install httpd yum: name: httpd state: latest
Parameters explained:
name
– Unique, descriptive identifier for the task (shown in output)yum
– Module for managing packages on RHEL/CentOS systemsname: httpd
– Package name to installstate: latest
– Ensures the latest version is installed
Alternative state options:
state: present
– Install if not already present (recommended for production)state: absent
– Remove the package if installedstate: latest
– Install or upgrade to the latest version
Task 2: Starting and Enabling HTTPD Service
Using the service module to manage Apache daemon
- name: start and enable httpd service: name: httpd state: started enabled: yes
Parameters explained:
service
– Module for managing system servicesname: httpd
– Service name to managestate: started
– Ensures the service is runningenabled: yes
– Configures service to start automatically at boot
This task is idempotent, meaning it can be run multiple times safely. If the service is already running, Ansible will not make any changes.
Running the Playbook
How to execute your playbook
Save the playbook content to a file (e.g., install_httpd.yml
) and run it with the ansible-playbook command:
[ansible@ansiblecontrolnode ~]$ ansible-playbook install_httpd.yml PLAY [ansiblenode2] **************************************************** TASK [Gathering Facts] ************************************************* ok: [ansiblenode2] TASK [install httpd] *************************************************** changed: [ansiblenode2] TASK [start and enable httpd] ****************************************** changed: [ansiblenode2] PLAY RECAP ************************************************************* ansiblenode2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The output shows:
- Gathering Facts: Ansible automatically collects system information
- install httpd: Package installation task (changed status indicates it was installed)
- start and enable httpd: Service management task (changed indicates it was started)
- PLAY RECAP: Summary showing 3 tasks succeeded with 2 changes
Verifying the Installation
Checking if Apache is running
After the playbook completes, verify that httpd is installed and running:
# Check httpd service status ansible ansiblenode2 -b -m shell -a "systemctl status httpd" # Verify httpd is listening on port 80 ansible ansiblenode2 -b -m shell -a "netstat -tulpn | grep :80" # Test the web server curl http://ansiblenode2
Enhanced Playbook with Firewall Configuration
Adding firewall rules for complete setup
For a production-ready installation, you should also configure the firewall to allow HTTP traffic:
--- - hosts: ansiblenode2 become: yes tasks: - name: install httpd yum: name: httpd state: present - name: start and enable httpd service: name: httpd state: started enabled: yes - name: allow http through firewall firewalld: service: http permanent: yes state: enabled immediate: yes - name: create a simple index.html copy: content: "Welcome to {{ ansible_hostname }}
" dest: /var/www/html/index.html owner: apache group: apache mode: 0644
This enhanced version includes:
- Firewall configuration using the firewalld module
- Creation of a custom index.html page
- Use of Ansible variables ({{ ansible_hostname }})
Playbook Best Practices
- Use descriptive task names: Clear names make debugging easier
- Prefer ‘present’ over ‘latest’: Avoid unexpected upgrades in production
- Always enable services: Ensure services survive reboots
- Check syntax before running: Use
ansible-playbook --syntax-check playbook.yml
- Test with –check mode: Dry-run with
ansible-playbook --check playbook.yml
- Use version control: Store playbooks in Git for tracking changes
- Add handlers for service restarts: Only restart services when configuration changes
Common Issues and Troubleshooting
Package installation fails:
- Ensure yum repositories are configured properly
- Check internet connectivity on target nodes
- Verify sudo privileges are configured correctly
Service won’t start:
- Check for port conflicts (another service using port 80)
- Review SELinux context and permissions
- Examine logs:
/var/log/httpd/error_log
Firewall blocking connections:
- Verify firewalld is running:
systemctl status firewalld
- Check firewall rules:
firewall-cmd --list-all
- Ensure http service is allowed
Conclusion
This simple playbook demonstrates the fundamental concepts of Ansible automation: declarative configuration, idempotency, and infrastructure as code. By installing and configuring Apache HTTP Server, you’ve learned how to combine multiple modules into a cohesive automation workflow.
As you become more comfortable with playbooks, you can expand this example to include:
- Virtual host configurations
- SSL certificate deployment
- Custom Apache modules
- Load balancer integration
- Monitoring and logging setup
The skills you’ve learned here form the foundation for managing complex infrastructure with Ansible. Keep practicing, and soon you’ll be automating entire application stacks!
Was this article helpful?