How to manage your workstation configuration with Ansible

In the first article in this series, learn the basics of setting up configuration management for your laptops and desktops.
426 readers like this.
Jump-start your career with open source skills

Configuration management is a very important aspect of both server administration and DevOps. The "infrastructure as code" methodology makes it easy to deploy servers in various configurations and dynamically scale an organization's resources to keep up with user demands. But less attention is paid to individual administrators who want to automate the setup of their own laptops and desktops (workstations).

In this series, I'll show you how to automate your workstation setup via Ansible, which will allow you to easily restore your entire configuration if you want or need to reload your machine. In addition, if you have multiple workstations, you can use this same approach to make the configuration identical on each. In this first article, we'll set up basic configuration management for our personal or work computers and set the foundation for the rest of the series. By the end of this article, you'll have a working setup to benefit from right away. Each article will automate more things and grow in complexity.

[Read part two of this series.]

Why Ansible?

Many configuration management solutions are available, including Salt Stack, Chef, and Puppet. I prefer Ansible because it's lighter in terms of resource utilization, its syntax is easier to read, and when harnessed properly it can revolutionize your configuration management. Ansible's lightweight nature is especially relevant to the topic at hand, because we may not want to run an entire server just to automate the setup of our laptops and desktops. Ideally, we want something fast; something we can use to get up and running quickly should we need to restore our workstations or synchronize our configuration between multiple machines. My specific method for Ansible (which I'll demonstrate in this article) is perfect for this—there's no server to maintain. You just download your configuration and run it.

My approach

Typically, Ansible is run from a central server. It utilizes an inventory file, which is a text file that contains a list of all the hosts and their IP addresses or domain names we want Ansible to manage. This is great for static environments, but it is not ideal for workstations. The reason being we really don't know what the status of our workstations will be at any one moment. Perhaps I powered down my desktop or my laptop may be suspended and stowed in my bag. In either case, the Ansible server would complain, as it can't reach my machines if they are offline. We need something that's more of an on-demand approach, and the way we'll accomplish that is by utilizing ansible-pull. The ansible-pull command, which is part of Ansible, allows you to download your configuration from a Git repository and apply it immediately. You won't need to maintain a server or an inventory list; you simply run the ansible-pull command, feed it a Git repository URL, and it will do the rest for you.

Getting started

First, install Ansible on the computer you want it to manage. One problem is that a lot of distributions ship with an older version. I can tell you from experience you'll definitely want the latest version available. New features are introduced into Ansible quite frequently, and if you're running an older version, example syntax you find online may not be functional because it's using features that aren't implemented in the version you have installed. Even point releases have quite a few new features. One example of this is the dconf module, which is new to Ansible as of 2.4. If you try to utilize syntax that makes use of this module, unless you have 2.4 or newer it will fail. In Ubuntu and its derivatives, we can easily install the latest version of Ansible with the official personal package archive (PPA). The following commands will do the trick:

sudo apt-get install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible

If you're not using Ubuntu, consult Ansible's documentation on how to obtain it for your platform.

Next, we'll need a Git repository to hold our configuration. The easiest way to satisfy this requirement is to create an empty repository, or you can utilize your own Git server if you have one. To keep things simple, I'll assume you're using GitHub, so adjust the commands if you're using something else. Create a repository in GitHub; you'll end up with a repository URL that will be similar to this:<your_user_name>/ansible.git

Clone that repository to your local working directory (ignore any message that complains that the repository is empty):

git clone<your_user_name>/ansible.git

Now we have an empty repository we can work with. Change your working directory to be inside the repository (cd ./ansible for example) and create a file named local.yml in your favorite text editor. Place the following configuration in that file:

- hosts: localhost
  become: true
  - name: Install htop
    apt: name=htop

The file you just created is known as a playbook, and the instruction to install htop (a package I arbitrarily picked to serve as an example) is known as a play. The playbook itself is a file in the YAML format, which is a simple to read markup language. A full walkthrough of YAML is beyond the scope of this article, but you don't need to have an expert understanding of it to be proficient with Ansible. The configuration is easy to read; by simply looking at this file, you can easily glean that we're installing the htop package. Pay special attention to the apt module on the last line, which will only work on Debian-based systems. You can change this to yum instead of apt if you're using a Red Hat platform or change it to dnf if you're using Fedora. The name line simply gives information regarding our task and will be shown in the output. Therefore, you'll want to make sure the name is descriptive so it's easy to find if you need to troubleshoot multiple plays.

Next, let's commit our new file to our repository:

git add local.yml
git commit -m "initial commit"
git push origin master

Now our new playbook should be present in our repository on GitHub. We can apply the playbook we created with the following command:

sudo ansible-pull -U<your_user_name>/ansible.git

If executed properly, the htop package should be installed on your system. You might've seen some warnings near the beginning that complain about the lack of an inventory file. This is fine, as we're not using an inventory file (nor do we need to for this use). At the end of the output, it will give you an overview of what it did. If htop was installed properly, you should see changed=1 on the last line of the output.

How did this work? The ansible-pull command uses the -U option, which expects a repository URL. I gave it the https version of the repository URL for security purposes because I don't want any hosts to have write access back to the repository (https is read-only by default). The local.yml playbook name is assumed, so we didn't need to provide a filename for the playbook—it will automatically run a playbook named local.yml if it finds it in the repository's root. Next, we used sudo in front of the command since we are modifying the system.

Let's go ahead and add additional packages to our playbook. I'll add two additional packages so that it looks like this:

- hosts: localhost
  become: true
  - name: Install htop
    apt: name=htop

  - name: Install mc
    apt: name=mc
  - name: Install tmux
    apt: name=tmux

I added additional plays (tasks) for installing two other packages, mc and tmux. It doesn't matter what packages you choose to have this playbook install; I just picked these arbitrarily. You should install whichever packages you want all your systems to have. The only caveat is that you have to know that the packages exist in the repository for your distribution ahead of time.

Before we commit and apply this updated playbook, we should clean it up. It will work fine as it is, but (to be honest) it looks kind of messy. Let's try installing all three packages in just one play. Replace the contents of your local.yml with this:

- hosts: localhost
  become: true
  - name: Install packages
    apt: name={{item}}
      - htop
      - mc
      - tmux

Now that looks cleaner and more efficient. We used with_items to consolidate our package list into one play. If we want to add additional packages, we simply add another line with a hyphen and a package name. Consider with_items to be similar to a for loop. Every package we list will be installed.

Commit our new changes back to the repository:

git add local.yml
git commit -m "added additional packages, cleaned up formatting"
git push origin master

Now we can run our playbook to benefit from the new configuration:

sudo ansible-pull -U<your_user_name>/ansible.git

Admittedly, this example doesn't do much yet; all it does is install a few packages. You could've installed these packages much faster just using your package manager. However, as this series continues, these examples will become more complex and we'll automate more things. By the end, the Ansible configuration you'll create will automate more and more tasks. For example, the one I use automates the installation of hundreds of packages, sets up cron jobs, handles desktop configuration, and more.

From what we've accomplished so far, you can probably already see the big picture. All we had to do was create a repository, put a playbook in that repository, then utilize the ansible-pull command to pull down that repository and apply it to our machine. We didn't need to set up a server. In the future, if we want to change our config, we can pull down the repo, update it, then push it back to our repository and apply it. If we're setting up a new machine, we only need to install Ansible and apply the configuration.

In the next article, we'll automate this even further via cron and some additional items. In the meantime, I've copied the code for this article into my GitLab repository so you can check your syntax against mine. I'll update the code as we go along.

Want more on Ansible? Learn how to automate your CI/CD pipeline with Ansible in this free whitepaper.

User profile image.
Jay LaCroix is a technologist from Michigan, with a focus on Linux and open-source software. Using Linux since 2002, Jay has been a die-hard fan ever since. He is currently a Senior Solutions Architect and freelance consultant and enjoys training and empowering others to use Linux and to make the most of this amazing software.


QUOTE when harnessed properly it can revolutionize your configuration management. UNQUOTE

And the other solutions cannot? If they can also do this, then this is not a valid reason to argue that Ansible is better. As most people do not use use a configuration managment procedure for workstations, their non-existent procedure cannot be revolutionized. You fail to explain just how Ansible "revolutionizes" configuration management, and so this only sounds like a meaningless technobabble phrase borrowed from the marketing department.

QUOTEthere's no server to maintain.UNQUOTE

QUOTE create an empty repository on GitHub, or you can utilize your own Git server if you have one. QUOTE

You mislead your readers by contradicting yourself.

You do not need an ANSIBLE server but you do need a GIT server: either your own or provided by somebody else eg Github (other free services ARE available).

Sorry to appear to be so negative, but these discrepancies should have been addressed before publishing the article which otherwise provides useful HOWTO information.

Ansible really may be the best choice for workstation management but you are not making a good case, other than it is more lightweight, than the alternatives.

The revolutionary nature of Ansible comes from the fact that it's agentless, doesn't require a server, is lightweight, among other benefits. If you're wondering about all of the benefits that Ansible has to offer, I recommend you consult additional articles and books on the subject to grow your knowledge further.

In regards to not needing a server, having a Github repository doesn't constitute maintaining a server. Github's servers aren't maintained by the end-user. I only mentioned using your own Git server if you have one, because some individuals won't want to make their desktop configuration public, especially if the code contains any privileged information. But a server is not necessary. In fact, you could store all of this code on a flash drive and bypass having a Git repository if you wanted to go that far.

In reply to by Mr Awkward (not verified)

Jay, thanks a lot for this article! I'm one of "those people" who 1) always run the latest release of the distro and 2) often wipe the disk and do a fresh install. Because of this I generally have a few days after the install where I suddenly remember I need to install package XYZ. Sometimes this goes on for several months (I seem to use the "units" command about twice a year). I've often wished for a nice way to automate my post-install configuration and this looks like it could be a winner.

I'm already thinking about how to get the list of packages from the current system to start building my first playbook...

Looking forward to your next column!

Thank you for this article because it’s really informative, I love reading your article and I hope that I will read some more about this stuff.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.