Ansible Pilot

Deploy a web server apache httpd virtual host on Debian-like systems - Ansible modules apt, file, copy, template, command, ufw and service

How to automate the deployment of a web server apache httpd virtual host "example.com" on Debian-like systems with custom web page taking care of downloading, installing, and enabling the service instantly and on boot and open the relevant firewall ports with Ansible modules apt, file, copy, template, command, ufw, and service. Debian, Ubuntu all the similar distributions.

February 24, 2022
Access the Complete Video Course and Learn Quick Ansible by 200+ Practical Lessons

How to deploy a webserver apache httpd virtual host on Debian-like systems with Ansible?

I’m going to show you a live demo with some simple Ansible code. I’m Luca Berton and welcome to today’s episode of Ansible Pilot.

Deploy a web server apache httpd virtual host on Debian-like systems

Today we’re talking about how to Deploy a web server apache httpd on Debian-like Linux systems. The full process requires seven steps that you could automate with different Ansible modules. Firstly you need to install the apache2 package and dependency using the ansible.builtin.apt Ansible module. Secondly, you need to create the document root with the right permission with the ansible.builtin.file module. Thirsty, you need to create the custom index.html with the ansible.builtin.copy Ansible module. You could upgrade this step using the template module. Fourthly, you need to set up Apache configuration for the specific virtual host using the ansible.builtin.template module. Fifty, you need to enable a new site using the a2ensite via the ansible.builtin.command module. Sixty, you need to start the apache2 service and enable it on boot and all the dependant using the ansible.builtin.service Ansible module. Seventy you need to open the relevant firewall service-related ports using the community.general.ufw Ansible module.

The Best Resources For Ansible

Video Course

Books

demo

How to automate the deployment of a web server apache httpd virtual host on Debian-like systems with Ansible Playbook.

code

---
- name: setup webserver vhost
  hosts: all
  become: true
  vars:
    app_user: "www-data"
    http_host: "example.com"
    http_conf: "example.com.conf"
    http_port: "80"
    disable_default: true
  tasks:
    - name: apache installed
      ansible.builtin.apt:
        name: apache2
        update_cache: true
        state: latest

    - name: document root exist
      ansible.builtin.file:
        path: "/var/www/{{ http_host }}"
        state: directory
        owner: "{{ app_user }}"
        mode: '0755'

    - name: custom index.html
      ansible.builtin.copy:
        dest: "/var/www/{{ http_host }}/index.html"
        content: |
                    Custom Web Page

    - name: set up Apache virtualhost
      ansible.builtin.template:
        src: "templates/apache.conf.j2"
        dest: "/etc/apache2/sites-available/{{ http_conf }}"

    - name: enable new site
      ansible.builtin.command: "/usr/sbin/a2ensite {{ http_conf }}"
      notify: reload Apache

    - name: disable default Apache site
      ansible.builtin.command: "/usr/sbin/a2dissite 000-default.conf"
      when: disable_default
      notify: reload Apache

    - name: open firewall
      community.general.ufw:
        rule: allow
        port: "{{ http_port }}"
        proto: tcp

  handlers:
    - name: reload Apache
      ansible.builtin.service:
        name: apache2
        state: reloaded
<VirtualHost *:{{ http_port }}>
  ServerAdmin [email protected]
  ServerName {{ http_host }}
  ServerAlias www.{{ http_host }}
  ErrorLog ${APACHE_LOG}/error.log
  CustomLog ${APACHE_LOG}/access.log combined
  DocumentRoot "/var/www/{{ http_host }}"
</VirtualHost>

execution

ansible-pilot $ ansible-playbook -i virtualmachines/ubuntu/inventory services/httpd_debian_vhost.yml
PLAY [setup webserver] ****************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [ubuntu.example.com]
TASK [apache installed] ***************************************************************************
changed: [ubuntu.example.com]
TASK [document root exist] ************************************************************************
changed: [ubuntu.example.com]
TASK [custom index.html] **************************************************************************
changed: [ubuntu.example.com]
TASK [set up Apache virtualhost] ******************************************************************
changed: [ubuntu.example.com]
TASK [enable new site] ****************************************************************************
changed: [ubuntu.example.com]
TASK [disable default Apache site] ****************************************************************
changed: [ubuntu.example.com]
TASK [open firewall] ******************************************************************************
ok: [ubuntu.example.com]
RUNNING HANDLER [reload Apache] *******************************************************************
changed: [ubuntu.example.com]
PLAY RECAP ****************************************************************************************
ubuntu.example.com         : ok=9    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

(almost) idempotency

ansible-pilot $ ansible-playbook -i virtualmachines/ubuntu/inventory services/httpd_debian_vhost.yml
PLAY [setup webserver] ****************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [ubuntu.example.com]
TASK [apache installed] ***************************************************************************
ok: [ubuntu.example.com]
TASK [document root exist] ************************************************************************
ok: [ubuntu.example.com]
TASK [custom index.html] **************************************************************************
ok: [ubuntu.example.com]
TASK [set up Apache virtualhost] ******************************************************************
ok: [ubuntu.example.com]
TASK [enable new site] ****************************************************************************
changed: [ubuntu.example.com]
TASK [disable default Apache site] ****************************************************************
changed: [ubuntu.example.com]
TASK [open firewall] ******************************************************************************
ok: [ubuntu.example.com]
RUNNING HANDLER [reload Apache] *******************************************************************
changed: [ubuntu.example.com]
PLAY RECAP ****************************************************************************************
ubuntu.example.com         : ok=9    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

before execution

ansible-pilot $ ssh [email protected]
Last login: Thu Feb 24 11:21:41 2022 from 192.168.76.111
$ sudo su
[email protected]:/home/devops# cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
[email protected]:/home/devops# apt list apache2
Listing... Done
apache2/focal-updates,focal-security 2.4.41-4ubuntu3.9 amd64
apache2/focal-updates,focal-security 2.4.41-4ubuntu3.9 i386
[email protected]:/home/devops# apt list apache2 --installed
Listing... Done
[email protected]:/home/devops# dpkg -l | grep apache
[email protected]:/home/devops# cat /etc/apache2/sites-available/example.com.conf
cat: /etc/apache2/sites-available/example.com.conf: No such file or directory
[email protected]:/home/devops# ls -al /var/www/example.com
ls: cannot access '/var/www/example.com': No such file or directory
[email protected]:/home/devops# cat /var/www/example.com/index.html
cat: /var/www/example.com/index.html: No such file or directory
[email protected]:/home/devops# systemctl status apache2
Unit apache2.service could not be found.
[email protected]:/home/devops# ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To                         Action      From
--                         ------      ----
80/tcp                     ALLOW IN    Anywhere                  
22/tcp (OpenSSH)           ALLOW IN    Anywhere                  
80/tcp (v6)                ALLOW IN    Anywhere (v6)             
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
[email protected]:/home/devops#

after execution

ansible-pilot $ ssh [email protected]
Last login: Thu Feb 24 11:37:49 2022 from 192.168.76.111
$ sudo su
[email protected]:/home/devops# apt list apache2
Listing... Done
apache2/focal-updates,focal-security,now 2.4.41-4ubuntu3.9 amd64 [installed]
apache2/focal-updates,focal-security 2.4.41-4ubuntu3.9 i386
[email protected]:/home/devops# apt list apache2 --installed
Listing... Done
apache2/focal-updates,focal-security,now 2.4.41-4ubuntu3.9 amd64 [installed]
N: There is 1 additional version. Please use the '-a' switch to see it
[email protected]:/home/devops# apt list apache2 --installed -a
Listing... Done
apache2/focal-updates,focal-security,now 2.4.41-4ubuntu3.9 amd64 [installed]
apache2/focal 2.4.41-4ubuntu3 amd64
[email protected]:/home/devops# dpkg -l | grep apache2
ii  apache2                              2.4.41-4ubuntu3.9                     amd64        Apache HTTP Server
ii  apache2-bin                          2.4.41-4ubuntu3.9                     amd64        Apache HTTP Server (modules and other binary files)
ii  apache2-data                         2.4.41-4ubuntu3.9                     all          Apache HTTP Server (common files)
ii  apache2-utils                        2.4.41-4ubuntu3.9                     amd64        Apache HTTP Server (utility programs for web servers)
[email protected]:/home/devops# cat /etc/apache2/sites-available/example.com.conf 
<VirtualHost *:80>
   ServerAdmin [email protected]
   ServerName example.com
   ServerAlias www.example.com
   DocumentRoot /var/www/example.com
   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined
   DocumentRoot "/var/www/www.example.com"
</VirtualHost>[email protected]:/home/devops# ls -al /var/www/example.com/
total 12
drwxr-xr-x 2 www-data root 4096 Feb 24 11:37 .
drwxr-xr-x 4 root     root 4096 Feb 24 11:37 ..
-rw-r--r-- 1 root     root   16 Feb 24 11:37 index.html
[email protected]:/home/devops# cat /var/www/example.com/index.html 
Custom Web Page
[email protected]:/home/devops# systemctl status apache2
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-02-24 11:37:04 UTC; 2min 41s ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 4191 ExecReload=/usr/sbin/apachectl graceful (code=exited, status=0/SUCCESS)
   Main PID: 2318 (apache2)
      Tasks: 55 (limit: 1071)
     Memory: 5.7M
     CGroup: /system.slice/apache2.service
             ├─2318 /usr/sbin/apache2 -k start
             ├─4195 /usr/sbin/apache2 -k start
             └─4228 /usr/sbin/apache2 -k start
Feb 24 11:37:04 ubuntu systemd[1]: Starting The Apache HTTP Server...
Feb 24 11:37:04 ubuntu systemd[1]: Started The Apache HTTP Server.
Feb 24 11:37:12 ubuntu systemd[1]: Reloading The Apache HTTP Server.
Feb 24 11:37:13 ubuntu systemd[1]: Reloaded The Apache HTTP Server.
Feb 24 11:37:50 ubuntu systemd[1]: Reloading The Apache HTTP Server.
Feb 24 11:37:50 ubuntu systemd[1]: Reloaded The Apache HTTP Server.
[email protected]:/home/devops# ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To                         Action      From
--                         ------      ----
80/tcp                     ALLOW IN    Anywhere                  
22/tcp (OpenSSH)           ALLOW IN    Anywhere                  
80/tcp (v6)                ALLOW IN    Anywhere (v6)             
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
[email protected]:/home/devops# cat /var/log/apache2/access.log 
192.168.76.111 - - [24/Feb/2022:11:41:21 +0000] "GET / HTTP/1.1" 200 299 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
192.168.76.111 - - [24/Feb/2022:11:41:23 +0000] "GET / HTTP/1.1" 200 299 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
192.168.76.111 - - [24/Feb/2022:11:41:23 +0000] "GET /favicon.ico HTTP/1.1" 404 497 "http://ubuntu.example.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
192.168.76.111 - - [24/Feb/2022:11:41:23 +0000] "GET /apple-touch-icon-precomposed.png HTTP/1.1" 404 497 "-" "Safari/16612.2.9.1.30 CFNetwork/1240.0.4 Darwin/20.6.0"
192.168.76.111 - - [24/Feb/2022:11:41:23 +0000] "GET /apple-touch-icon.png HTTP/1.1" 404 496 "-" "Safari/16612.2.9.1.30 CFNetwork/1240.0.4 Darwin/20.6.0"
192.168.76.111 - - [24/Feb/2022:11:41:49 +0000] "GET / HTTP/1.1" 200 299 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
192.168.76.111 - - [24/Feb/2022:11:41:49 +0000] "GET /favicon.ico HTTP/1.1" 404 492 "http://192.168.76.32/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
192.168.76.111 - - [24/Feb/2022:11:42:14 +0000] "-" 408 0 "-" "-"
192.168.76.111 - - [24/Feb/2022:11:42:17 +0000] "GET / HTTP/1.1" 304 180 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
[email protected]:/home/devops#

web server apache httpd virtual host on Debian-like system

code with ❤️ in GitHub

Recap

Now you know how to deploy a webserver apache httpd virtual host on Debian-like systems with Ansible. Subscribe to the YouTube channel, Medium, Website, Twitter, and Substack to not miss the next episode of the Ansible Pilot.

Academy

Learn the Ansible automation technology with some real-life examples in my

My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps

BUY the Complete PDF BOOK to easily Copy and Paste the 200+ Ansible code

Want to keep this project going? Please donate

Access the Complete Video Course and Learn Quick Ansible by 200+ Practical Lessons
Trustpilot
Follow me

Subscribe not to miss any new releases

FREE Top 10 Best Practices

Top 10 Best Practices of Ansible Automation: save time, reduce errors and stress