Automation Using Ansible

Eric Brauer

What is Ansible?

From the docs:

Ansible is an agentless IT automation engine for automating cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT system administration tasks.

But What is Ansible?

In other words, Ansible allows you to control a remote system over SSH (usually). Ansible is usually used to run playbooks, which will change a configuration on a remote machine. Ansible is usually categorised as a ‘configuration management’ tool.

Terminology:

  • Control machine (for us, it will be your VM or Matrix)
  • Managed machine(s) (for us, it will be myvmlab)
  • Playbook

Initial Setup: Control Machine

Your Control machine can be either Fedora or Matrix.

  • Clone your lab 9 repository to your control machine.
  • Make sure Ansible is installed on your control machine.
  • Copy your public key from control to the remote machine.
  • You should be able to SSH from Control to Remote without a password.

Initial Setup: Remote

Ansible uses an SSH connection to reach the managed machine. In order to cut down on password prompts, you should:

be able to run a sudo command on myvmlab without supplying a password (ie. modify your /etc/sudoers file on remote)

Installing Ansible

Only your Control Machine needs to have Ansible installed.

On Fedora, run

sudo dnf install ansible

If you are using Matrix, then Ansible is already installed.

Inventory File (Hosts)

Contains the machine(s) you will be managing. Basically here we can define IP addresses (or ranges) of machines to control. Copy the sample hosts file from your repo and observe the syntax:

jkwok   ansible_host=myvmlab.senecacollege.ca ansible_port=7850
  • jkwok: an alias! Replace it with your Myseneca username.
  • ansible_host: a hostname or IP address of your remote machine. No change needed here.
  • ansible_port: replace with the port # in your email that maps to port 22!

Initial Prep Checklist

Before you even touch Ansible, make sure that:

  • You can SSH from control to remote without a password
  • You can run sudo commands on remote without a password
  • You have Ansible installed on control
  • You have a hosts file with the correct information on control

Ad Hoc Mode

You can run Ansible commands from the shell. These are useful for making sure that everything is working. For everything else, a playbook is preferable.

Let’s call these tasks.

There are a few tasks you might want to run in ad-hoc mode:

  • shell commands
  • using modules

Simple Shell Command in Ad Hoc Mode

This will establish an SSH connection with the remote machine, run the shell command on the remote machine, and then show you a summary of what occurred.

The syntax of this command:

$ ansible remote_machine_id [-i inventory] [--private-key id_rsa] [-u remote_user] -a date

Simple Shell Command in Ad Hoc Mode

Assuming that hosts is in your current working directory:

$ ansible jkwok -i hosts --private-key ~/.ssh/id_rsa -u student -a date

Use -a to specify arguments. For simple shell commands, this specifies the command to run (date).

Ansible Modules

These are a useful way of extending the capabilities of Ansible. These are like modules in Python: some are official, some are developed by third parties. They need to be installed on your Control Machine.

Many modules are installed alongside Ansible. You can view the installed modules on your control machine:

ansible-doc --list_files

You’ll see a module for yum has been installed. To view the man pages and learn how to use it:

ansible-doc yum

While you’re at it, we will use this module next:

ansible-doc copy

Using The Copy Module in Ad Hoc Mode

ansible jkwok -i hosts --private-key ~/.ssh/id_rsa -u student -m copy -a "src=hosts dest=/tmp/ansible_hosts"

Use -m to specify module name. -a is now used to specify some arguments required by the module.

If you’re wondering, there is no need for hosts to be on the remote machine, we are just using it for testing here.

Handling Root Permissions

You will now attempt to use Ansible’s yum module to install the epel-release repository. You might get a message like this:

jkwok | FAILED! => {
...
        "msg": "You need to be root to perform this command.\n",

Handling Root Permissions

Make sure that your student user is able to run sudo commands without a password (ie. NOPASSWD), and then pass -b as an option to invoke sudo from your Ansible command. Then try again:

jkwok | CHANGED => {
        "changed": true,
        "changes": {
        "installed": [
            "epel-release"

Reading Ansible’s Output

Ansible will check the current state of the machine, and if epel-release is already installed, won’t attempt to repeat that installation process. This is useful!

Ansible tasks have three possible outcomes:

  • FAILED!
  • CHANGED
  • SUCCESS

Reading Ansible’s Output

The second time we ran this command, changed is set to false because epel-release was already installed.

jkwok | SUCCESS => {
        "changed": false,
        "rc": 0,
        "results": [
            "epel-release-7-11.noarch providing epel-release is already installed"

rc refers to ‘return code’ and it can provide further help when tasks fail. Here rc: 0, meaning no errors occurred.

Playbooks

Most of what you do on Ansible will be contained in playbooks, which is essentially a script to create repeatable tasks.

The real power of Ansible is in automating tasks, or repeating a certain task on many machines.

Playbooks are in YAML format. Indentation in YAML is very important!

MOTD Playbook Example (General)

The top of your playbook is setting some global values. The second part is where we will specify our tasks.

- name: update motd file
  hosts: jkwok
  user: student
  become: yes
  vars:
    motd_warning: 'WARNING: user by ICT faculty/students only.'

MOTD Playbook Explained

- name: ← description of your yaml file
  hosts: ← what entry in your inventory?
  user: ← remote user name
  become: ← will we become sudo?
  vars: ← setting up variables inside yaml
    motd_warning: 'WARNING: user by ICT faculty/students only.'

MOTD Playbook: Setting Tasks

tasks is where the real work gets done. Please note the indenation level is the same as the ones above!

  tasks:
  - name: setup a MOTD
    copy:
      dest: /etc/motd
      content:"{{ motd_warning }}"

We name our task, identify the copy module to be used, and pass the motd_warning variable as one of the arguments.

MOTD Playbook: Explanation

  tasks : ← this is a list of discrete tasks 
  - name :  ← task description 
    copy : ← name of the module used 
      ?? :  ← these arguments will change 
      ?? :  ←  based on what module you use

You can access variables you created earlier by putting them inside {{ }}.

Playbook Output

$ ansible-playbook motd-play.yml
TASK [setup a MOTD] ************************************************
changed: [192.168.99.153]
PLAY RECAP ************************************************
192.168.99.153             : ok=1    changed=1    unreachable=0    failed=0

END