Ansible


# Ansible

Ansible Logo

Ansible (opens new window) is een open-source software provisioning, configuratie management, en applicatie-deployment tool die infrastructuur als code mogelijk maakt. Het draait op alle Linux systemen (als ook Unix systemen) en Microsoft Windows, en kan deze ook configureren. Het bevat een eigen declaratieve taal om systeemconfiguratie te beschrijven. Ansible is geschreven in 2013 door Michael DeHaan en in 2015 overgenomen door Red Hat die nu commerciele ondersteuning bied. Voor ons is Ansible een handige tool omdat het agentless is. Het maakt tijdelijk op afstand verbinding via SSH of Windows Remote Management (waardoor PowerShell op afstand kan worden uitgevoerd) om zijn taken uit te voeren, tegenover sommige alternatieven als Chef of Puppet is voor Ansible op de server geen installatie nodig! Dit laat ons toe sneller servers op te zetten.

In dit deel focussen we op het gebruik op Linux (meer bepaald Ubuntu). Windows installatie van Ansible is moeilijker.

Ansible gaat ons toelaten om in YAML formaat Linux en Windows servers te configureren. We kunnen bestanden aanmaken, configuratie aanpassen en software installeren. In vergelijking met een script is een paar verschillen:

Ansible laat ons toe meerdere servers tegelijk te configureren en beheren doormiddel van inventories.

Ansible checkt na het verbinden met je server wat al gebeurd is en zorgt dat je server bij elke Ansible-run op to date is met wat in je Ansible configuratie staat. Je kan dus gerust je installatie laten staan Ansible checkt dit steeds voor het uitvoeren. Dit laat je toe snel servers toe te voegen.

# Installatie

Ansible moeten we enkel installeren op de client. Hiervoor raad ik aan een Ubuntu Desktop te installeren.

Installeer Ansible via APT:

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
1
2
3
4

# Concepten

architecture

Deze concepten komen voor in Ansible. Hiermee bouw je een Ansible setup op:

# Control node

Elke machine waarop Ansible is geïnstalleerd. Je kab Ansible-opdrachten en -playbooks uitvoeren door het ansible of ansible-playbook commando uit te voeren. Vaak is dit onze laptop, maar het kan ook een andere server zijn waar heel je team aan kan.

# Managed nodes

Dit zijn de servers die je beheert met Ansible. Managed nodes worden ook wel eens "hosts" genoemd. Ansible wordt niet geïnstalleerd op managed nodes.

# Inventory

Een lijst vanmanaged nodes. Een inventoryfile wordt ook wel eens een "hostfile" genoemd. Je inventory kan informatie specificeren zoals IP adressen voor elke managed node. Een inventory kan ook beheemanaged rde nodes organiseren, groepen aanmaken en nesten voor eenvoudiger schalen.

# Modules

De eenheden van code die Ansible uitvoert. Elke module heeft een specifiek gebruik, van het beheren van gebruikers op een specifiek type database tot het beheren van VLAN-interfaces op een specifiek type netwerkapparaat. Je kan een enkele module aanroepen met een taak, of meerdere verschillende modules aanroepen in een playbook. Vele van deze modules worden meegeleverd of zijn te vinden op het internet. Deze modules besperen ons tijd door al expertise te gebruiken van mede-Ansible-gebruikers.

# Task

De eenheden van actie in Ansible. Je kan een enkele taak eenmalig uitvoeren met een ad-hoc commando.

# Playbooks

Geordende lijsten van tasks, opgeslagen zodat je die taken herhaaldelijk in die volgorde kunt uitvoeren. Playbooks kunnen zowel variabelen als taken bevatten. Playbooks worden geschreven in YAML.

# Getting started

We hebben al Ansible geinstalleerd op onze Ubuntu. We gaan enkele acties uitvoeren als demo van Ansible. We gaan snel in een cloud provider een VM aanmaken en deze configureren met Ansible.

We zorgen ervoor dat we we een SSH key hebben:

ssh-keygen # en volg de stappen
cat ~/.ssh/id_rsa.pub
1
2

Je kan deze key nu ingeven bij het aanmaken van de VM.

# Project opzetten

We maken een map aan waar we ons Ansible project in kunnen zetten. We openen de map hierna in een editor als Visual Studio Code.

Alseerst maken we een file met naam hosts (verander de username wel)

[servers]
<IP> ansible_user=ubuntu ansible_python_interpreter=/usr/bin/python3
1
2

Nu maken we een file met naam ansible.cfg

[defaults]
inventory = hosts
host_key_checking = False
1
2
3

Je kan nu zien of Ansible de hosts herkent:

$ ansible all --list-hosts
  hosts (1):
    141.148.244.47
1
2
3

TIP: in WSL kan een gedeelde map van Windows gezien worden als "world writable" wat in Ansible een security mechanisme triggered je kan hier rond werken door het expliciet toe te laten in een environment variable:

export ANSIBLE_CONFIG=$(pwd)/ansible.cfg
1

We pingen (SSH test in dit geval) nu de servers:

$ ansible all -m ping
1

Nu maken we een file met naam main.yml

- hosts: servers # installer dit op all hosts onder "servers:
  tasks:
    - name: Create a directory if it does not exist
      become: yes # become is kort voor become_user root
      file:
        path: /ansible_was_here
        state: directory

    - name: Install SL
      become: yes
      apt:
        name: sl
        state: present
        update_cache: yes
1
2
3
4
5
6
7
8
9
10
11
12
13
14

We voeren nu de file uit:

$ ansible-playbook main.yml
1

We zien nu dat Ansible de map /ansible_was_here heeft aangemaakt alsook dat de SL is geïnstalleerd. Als we dit opnieuw draaien bevestigt Ansible dat de map al bestaat en dat de SL al geïnstalleerd is. We kunnen deze verwijderen Ansible terug draaien en onze servers zijn weer inorde!

# Roles

In dit voorbeeld hebben we op al onze servers hetzelfde gezet, nu dit is meestal niet het geval. We spreken vaak van server roles. Dit zijn rollen die een bepaalde server kan aannemen. We zien hieronder een typische structuur voor zo een rollen:

ansible/
├── roles
│   ├── common
│   │   └── tasks
│   ├── web_server
│   │   ├── handlers
│   │   ├── tasks
│   │   │   ├── main.yml
│   │   │   ├── setup_db.yml
│   │   │   └── setup_nginx.yml
│   │   └── templates
│   │       └── nginx_site_config.j2
├── hosts_production
├── hosts_staging
├── mail.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Onze main.yaml zegt dan welke server tags welke roles krijgen

- hosts: web_hosts
  roles:
      - common
      - web_server
1
2
3
4

Elke role heeft een structuur:

  • tasks zijn onze taken, we starten altijd met de main.yml
  • templates zijn templates voor files, hierdoor kan je variables gebruiken in configuratie files
  • handlers zijn handlers voor de acties, bijvoorbeeld als een configuratie file wordt aangepast de service te herstarten

# Plugins

Absible heeft een groot ecosysteem van plugins, je hebt vele externe maar ook ingebouwde plugins. De volledige lijst van ingebouwde kan je op de Ansible site vinden (opens new window).

# Top Modules

# APT
- name: Install MariaDB
  become: yes
  apt:
      name: mariadb-server
      state: present
      update_cache: yes
1
2
3
4
5
6
# Services
- name: Restart apache2
  service:
      name: apache2
      state: restarted
1
2
3
4
# Copy
- name: Write some content in a file /tmp/hello.txt
  copy:
      dest: /tmp/hello.txt
      content: |
          Good Morning!
          Awesome sunshine today.
1
2
3
4
5
6
- name: Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version
  copy:
      src: /mine/ntp.conf
      dest: /etc/ntp.conf
      owner: root
      group: root
      mode: "0644"
      backup: yes
1
2
3
4
5
6
7
8
# File
- name: Change file ownership, group and permissions
  file:
      path: /etc/foo.conf
      owner: foo
      group: foo
      mode: "0644"
1
2
3
4
5
6
- name: Create a directory if it does not exist
  file:
      path: /etc/some_directory
      state: directory
      mode: "0755"
1
2
3
4
5
- name: Delete content & directory
  file:
      state: absent
      path: /home/ubuntu/tempfiles/
1
2
3
4
# Lineinfile
- name: Add a line to a file
  lineinfile:
      path: /etc/hosts
      line: 192.168.1.99 foo.lab.net foo
1
2
3
4
# Git
- name: Clone a Git repo
  git:
      repo: https://github.com/ansible/ansible-examples.git
      dest: /src/ansible-examples
1
2
3
4
# Archive
- name: Compress directory /path/to/foo/ into /path/to/foo.tgz
  archive:
      path: /path/to/foo
      dest: /path/to/foo.tgz
1
2
3
4
# Command
- name: Change the working directory to somedir/ and run the command as db_owner if /path/to/database does not exist.
  command: /usr/bin/make_database.sh db_user db_name
  become: yes
  become_user: db_owner
  args:
      chdir: somedir/
      creates: /path/to/database
1
2
3
4
5
6
7

# Opdracht

We hebben onze eerste stappen gezet in Ansible, nu is het aan jouw om je eeste Ansible playbooks te schrijven!

We willen een playbook voor het opzetten van een webserver:

  • Installeer apache
  • Installeer PHP
  • Maak een index.php pagina met de inhoud van onderaan
<?php
echo '<h1>Hello Ansible</h1>';
phpinfo();
1
2
3

Standaard gaat Oracle cloud alle poorten blocken in iptables, ook hier kunnen we in plaats van commando's te schrijven een playbook gebruiken:

- name: Allow incoming connections
  become: yes
  iptables:
      chain: INPUT
      jump: ACCEPT
      flush: yes
- name: Allow outgoing connections
  iptables:
      chain: OUTPUT
      jump: ACCEPT
      flush: yes
  become: yes
- name: Allow forwarding of connections
  iptables:
      chain: FORWARD
      jump: ACCEPT
      flush: yes
  become: yes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Ansible voor Cisco IOS

We kunnen Ansible natuurlijk ook voor meer dan enkel voor Linux servers gaan gebruiken. Een mogelijke integratie is de lessen netwerkbeheer met Cisco IOS. De IOS Collection (opens new window) heeft een uitgebreide lijst van modules voor Cisco apparaten. Ook voor IOS-XE (opens new window) is er een Ansible Collection.

Tips

Onze les switchen kunnen verouderd zijn en een oude SSH key exchange gebruiken. Dit kan je oplossen door de oude key exhanges in te schakelen:

sudo nano /etc/ssh/ssh_config
1

Unquoten de lijn Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc En voeg onderaan toe:

KexAlgorithms +diffie-hellman-group1-sha1
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
1
2
3

In requirements.yml voegen we de volgende toe:

---
collections:
    - name: cisco.ios
1
2
3

Dan installeren we de plugin:

ansible-galaxy collection install -r requirements.yml
1

Alle aparaten waar we op willen werken moeten natuurlijk SSH enabled hebben als ook een IP hebben. We kunnen deze dan ook in een hosts file zetten.

We kunnen hierna deze modules gebruiken om onze router/switch te configureren.

Je kan vele voorbelden vinden in de GitHub repository.

Dit zijn is een klein vorbeeldje:

---
- hosts: switches
  vars:
      vlan_id: 998
      vlan_name: Ansible_VLAN

  tasks:
      - name: Ensure Fa2/0/5 is configured for access vlan 20
        cisco.ios.ios_l2_interface:
            name: FastEthernet2/0/5
            mode: access
            access_vlan: { { vlan_id } }
1
2
3
4
5
6
7
8
9
10
11
12

Probeer de Ansible IOS Demo (opens new window) eens uit! Probeer nu ook twee switches tegelijk te configureren met licht verschillende configuraties.

# Resources

Ga je in je project Ansible gebruiken? Lees dan zeker deze resources!

Last update: October 15, 2022 13:20
Contributors: Maartje Eyskens