Automatic desktop configuration using Ansible and Perl

In a New Guise

Next up when customizing a Linux distribution is typically running my binlinks script, which resides in a locally cloned Git repository and links a variety of other practical Perl scripts, which are located in subdirectories of the same repository, with entries in the bin directory under my home directory. After running binlinks, for example, my Perl script template generator tmpl (which I use to start almost every project) is directly available at the command line as tmpl – because my command path $PATH includes the bin directory in my home directory.

As Listing 2 shows, the script simply creates a symlink pointing at the position of the original tool in the repository for each script listed below the __DATA__ keyword at the bottom. Calling

Listing 2

binlinks

 

ansible-playbook binlinks.yml

runs the playbook in Listing 3 with the command module included with Ansible; this in turn calls the binlinks script and returns with a success message if the script completes with a exit code of 0.

Listing 3

binlinks.yml

 

I can now also repeat complicated processes (e.g., repairing the Nagios configuration that in my experience gets destroyed during each and every upgrade) using a combination of the template mechanisms supported by Ansible for modifying files and other scripts. Although Ansible itself cannot foretell the future and only repeats the steps from yesteryear, it still helps immensely to at least know what manual actions were needed for the installation so that I can repeat them later with Ansible and some minor adjustments.

Virtual Worlds

Another configuration marathon always ensues whenever I want to find out whether a Perl module that just completed in my development environment will also run flawlessly on a production system using an Apache 2 server and the mod_perl2 accelerator. For this to happen, a clean room that only installs absolutely necessary packages – starting from a new Linux distribution on a Vagrant VM [4] – configures the server accordingly and drops the Perl module into place.

The instructions for this are in the source repository and can be read by a machine, to avoid developers wearing out their fingers typing in this process or even having to read instructions. Ansible follows the steps in exactly the same manner for each newly created VM.

The Vagrant configuration file in Listing 4 makes use of a current Ubuntu distribution, which Vagrant downloads from the HashiCorp server, if required. Furthermore, the configuration ensures with the forwarded_port directive that the Apache server listening on port 80 in the VM listens on port 8080 on the host system.

Listing 4

Vagrantfile

 

To deal with a Vagrant VM from the main host, Ansible first needs to know which SSH port and which private key it can use to connect to the freshly booted VM using vagrant up. Calling vagrant ssh-config reveals that the Ubuntu VM is accessible via SSH port 2222 on the local host, along with the path on the local filesystem for the private SSH key for identification.

The Ansible configuration file sets these values for Ansible, ensuring that the tool can log in to the newly created VM and can perform the predefined work there. If ansible-playbook is called from the same directory in which the configuration file resides, it sets the following values to establish a connection:

[defaults]
hostfile = hosts
remote_user = vagrant
private_key_file = /home/mschilli/  .vagrant.d/insecure_private_key
host_key_checking = False

This works well. The file containing this information is called ansible.cfg, so Ansible checks for it by default.

Steady Control

When writing new software projects from scratch, or just modifying them slightly to fix bugs, the question of whether the system will actually work after the fix always arises. A unit test suite may remove any particularly embarrassing mistakes, but – ultimately – only a test in a production environment will provide certainty.

For example, it is only possible to tell whether the mod_perl handler in Listing 5 works in an Apache server with the mod_perl module installed. You not only have to install the respective distribution packages such as apache2 and mod-perl2, you also need to point the web server to dynamic content in the /modperltest path using a configuration file – as shown in Listing 6.

Listing 6

mod-perl-test.conf

 

Ansible also helps here. Listing 7 shows the playbook for an Apache 2 server with the mod_perl2 module and the test application in Listing 5 installed. A simple call to the playbook via

Listing 7

mod-perl.yml

 

ansible-playbook mod-perl.yml

installs the whole enchilada in the VM that was booted by vagrant up. If you're wondering about the apt parameter in line 6, it specifies the name of the Ubuntu packages to be installed with the name key.

The update_cache=yes parameter prompts Ubuntu to obtain the latest index files for the repository before trying to fetch any packages – this may take quite a fair amount of time, but it's necessary with a fresh installation because a fresh Ubuntu VM's cache always contains outdated information, which can mean that a subsequent apt-get install often doesn't find the required packages.

Because Ansible doesn't normally run as root, but the apt-get install command does need root privileges, Line 7 in Listing 7 activates sudo mode. Each task can thus fine-tune its rights, leaving nothing running unnecessarily with a dangerous amount of firepower. As one of its tasks, the playbook in Listing 7 copies the Apache configuration file to /etc/apache2/conf.

The ModPerl application, which generates the output seen in Figure 3, responds promptly when calling on http://localhost:80/modperltest within the VM, and due to the port mappings in Listing 4 on port 8080 on the host computer.

Figure 3: Thanks to Ansible, mod_perl2 runs on an Apache 2 server with the test script from Listing 5 in the vagrant VM.

Listing 5

ModPerlTest.pm

 

Thanks to the playbook, Ansible also ensures that the Apache server inside the VM restarts if its configuration or the application's source code has changed. The notify: restart apache directive from line 11 always triggers the restart mechanism defined in lines 18-19 via apachectl whenever the developer installs a new version of the application.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Ansible Container Auto Deploy

    Streamline software deployment with Ansible and Docker containers.

  • ELK Stack Workshop

    ELK Stack is a powerful monitoring system known for efficient log management and versatile visualization. This hands-on workshop will help you take your first steps with setting up your own ELK Stack monitoring solution.

  • Perl – Vagrant Package

    The Vagrant package provides easy management of virtual machines with VirtualBox as the hypervisor on the command line. Provisioning tools like Puppet let customers try out products in pre-installed environments.

  • Vagrant

    With Vagrant, you can automate the creation and management of consistent virtual machines that work across platforms.

  • Perl: Speed Bumps

    Instead of souped up CPUs, simple programming tricks are often all it takes to speed up a program. Profilers can discover bottlenecks that need more TLC from the developer.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News