Slide 1

Slide 1 text

Role over, lay down Testing Roles With Molecule Ton Kersten Antwerp / Belgium / 2018

Slide 2

Slide 2 text

Agenda 1 Introduction 2 Why 3 Question Time! ans-v1.25-2

Slide 3

Slide 3 text

$ who am i --- - name: Ton Kersten creds: work: UNIX/Linux consultant and Trainer @ AT Computing linux: UNIX/Linux Geek (UNIX since 1986, Linux since 1992) scripting: Scripting / programming Freak cfgmgmt: Configuration Management Addict - ansible: - Ansible user and contributor since 2012 - Red Hat Certified Specialist in Ansible Automation - Ansible Ambassador since 2015 foss: Free and Open Source Software Enthusiast things: Big fan of things that just work ans-v1.25-3

Slide 4

Slide 4 text

Why test roles Ansible playbooks and roles are production code Check installation of required packages Process and check needed templates Check files for contents Check running and enabled services Trigger handlers · · · ans-v1.25-4

Slide 5

Slide 5 text

Return of investment Higher role and playbook quality Improved reliability ⇒ Less interruptions Ensuring consistency Improve Robustness Automatic testing ⇒ Continues Integration / Deployment · · · ans-v1.25-5

Slide 6

Slide 6 text

Molecule Open Source (of course) Designed to test Ansible roles Uses Ansible to test Ansible roles Supports different OS’s / test scenarios Supports different test frameworks Supports multiple virtualization providers Setup The tools Molecule Testinfra Docker ansible-lint flake8 ans-v1.25-6 # apt-get install docker-engine # pip install ansible # pip install ansible-lint # pip install 'docker-py<3.0' # pip install molecule # pip install yamllint # pip install flake8 # pip install testinfra

Slide 7

Slide 7 text

Get started Version 1 $ molecule init --role chrony --driver docker Version 2 $ molecule init role \ --role-name=chrony \ --driver-name=docker \ --verifier-name=testinfra ans-v1.25-7

Slide 8

Slide 8 text

Configure linter molecule/default/molecule.yml (Part 1) lint: name: yamllint options: config-file: molecule/default/yamllint.cfg molecule/default/yamllint.cfg extends: default rules: line-length: max: 132 level: warning allow-non-breakable-words: true allow-non-breakable-inline-mappings: false truthy: disable ans-v1.25-8

Slide 9

Slide 9 text

Configure provisioner molecule/default/molecule.yml (Part 2) # # Ansible provisioner and variables # provisioner: name: ansible inventory: group_vars: # Mock data for Ansible group_vars all: name: Wile E. Coyote company: ACME domain: acme.net host_vars: # Mock data for Ansible host_vars centos7: foo: bar lint: name: ansible-lint ans-v1.25-9

Slide 10

Slide 10 text

Configure verifier molecule/default/molecule.yml (Part 3) verifier: name: testinfra options: verbose: False debug: False lint: name: flake8 options: ignore: "E201,E202,E203,E211,E223,E224" ans-v1.25-10 E201: whitespace after char E202: whitespace before char E203: whitespace before char E211: whitespace before text E223: tab / multiple spaces before operator E224: tab / multiple spaces after operator

Slide 11

Slide 11 text

Configure CentOS molecule/default/molecule.yml (Part 4) - name: centos7 hostname: centos7 image: couchbase/centos7-systemd image_version: latest privileged: True groups: - chrony - centos command: "/usr/sbin/init" # Mount cgroup volumes on Debian 9 host volumes: - "/sys/fs/cgroup:/sys/fs/cgroup:rw" ans-v1.25-11 Run /sbin/init to startup systemd

Slide 12

Slide 12 text

Configure Ubuntu molecule/default/molecule.yml (Part 5) - name: ubuntu1604 hostname: ubuntu1604 image: solita/ubuntu-systemd image_version: latest privileged: True groups: - chrony - ubuntu command: "/sbin/init" ans-v1.25-12 Run /sbin/init to startup systemd

Slide 13

Slide 13 text

Create tests 1 molecule/default/tests/test_default.py import testinfra.utils.ansible_runner as ti # Get all hosts from the Ansible inventory # The inventory is generated from the molecule.yml file inventory = '.molecule/ansible_inventory' hosts = ti.AnsibleRunner(inventory).get_hosts('all') ans-v1.25-13 Setup framework and get all Ansible hosts

Slide 14

Slide 14 text

Create tests 2 molecule/default/tests/test_default.py def test_services(host): try: facts = host.ansible("setup")["ansible_facts"] except host.ansible.AnsibleException as exc: assert exc.result['failed'] is True assert exc.result['msg'] == 'Error getting facts' osfam = facts['ansible_os_family'].lower() if osfam == 'debian': present = [ host.service('chrony') ] elif osfam == 'redhat': present = [ host.service('chronyd') ] else: raise EnvironmentError("'%s' is an unsupported OS" % osfam) ans-v1.25-14 Get all Ansible facts and check OS family

Slide 15

Slide 15 text

Create tests 3 molecule/default/tests/test_default.py if present: for this in present: assert this.is_installed ans-v1.25-15 Check if all packages are installed

Slide 16

Slide 16 text

Create tests 4 molecule/default/tests/test_default.py if present: for this in present: assert this.exists assert this.is_file assert this.uid == 0 assert this.gid == 0 assert this.mode == 0o644 assert this.contains("# Copyright (c) 2012-today by ACME") ans-v1.25-16 Check if files have the correct content and credentials

Slide 17

Slide 17 text

Create tests 5 molecule/default/tests/test_default.py if present: for this in present: assert this.is_running assert this.is_enabled ans-v1.25-17 Check if all services are running and enabled

Slide 18

Slide 18 text

Running tests molecule create molecule converge molecule verify Fix molecule login molecule destroy Correct? No Yes molecule test ans-v1.25-18

Slide 19

Slide 19 text

Problems Fragile environment Versions of tools must match Sudden, unexpected breaking of test line Needs Python Docker < 3.0 Large difference between version 1 and 2 Documentation not always clear · · · ans-v1.25-19

Slide 20

Slide 20 text

Question Time! Questions?? Contact me [email protected] http://www.atcomputing.nl https://github.com/tonk https://speakerdeck.com/tonk @TonKersten on Twitter TKersten on IRC Created with L A TEX Beamer Vim Poppler Tools ImageMagick Evince ans-v1.25-20