Ansible Crash Course

In present-day, there are many great technologies for “automating stuff”. One newer concept is Infrastructure as Code (IaC), which is where you define how your infrastructure should look in “code” (a config file), and then various tools will go out and make it happen. These tools can automate the process of making sure your servers are configured correctly.

The darling of this category of tools at the moment, is Ansible.

Image result for ansible

There are certainly similar products that do similar things. A few things make Ansible stand-out:

  1. It is agent-less. It doesn’t require software to be installed on the remote server (which then has to be upgraded, later). Everything is done over an SSH connection.
  2. It uses YAML, and can do pretty much what all of the other tools can do.
  3. It can “support” Windows servers too (your mileage may vary!)
  4. Red Hat bought the company, so it’s become a first-class player in this arena.

I have a basic skeleton of an Ansible setup to manage the Linux machines in my home lab, so I thought I’d write down the basics of managing machine configuration from Ansible.

What is Ansible?

Ansible is basically a Linux application that uses Python and SSH to connect to remote machines – and “do things”. It does technically support Windows too via PowerShell remoting, but given the issues with: inconsistent versions of PowerShell, and PowerShell remoting security issues (like firewalls blocking the port) – Windows could be trickier. To be blunt, this is pretty much a Linux tool (a very good one), and Windows is sort of an afterthought.

To get started, you basically set up a “playbook” – a set of files which describe what you want a machine, or a whole set of machines to look like. For example, for web servers, you might:

  • Install nginx
  • Set permissions for certain directories
  • Open firewalld ports

and for *all servers, you might also:

  • Create an operator account and give it certain permissions
  • Make sure the machine has joined the Active Directory domain
  • Set an /etc/issue.net banner

You can set these sorts of things up, then when you run the playbook, Ansible will SSH out into all the appropriate machines and “ensure” that each of those things are done. I say “ensure” because it’s smart enough to know if a step is already done. It only makes a change if something is not how it should be.

How to install/run it?

This is where there is lots of good news. The documentation from Ansible is pretty great:

https://docs.ansible.com/ansible/latest/intro_installation.html

and then secondly, because it’s so popular, there are tons of blog posts and YouTube videos:

https://www.youtube.com/results?search_query=installing+ansible

In my case, I’m forcing myself to get better with CentOS/RHEL, so from the first link above, I just added the EPEL repository and did a “yum install ansible”

Setup the directory structure

This is one of those tools where you don’t have to have a lot of structure. However, as you build out your playbooks more and more, structure is only going to help you. So, I’m starting off from what most people seem to recommend. In fact, from this link, here are some commands to go set up the directory structure and files that you’ll need.

I did this in the default /usr/share/ansible folder:

$ mkdir -p roles/common/{tasks,handlers,templates,files,vars,defaults,meta}

$ touch roles/common/{tasks,handlers,templates,files,vars,defaults,meta}/main.yml

My Set Up (to start…)

To get a handle on what to put where, I followed this video – this guy has some good Linux videos and is easy to understand. So, I’d recommend checking this out (it’s ~:20 minutes) – but explains what each folder and file is for:

First, in the root of that folder, I have a “hosts” file, which lists all of the Linux machines:

# All Hosts
ansible
rundeck
infrabase[1:2]
rancher[1:4]


# Groups
[infrastructure]
ansible
rundeck
infrabase[1:2]


[docker]
rancher[1:4]

The rancher[1:4] syntax is the same as having lines for rancher1, rancher2, rancher3, and rancher4.

In that same root folder, the site.yml looks like this:


– name: Show off some basic Ansible features
   hosts: all
   user: root


  roles:
     – common

In roles/common/file I have an issue.net file and a slightly-modified /etc/ssh/sshd_config file which points to /etc/issue.net for SSH logins. Then, in roles/common/tasks/main.yml is where the main action takes place. Here’s what that looks like:


– name: Upgrade all packages
   yum:
     name: ‘*’
     state: latest


– name: Install nano
   yum: name=nano state=present


– name: Install net-tools (netstat)
   yum: name=net-tools state=present



– name: Create the ‘operator’ user
   user: name=operator shell=/bin/bash groups=wheel append=yes



– name: Copy issue.net
   copy: src=issue.net dest=/etc/issue.net


– name: Copy SSHD config
   copy: src=sshd_config dest=/etc/ssh/sshd_config
   notify: Restart sshd


– name: Add color prompt
   blockinfile:
     path: /etc/bashrc
     backup: yes
     content: |
         if [[ $EUID -ne 0 ]]; then
             export PS1=”[\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h \[\033[33;1m\]\w\[\033[m\]]$ “
         else
             export PS1=”[\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h \[\033[33;1m\]\w\[\033[m\]]# “
         fi
         export CLICOLOR=1
         export LSCOLORS=ExFxBxDxCxegedabagacad
         alias ls=’ls –GFh’

Per the video above, I also have a roles/common/handlers/main.yml which defines the “restart sshd” task too.

Run a playbook:

So what we want to do is say: for all of the hosts, go apply the “common” role – and run all of those tasks. From /usr/share/ansible – I run:

# ansible-playbook -i hosts site.yml –k

in this case, I have a common root password at the moment, and the “-k” prompts me for that password. And we can see that it runs:

image

Upon first run when things are modified, you’d see more orange. And if there are any problems, it shows red.

Run a one-off command:

Another useful thing you can do is run a one-off command on all servers. You can do something like ping all of the machines:

# ansible all -i ./hosts -m ping –k

image

or another very interesting command is to return all of the “facts” about these servers. You can run something like:

# ansible all -i ./hosts -m setup –k

and this brings back a big JSON document for each server with everything from CPU, memory, disk, network, environment variables, etc.

Bottom line:

Normally, I might put these files in a GitHub Gist and share them with this post. However, this is literally the first thing I got working with my home setup. One of the very next things I want to do is actually get all of this into a www.github.com repo, where it can be versioned properly – and we can all reference it from there.

In order to get to that point, I need to set up SSH keys, and use a “vault” technology – so that there isn’t anything sensitive in the repo.

My point is, this post is just meant as a general primer and a quick reference for myself. I do intend to evolve this. As I do, I intend to get my config files into Git, and I plan to do more blog posts on the details. In the meantime, hopefully this is helpful to someone or perhaps Future Robert coming back here trying to remember the syntax of something!

Posted in Ansible, Computers and Internet, General, Infrastructure, Linux, New Technology, Organization will set you free, Security

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 4 other followers

%d bloggers like this: