Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tools for Testing Ansible Roles/Playbooks and Why You Should Use Them

Tools for Testing Ansible Roles/Playbooks and Why You Should Use Them

2d9c7a8cdab3ace496e6d4c68ac7ef1c?s=128

Roderick Randolph

July 26, 2018
Tweet

Transcript

  1. Tools for Testing Ansible Roles/Playbooks And Why You Should Use

    Them Roderick R. Randolph
  2. Who am I Roderick R. Randolph Opinions expressed are solely

    my own and do not express the views or opinions of my employer. /roderickrandolph •RRR •Raised in Amelia County, VA •Lived in Toronto for 2 years •Employed by Capital One •DevOps Architect
  3. This Talk •Why Ansible •What are Ansible Roles •Importance of

    Testing Ansible Roles •Tools for Testing Ansible Roles •Live Demo
  4. What is Ansible? Ansible is an IT automation tool. It

    can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates. http://docs.ansible.com/ansible/
  5. Ansible Goals • Easy to Use No agent to install

    or configure • Simple Describe desired state in human-readable YAML • Secure and Reliable Uses industry standard OpenSSH utilities • Extensible Create custom modules to make Ansible even more powerful
  6. # playbook.yml --- - hosts: all tasks: - name: install

    nginx package yum: name: nginx state: present - name: start nginx server systemd: name: nginx enabled: yes state: started Your First Playbook
  7. Image Credit: https://flic.kr/p/5rQphw

  8. A Month Later…

  9. --- - hosts: all tasks: - name: install nginx package

    yum: name: nginx state: present when: ansible_os_family == 'RedHat' - name: install nginx package apt: name: nginx state: present when: ansible_os_family == 'Ubuntu' - name: copy nginx configuration in place template: src: "{{item}}.j2" dest: /etc/nginx/main.d/{{item}} mode: 0644 with_items: - nginx.conf - vhosts.conf - name: create source directory file: path: /src state: directory mode: 0755 - name: copy source code copy: src: "{{lookup('pipe', 'dirname `pwd`')}}/{{item}}" dest: /src/{{item}} with_items: - package.json - app.js - name: install npm packages npm: path: /src state: latest production: yes - name: RedHat - Ensure Java is installed yum: name: "{{ java }}" state: "present" update_cache: yes when: ansible_os_family == 'RedHat' # - name: Debian - Refresh java repo # apt: update_cache=yes # changed_when: false # when: ansible_os_family == 'Debian' - name: Debian - Ensure Java is installed apt: name={{ java }} state="present" when: ansible_os_family == 'Debian' - name: Check java version command: java -version 2>&1 | grep OpenJDK register: open_jdk changed_when: false # https://github.com/docker-library/openjdk/issues/19 - ensures tests pass due to java 8 broken certs - name: refresh the java ca-certificates command: /var/lib/dpkg/info/ca-certificates-java.postinst configure when: ansible_distribution == 'Ubuntu' and open_jdk.rc == 0 changed_when: false - name: install tomcat package yum: name: tomcat state: present when: ansible_os_family == 'RedHat' - name: install tomcat package apt: name: tomcat state: present when: ansible_os_family == 'Ubuntu' - name: install java app on server copy: src: app.war dest: /usr/share/tomcat/webapps/app.war - name: start nginx server systemd: name: nginx enabled: yes state: started with_items: ['nginx', 'tomcat']
  10. Image Credi: https://flic.kr/p/7NJh8

  11. Ansible offers a powerful DSL • Variables Manage data values

    and differences between systems • Conditionals Skip tasks based on value of variables • Loops Repeat things in one task • Templating Create dynamic expressions, filters, lookups, and tests
  12. Image Credit: https://bit.ly/2mLWAmu

  13. Ansible Playbook "Code Smell" • Duplicate tasks • Large number

    of tasks Minimize the number of tasks to 5-6 per play • Complex loops and conditionals Ansible is not a substitute for a programming language • Hard coded variables / inconsistent naming conventions • Heavy tight coupling between roles • No tests
  14. None
  15. None
  16. # playbook.yml --- - hosts: all roles: - nginx -

    tomcat - newrelic - fluentd Refactor To Use Ansible Roles
  17. Ansible Roles • Provide a layer of abstraction to help

    organize playbook tasks (improve readability and intent) • Create reusable and common tasks that can be shared across playbooks (minimize duplication) • Breaks playbook into smaller unit of work (reduced complexity) • Can be tested independently
  18. # playbook.yml --- - hosts: all roles: - newrelic -

    fluentd tasks: - import_role: name: nginx - include_role: name: tomcat Mix Ansible Roles With Tasks
  19. Image Credit: https://flic.kr/p/77B38H

  20. None
  21. None
  22. Importance of Testing Ansible Roles • Higher quality roles Easy

    to maintain, extend, comprehend • Increased confidence Fewer bugs and rework • Validate Ansible upgrade compatibility • Self-documented example use cases
  23. Testing Strategies for Ansible • Unit testing Performed at the

    Ansible module-level • Functional testing Use Ansible to test Ansible! • Integration testing Ensures roles work together as intended
  24. Tools for Testing Ansible Roles

  25. https://www.ansible.com/

  26. Testing Ansible with Ansible # playbook.yml --- - hosts: all

    tasks: - wait_for: host: "{{ inventory_hostname }}" port: 8080 delegate_to: localhost
  27. Testing Ansible with Ansible # playbook.yml --- - hosts: all

    tasks: - uri: url: http://www.example.com return_content: yes register: webpage - fail: msg: website is unavailable when: "'AWESOME' not in webpage.content"
  28. Testing Ansible with Ansible # playbook.yml --- - hosts: all

    tasks: - shell: /usr/bin/some-command --parameter value register: command_results - assert: that: website is unavailable - "'not ready' not in command_results.stderr" - "'gizmo enabled' in command_results.stdout"
  29. https://github.com/metacloud/molecule

  30. Testing Ansible with Molecule --- dependency: name: galaxy driver: name:

    docker lint: name: yamllint platforms: - name: centos7 image: milcom/centos7-systemd privileged: True provisioner: name: ansible scenario: name: default verifier: name: testinfra $ molecule lint $ molecule syntax $ molecule setup $ molecule idempotence $ molecule destroy ... --> Scenario: 'default' --> Action: 'lint' --> Executing Yamllint on files found... Lint completed successfully. --> Executing Flake8 on files found... Lint completed successfully. --> Executing Ansible Lint on... Lint completed successfully.
  31. https://kitchen.ci/

  32. Testing Ansible with Test Kitchen --- driver: name: ec2 provisioner:

    name: ansible_playbook platforms: - name: ubuntu-16.04 - name: centos-7 suites: - name: default verifier: name: inspec $ kitchen create $ kitchen converge $ kitchen setup $ kitchen verify $ kitchen destroy --> Running rspec test suites ✔ git binary is found in PATH 3 tests, 2 failures Finished verifying <default-ubuntu-1404> (0m0.98s). --> Destroying --> Kitchen is finished. (1m44.11s)
  33. Image Credit: https://flic.kr/p/JykJBD

  34. Wrap Up • Ansible playbooks and roles should be treated

    as code • Refactor playbooks to use ansible roles and avoid code smell • Use test tools to verify your Ansible roles to increase your confidence
  35. Image Credit: https://flic.kr/p/47z3PA