preloader
  • Home
  • How to Create Your First Ansible Playbook to Deploy an Apache Web Server

Ansible is a powerful automation tool that simplifies IT management. In this guide, you’ll learn how to create your first Ansible playbook to deploy an Apache web server inside a Podman container running on Alpine Linux. This step-by-step tutorial is perfect for beginners looking to automate containerized deployments efficiently.

blog-thumb

📖 Estimated reading time: 4 min


Create an Ansible Playbook to Deploy an Apache Web Server

It’s not as complicated as you might think. Automating infrastructure with Ansible can save time and eliminate manual setup errors.

If you’re new to Ansible, a great first project is deploying a web server in a container. In this tutorial, you’ll learn how to create an Ansible playbook that installs Podman, launches an Alpine Linux container, sets up Apache, and serves a simple “Hello World” page.

All this is done in 5 simple steps. Don’t believe me? Read on.

By the end of this guide, you’ll have a fully functional web server running on port 8080, accessible from your browser. All with just a single Ansible command.

Let’s get started! 🚀


Prerequisites

In this lab I’ll be using Ubuntu. But you can use any Linux distribution. The result will be the same.

Before running the playbook, ensure you have:

* Ansible installed on your machine

* A target system with Podman installed (or let the playbook install it)

* SSH access to the target system


Step-by-Step: Writing the Ansible Playbook

Create a new file named apache_container.yml and add the following content:

 
- name: Deploy Apache in a Podman Container
  hosts: servers
  become: yes
  tasks:
    - name: Install Podman
      package:
        name: podman
        state: present

    - name: Create an Apache container
      containers.podman.podman_container:
        name: apache_container
        image: docker.io/httpd:alpine
        state: started
        recreate: yes
        restart_policy: always
        detach: true
        ports:
          - "8080:80"

    - name: Copy index.html to the container
      command: podman cp index.html apache_container:/usr/local/apache2/htdocs/index.html
        

✅ I know you could just use the “copy” module. However, the example only uses command to show how the reader could do more activities in this example playbook.



Deploying Your Apache Container

1) Install Ansible


 $ apt install ansible-core
 

2) Configure Ansible Inventory

Ensure your target server is listed under the [servers] group in your inventory file.

* If you’re running the Ansible playbook on localhost, your inventory file (inventory.ini) should look like this:


 [servers]
 localhost ansible_connection=local
 

3) Create the Web Server index.html page.

I’ve made this neat page for you. 😎


  $ cat index.html

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>My First Ansible Page</title>
      <style>
          body {
              text-align: center;
              font-family: Arial, sans-serif;
          }

          img {
              margin-bottom: 20px;
          }

          img {
              max-width: 100%;
              height: auto;
          }

          .info {
              margin-top: 20px;
              font-size: 1.2em;
          }
      </style>
  </head>
  <body>
      <img src="https://raw.githubusercontent.com/ansible/logos/refs/heads/main/community-logo/Ansible-Community-Logo-RGB-Black.png" alt="Ansible Logo">

      <h1>Hello World! This is my first Ansible Playbook!</h1>

      <div class="info">
          <p><strong>Current Date and Time:</strong> <span id="datetime">Loading...</span></p>
      </div>

      <script>
          function updateDateTime() {
              var currentDate = new Date();
              var dateStr = currentDate.toLocaleString();
              document.getElementById('datetime').innerText = dateStr;
          }
          setInterval(updateDateTime, 1000);
      </script>
  </body>
  </html>
 

By the way, you can find all these files on our public github.


4) Run the Playbook using the following command:

 
 $ ansible-playbook -i inventory.ini apache_container.yml
 

Running the playbook generates messages similar to these:

Ansible Playbook Running

5) Access Your Web Server

Open a browser and go to:

 
 http://<server-ip>:8080
 

You should see your “Hello World! This is my first Ansible Playbook!” message displayed. 🎉

Ansible Playbook Running

It was easier than you thought, wasn’t it? 😃



The Running Container

You can see the resources created and running using commands like these:


  $ podman ps
   
  CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS         PORTS                 NAMES
  6375dce19dde  docker.io/library/httpd:alpine  httpd-foreground  12 minutes ago  Up 12 minutes  0.0.0.0:8080->80/tcp  apache_container
   

  $ podman images

  REPOSITORY               TAG         IMAGE ID      CREATED      SIZE
  docker.io/library/httpd  alpine      fcd9ece3a2cc  4 weeks ago  66.2 MB
   

  $ podman logs apache_container | tail -10

  AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.31. Set the 'ServerName' directive globally to suppress this message
  AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.31. Set the 'ServerName' directive globally to suppress this message
  [Sun Feb 23 21:43:41.514018 2025] [mpm_event:notice] [pid 1:tid 1] AH00489: Apache/2.4.63 (Unix) configured -- resuming normal operations
  [Sun Feb 23 21:43:41.514061 2025] [core:notice] [pid 1:tid 1] AH00094: Command line: 'httpd -D FOREGROUND'
  X.X.X.X - - [23/Feb/2025:21:43:45 +0000] "GET / HTTP/1.1" 200 1192
  X.X.X.X - - [23/Feb/2025:21:44:54 +0000] "GET / HTTP/1.1" 200 1192
  X.X.X.X - - [23/Feb/2025:21:44:55 +0000] "GET /favicon.ico HTTP/1.1" 404 196
  10.88.0.1 - - [23/Feb/2025:21:51:13 +0000] "GET / HTTP/1.1" 200 1192
 

Stopping and Removing the Container

To remove the resources you have created:

 
 $ podman stop apache_container
  
 
 $ podman rm apache_container
 

 $ podman image rm docker.io/library/httpd:alpine

 Untagged: docker.io/library/httpd:alpine
 Deleted: fcd9ece3a2cca157cc637f914abf56d62aba9884aa1ee3a9b3c94dc88904874e
  


Conclusion

Congratulations! You’ve successfully automated the deployment of an Apache web server using Ansible and Podman. This is just the beginning!

Explore more advanced Ansible features to manage your infrastructure efficiently. 🚀

If you want more Ansible automation examples, let us know in the comments! 🎫


Did you like the content? Check out these other interesting articles! 🔥

✅ Leave a message with your questions! Share this material with your network!



Support us 💖

Do you like what you find here? With every click on a banner, you help keep this site alive and free. Your support makes all the difference so that we can continue to bring you the content you love. Thank you very much! 😊


Articles you might like 📌
comments powered by Disqus