3 Ansible playbooks, 2 DO droplets, and a website... in a pear tree ๐ŸŽ„

Running through another of Erika's Ansible posts with example playbooks, creating a few pointless ones of my own, and discovering just how easy it is to deploy a website running on Apache!

3 Ansible playbooks, 2 DO droplets, and a website... in a pear tree ๐ŸŽ„

I started looking at Ansible last week, after finding some good intro articles by Erika Heidi. Here's the one I followed in the last post.

How to Use Ansible to Automate Initial Server Setup on Ubuntu | DigitalOcean
Ansible offers a simple architecture that doesnโ€™t require special software to be installed on nodes. It also provides a robust set of features and built-in modules which facilitate writing automation scripts. This guide explains how to use Ansible to automate the steps contained in our Initial Serveโ€ฆ

If you followed how I set things up in my other post, then after the script creates the "sammy" user you still won't be able to login because you don't know the password. Just login to the remote host as "root", run sudo passwd sammy, and you're golden. Obviously, it'd be better if I automated that part too, but whatever.. this is for play.

Today I'm running through another of Erika's posts, which includes some sample playbooks to run. Plus I created a few of my own pointless playbooks.

Configuration Management 101: Writing Ansible Playbooks | DigitalOcean
This tutorial will walk you through the process of creating an automated server provisioning using Ansible, a configuration management tool that provides a complete automation framework and orchestration capabilities. We will focus on the language terminology, syntax and features necessary for creatโ€ฆ

Create a file and change the modification date

I created my first playbook with only two tasks. It creates an empty file using the file module, then makes it look old by changing the modification stamp.

---
- hosts: all

  tasks:
    - name: Create an empty file because reasons
      file:
        path: ~/sample_file.txt
        state: touch

    - name: Change the modification time of the empty file
      file:
        path: ~/sample_file.txt
        modification_time: 199902042120.30

Run it with the -u flag to make it run as "sammy", and then verify that the file has been on your server for 20 years. :p

ansible-playbook my_first_playbook/playbook.yml -u sammy

Install and remove packages

This task was taken from Erika's article, installing or updating 3 packages to the latest version. Then I added a task to remove git by setting it's state to absent. I can't believe how nicely Ansible abstracts away the underlying scripts it must be running to do what it does. ๐Ÿ‘

---
- hosts: all

  tasks:
    - name: Update some packages
      apt: name={{ item }} state=latest
      with_items:
        - vim
        - git
        - curl

    - name: Remove a package
      become: yes
      apt: name=git state=absent

Spin up a website using Apache

You'll want to copy the contents of Erika's ansible folder in the following repo.

erikaheidi/cfmgmt
Configuration Management Guide. Contribute to erikaheidi/cfmgmt development by creating an account on GitHub.

If you followed my setup using 2 DigitalOcean droplets, you'll need to add a task to allow port 80 (see below).

---
- hosts: all
  become: true
  vars:
    doc_root: /var/www/example
  tasks:
    - name: Update apt
      apt: update_cache=yes

    - name: Install Apache
      apt: name=apache2 state=latest

    - name: Create custom document root
      file: path={{ doc_root }} state=directory owner=www-data group=www-data

    - name: Set up HTML file
      copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644

    - name: Allow all access to tcp port 80
      ufw:
        rule: allow
        port: '80'
        proto: tcp

    - name: Set up Apache virtual host file
      template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
      notify: restart apache
  handlers:
    - name: restart apache
      service: name=apache2 state=restarted

Here's the results. I colorized each area of output to make it easier to understand.

  • The red area shows that the only open port was for SSH, but the Ansible script configured it to allow port 80 as well (purple area).
  • The blue and green areas show the web page and apache config file, respectively.
  • The yellow area shows that apache2 has been up for nearly 7 minutes. It didn't restart Apache when I ran the script below, because I had run the playbook several times already and the apache conf file hadn't changed, so the 'setup apache virtual host file' task didn't have to run again... at least that's how I understand it.

And finally, opening the little index.html page I created, which was copied to the remote host that the Ansible controller node copied it to. Success!

The power of Ansible is easy to see. So far, I've only played around with pushing changes to a single remote host, but I could easily spin up more droplets, modify the /etc/ansible/hosts file on the controller node (pasted below) to include them, and push out a website (or anything else I want) to every machine at once. ๐Ÿคฏ

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

[servers]
server1 ansible_host=64.225.30.45

[servers:vars]
ansible_python_interpreter=/usr/bin/python3