On most Linux distributions Ansible can be installed directly through your distribution’s package manager.
For those using macOS or a distribution that doesn’t package Ansible, you can install it via python pip. The Ansible docs have a really good walkthrough for installation that can be found here: http://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html
I won’t repeat those instructions except to say that you will want to make sure that the computer you install Ansible on should have Python 2.6 or higher or Python 3.5 or higher and while Windows can be managed by Ansible it cannot be a control machine.
Once Ansible has been installed it is, for the most part, ready to be used. There are no daemons to start, or services to enable. Ansible will run when you call it, either directly from the command shell, or via scheduled tasks.
There are a few files that you should be aware of when you get started using Ansible.
The Ansible configuration file:
Located at /etc/ansible/ansible.cfg the Ansible configuration file contains all of the global Ansible settings.
You can specify the user that Ansible will run as, the number of parallel processes (forks) that it will spin up, and many other configuration items to help you fine-tune your Ansible installation.
The settings in this file can be overwritten by creating an ansible.cfg file located in your users home directory ~/.ansible.cfg or in the directory that contains your playbooks <current_dir>/ansible.cfg. For common options and a more in-depth explanation of these files take a look at the ansible documentation.
The Ansible inventory file:
The Ansible inventory file is located at /etc/ansible/hosts.
You can change the default location of this file by updating the Ansible configuration file to point to a different path, or you can specify an inventory file with “-i” when calling an Ansible playbook.
The inventory file is a flat text file that lists the hosts you want to manage using Ansible. Any host that you want to run a playbook on must have an entry in the inventory file. When you installed Ansible a template file should’ve been created for you at /etc/ansible/hosts.
The structure of the inventory file is pretty simple and fairly easy to learn. As you become more comfortable using Ansible you will find that there are a lot of modifications that can be made to the inventory file that will make your playbooks even more powerful.
The basic setup of an Ansible inventory file would have a Header Section noted with brackets to indicate a group of servers: for example a group that contains all servers might look like this:
[all] server1 server2 ........
A group that contains only database servers would look like this:
[dbservers] dbserver1 dbserver2 .......
The dot’s, in this case, indicate that the list could go on and on, don’t put them in your inventory file.
You can have any name you want for your groups, just make sure that they make sense to you. You can also have groups of groups, and variables that apply to entire groups. Here is a link to the documentation that you will need to create well-defined inventory files: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#intro-inventory
Don’t skip that section read it carefully and take time to define your groups well.
Getting Started with Ansible
Once you have Ansible installed, and have built at least a simple inventory file. Try making a test group with a couple of hosts in it. Append the following to the bottom of your /etc/ansible/hosts file.
[test] sometestserver01 someothertestserver02
If you have never used Ansible, try out some of the ad-hoc commands. These commands can run Ansible modules against a host or group of hosts without writing a playbook.
One of the most useful ad-hoc commands is also the simplest one.
Ansible has a module built into it called “ping”. The ping module will connect with a target system and attempt to locate a compatible python installation.
It will then report back with a success or failure message, indicating that the target host is up and able to be managed with Ansible.
I use this module quite a bit to ensure that I have connectivity between my Ansible control server, and the client servers that I want to run playbooks against. This helps to minimize surprises when a playbook fails to run at the expected time.
To use the ping module run the following command:
ansible test -m ping
In this command string, we are doing a couple of things.
First, we need to specify the group or host that we want Ansible to run against, in this case, it is the “test” group we just created. Second, we specify the module that we want to use, in this case, that is the ping module.
As long as your Ansible control server (could be a laptop at this point) can connect to the target hosts on port 22 then this command should complete successfully.
Speaking of success, how can you know if an Ansible playbook or command ran successfully.
Ansible output is color coded
Green text: Indicates that Ansible ran successfully but made no changes the target host. This is a success in that, the host was already configured as defined in the playbook.
Yellow text: Indicates that Ansible ran successfully and made changes to the target host. This is a success in that, the host is now configured as defined.
Red text: Indicates a failure, either a connection failure, a syntax error, or a failure to run the appropriate tasks on the target host. If you see this you will want to take a moment to read the output. Ansible usually gives fairly detailed error messages.
Purple text: Indicates a warning. You will see this when you call a command rather than using an available module, i.e. Calling yum in a command rather than using the yum module. Generally Ansible will still run when you see purple, however, you should consider updating your playbook to use the built-in modules instead. You may also see purple text when a host is specified in a playbook but does not have a corresponding entry in the inventory file.
For more information about ad-hoc commands read the following documentation page: https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html
Convert old shell scripts
Once you have spent some time playing around with ad-hoc commands and feel comfortable using them. The next thing I would do is to start evaluating all the bash scripts you have laying around.
Find out which ones would be a good fit for Ansible. If you have scripts that you run for: patching, firewall changes, configuration file changes, user creation/modification/deletion. Then you already have a lot low hanging fruit to pick from.
Once you start converting bash scripts to Ansible and start running them from a centralized server, you will begin to see the power that this tool affords you.
Common repeatable tasks
If you find yourself doing the same thing over and over again. Take a few hours every day, and instead of going through the motions see if you can break those tasks down into repeatable steps. Check the Ansible module index to see if you can offload any of that work to a playbook.
After you have converted some shell scripts into Ansible it should be a little easier for you to identify which of your day to day tasks can be accomplished by an Ansible playbook.
I know most Sysadmins are not straining to fill the hours at the office. We all have more work than we know what to do with, but I promise that spending a couple hours a week on automation will be well worth it in the long run and unless your boss is incompetent or some kind of control freak they should be ecstatic to see you working to improve processes. If not, find a new job…
Things you don’t like to do
This is why I love Ansible. Once you’ve found a few common configuration items, and identified repetitive tasks, you can begin the noble work of getting Ansible to do the parts of your job that you don’t like doing.
Updating a firewall on 200 servers? That sounds awful and I don’t want to do it… Spend one day on a playbook, and never worry about it again.
Spending your nights and weekends patching? Nah, I’d rather sit on the couch and watch my cats chase a laser while stuffing my face with pizza and beer.
Seriously, work is for suckers. Spend some time learning Ansible and it will pay you back in spades. You might even find yourself with enough time to work on a project you haven’t had time for. Or maybe take a vacation.
Ansible Example: Patch and reboot
Ah yes, patching, we have to do it. If you’re not regularly applying patches, you need to have a really good reason not to and a good mitigation strategy.
Patching is something, that in large environments, can quickly consume a lot of time if it isn’t managed properly, and more importantly if it isn’t automated. In that regard, I have provided an example playbook that you can use to begin automating some of your vulnerability patching.
--- - hosts: <put some server names in here, with out the angle brackets> become: yes tasks: - name: Upgrade all installed packages yum: name: '*' state: latest - name: Reboot after update command: /sbin/shutdown -r 1 "Reboot after patching" async: 0 poll: 0 ignore_errors: true - name: Wait for server to become available wait_for_connection: delay: 60 timeout: 500 # This can vary use a timeout that is reasonable for your environment, most VM's will reboot before 500 seconds.
Breaking down the playbook
What does it do? This playbook, will patch, reboot, and wait for a server to become available. After you run it you will get a nice little color-coded summary of the play.
Every yaml file starts with “—” it’s like the #! at the start of a bash script.
What does “become” do? Using the keyword “become” means that upon executing this playbook Ansible will attempt to escalate privileges to root.
After that, you can list your tasks in blocks using modules. You can find an index of provided modules here: https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
Granted this is a pretty simple playbook, it only takes into account Red Hat based systems, and it doesn’t provide notifications upon completion, but I’ll leave that part up to you. If you spend a lot of time patching then this little snippet of code should get you a long way towards reducing the manual effort you put into server updates.
If this helped you feel free to share it or comment below.