Photo by Phillip Glickman on Unsplash

Ansible is a tool to automate system administration tasks. The Ansible Control Node is the machine used to control other machines; the Managed Node is the machine being controlled.

Both machines have to run Linux (e.g. two VMs, one WLS and one VM, a local Linux machine and a remote VM, two remote Linux machines…)

Since Ansible runs commands by SSH, so no need to have an agent on managed nodes.

How does it work

Ansible selects machine to run the commands on using an inventory (in /etc/ansible/hosts); it connects to machines using ssh, copy modules and then executes them.

Installation (Ubuntu)

Please refer here to install on other OS.

Python should be installed on both the machines (control node and managed node).

Install Ansible on the Control Node:

sudo apt-get updatesudo apt-get upgradesudo install python3-pipsudo apt-install software-properties-commonsudo add-apt-repository –yes –update ppa-ansible/ansiblesudo apt-install ansible

Finding the IP of the destination machine

ip addr show

Installing openssh on the managed nodes

sudo apt-install openssh-server

Note: all the managed nodes have to be accessible with the same username

Generating SSH keys

ssh_keygen -t rsassh-copy-id <user@ip>

Keys are needed to authenticate the session without using user/password.

Testing Ansible

ansible all -m ping

Playbooks

Playbooks execute many operations on managed nodes (e.g. creating multiple users). They are essentially .yml files.

- name: Create usershosts: *vars:  myusers:    - dave    - martin    - andrewtasks:  - name: Create users    user:      name: "{{ item }}"      state: present  loop: "{{ myusers }}"

state: present -> makes sure the user has been added, if not, it will be added

state: absent -> makes sure the user has been removed, if not, it will be removed

Be careful with loops, as they are not always efficient. (e.g: looping over three yum vs using a single yum with three packages)

Ansible-galaxy is a playbook repository (there you can find a playbook to install mysql defining databases and users, along with their access rights).

ansible-galaxy install geerlingguy-mysql

Executing a Playbook

ansible-playbook mybook.yml

Dry run of a playbook

ansible-playbook -C mybook.yml

Escalating privileges in a Playbook (sudo)

ansible-playbook mybook.yml -K

Adding the user to sudoers removes the need of -K.

Secrets management with ansible-vault

ansible-vault allows the user to encrypt/decrypt files of secrets (e.g. API keys, passwords)

ansible-vault create filenamevieweditencryptdecryptrekey -> assign a new key to filename

Executing a Playbook with a vault password

ansible-playbook –-ask-vault-pass mybook.yml

no-log doesn’t show the secrets while executing playbooks.

Conditional tasks

Conditional tasks are defined using “when”.

when: var_name is defined

Testing for conditions (it is possible to use booleans)

when:
- condition A
- condition B

Ansible Facts

Data regarding the remote system (e.g: IP, OS…) gathered in a dictionary with a standard nomenclature.

Handlers

Task responding to notifications sent by other tasks (e.g. rebooting the system after relaunching services). Handler are defined at playbook level.

tasks:  - name: copy apache conf    template:      src: path/to/src/conf.template      dest: path/to/dest/file.conf    notify:      - restart apachehandlers:  - name: restart apache    service:      name: httpd      state: restarted

Block

Blocks are clauses gathering tasks in logic units.

A block can provide a “when” so that the tasks in a block are launched if and only if a condition is met.

tasks:  - name:    block:    rescue:    always:

rescue: only executed if the block fails

always: is always executed

Templating (Jinja2)

Templating allows deploying customized files. Ansible searches for template files in the playbook directory or in a “templates” directory in the playbook directory.

- name: customize file  template:    src: file_template.j2    dest: /path/to/dest_file    owner: root    group: root    mode: “0600”    setype: etc.t

File “template.j2”:

Hi, my is {{ ansible_fact[‘hostname’] }}

Looping in the template

{% for i in list %}{% endfor %}{# This is a comment #}

Filters in the template

Useful to process variables without changing their values

{{ name | capitalize }}

Lookup plugins

Lookup plugins are extensions to the Jinja2 language allowing to get data from external sources (e.g. file content, API calls…).

Example: “dig” to gather informations about a DNS record.