Meetup Ansible #2

28 mars 2019 – organisé par Evolix

  • 18h – accueil, discussions…
  • 19h – présentation
  • 20h – apéro

              $ who
              Jérémy Lecour <jlecour@evolix.fr>
              Grégory Colpart <reg@evolix.fr>

              $ whois Evolix
              EVOLIX-AS : AS 197696

              $ man Evolix
              Open Source managed hosting provider

              $ uptime
              up 14 years, 20 users

              $ whereis Evolix
              /fr/Marseille, /fr/Aix, /fr/Paris, /ca/Montréal

              $ top
              Linux/BSD servers: 800, customers: 120
            

  • Infogérance / Hébergement dédié et Cloud / Conseil et Formations
  • Linux, infra web, HA, virtualisation, conteneurs, Ansible
  • Clients : agences web, SaaS, médias
Ansible

Automatisation de configuration d'infrastructure et déploiement

Des nouvelles d'Ansible

releases Ansible

  • Ansible 2.5 : mars 2018
  • Ansible 2.6 : juin 2018
  • Ansible 2.7 : octobre 2018
  • Ansible 2.8 : prévue pour le 2 mai 2018

depuis décembre

  • v2.5.15
  • v2.6.15
  • v2.7.9
Ansible

Ansible et Debian

  • ansible 2.7 sera dans Debian 10
  • ...déjà disponible via backports Debian 9
  • ansible-lint 4.1 sera dans Debian 10
  • ...déjà disponible via backports Debian 9

#AnsibleFest

24-26 septembre 2019 à Atlanta

ansible.com/blog

  • Ansible Tips and Tricks: Dealing with Unreliable Connections and Services
  • Deep Dive on cli_command for Network Automation
  • Ansible Community Update — February 2019

webinar

Ansible Best Practices: Roles and Modules

Commentaires de commande


###
# ansible-playbook evolinux.yml --ask-vault-pass --diff --check
---
- hosts: all
  gather_facts: yes
  become: yes

  vars_files:
    - vars/evolinux-secrets.yml

  roles:
    - evolinux-base
    - evolinux-users
            

Commentaires de commande (2)


###
# ansible-playbook upgrade.yml -K --ask-vault-pass --skip-tags post-upgrade --diff (--check)
#
# The upgrade has 3 steps :
# 1. Run the playbook with "--skip-tags post-upgrade" before dist-upgrade
# 2. SSH into the server to do `apt dist-upgrade`
# 3. Run the playbook with "--skip-tags pre-upgrade" after dist-upgrade
#
# Reference documentation can be found at
# https://wiki.evolix.org/HowtoDebian/MigrationJessieStretch
#
# Each group of task has one or multiple tags to selectively run tasks.
# see https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html
            

Handler conditionnel

# roles/minifirewall/handlers/main.yml

---
- name: restart minifirewall
  command: /etc/init.d/minifirewall restart
  register: minifirewall_init_restart
  failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout"
  changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout"

- name: restart minifirewall (noop)
  meta: noop
  register: minifirewall_init_restart
  failed_when: False
  changed_when: False
            

Handler conditionnel (3)

# roles/minifirewall/tasks/main.yml

- set_fact:
    minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed \
        | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
            
# roles/minifirewall/defaults/main.yml

minifirewall_restart_if_needed: True
            

Handler conditionnel (4)

# firewall.yml

##
# ansible-playbook firewall.yml
---

- hosts: all
  gather_facts: yes
  become: yes

  vars:
    # Set this variable to False to disable the restart handler execution.
    minifirewall_restart_if_needed: True

  roles:
    - minifirewall
            

Handler conditionnel (2)


---
- blockinfile:
    dest: "{{ minifirewall_tail_file }}"
    marker: "# {mark} PRIVATE LAN"
    block: |
      /sbin/iptables -A INPUT -i eth0 -j ACCEPT
  notify: "{{ minifirewall_restart_handler_name }}"
            

Vérification avant de se lancer

# roles/upgrade-jessie-to-stretch/tasks/main.yml
---
- name: "System compatibility checks"
  assert:
    that:
      - ansible_distribution == "Debian"
      - ansible_distribution_major_version | version_compare('8', '>=')
      - ansible_distribution_major_version | version_compare('9', '<=')
    msg: only compatible with Debian = 8 and 9
  when: upgrade_stretch_check_compatibility
            

Découpage des gros rôles


- include: backup.yml
  tags: backup

- include_role:
    name: etc-git
  tags: etc-git-install

- include_role:
    name: etc-git
    tasks_from: commit.yml
  vars:
    commit_message: "Ansible pre-run upgrade-jessie-to-stretch.yml"
  tags: etc-git-commit

- include: mysql-pre.yml
  when: is_mysql.rc == 0 or is_mariadb.rc == 0
  tags: mysql
            

Capture de tâches et debug


- command: "cat /etc/evolinux/todo.txt"
  changed_when: False
  failed_when: False
  check_mode: no
  register: evolinux_todo

- debug:
    var: evolinux_todo.stdout_lines
  when: evolinux_todo.stdout != ""
            

with_first_found

# roles/haproxy/tasks/main.yml
- name: Copy HAProxy configuration
  template:
    src: "{{ item }}"
    dest: /etc/haproxy/haproxy.cfg
  with_first_found:
    - "templates/haproxy/haproxy.{{ inventory_hostname }}.cfg.j2"
    - "templates/haproxy/haproxy.{{ host_group }}.cfg.j2"
    - "templates/haproxy/haproxy.default.cfg.j2"
    - "haproxy.default.cfg.j2"
            

Une sorte d'annuaire local

# vars/main.yml
users_db:
  foo:
    name: foo
    uid: 42081
    fullname: 'Mr Foo'
    password_hash: "$6$6/CHVo1Ftrsmn805xY"
  bar:
    name: bar
    uid: 42082
    fullname: 'Mr Bar'
    password_hash: "$6$6/Ctrsmn80HVo1F5xY"
    ssh_keys:
      - "ssh-rsa AAAAB3NzaC1ycBe6mRGUw=="
            

Une sorte d'annuaire local (2)

# roles/users/tasks/main.yml
- assert:
    that: users_db != {}
    msg: "Error: empty variable 'users_db'!"

- include: adduser.yml
  vars:
    user: "{{ users_db[item] }}"
  with_items: "{{ users_present | default([]) }}"

- include: deluser.yml
  loop_control:
    loop_var: name
  with_items: "{{ users_absent | default([]) }}"
            

Gestion fine des variables

# roles/users/tasks/main.yml
- set_fact:
    users_absent: "{{ (users_absent_for_all + users_absent_for_group \
                      + users_absent_for_host) | unique }}"

- set_fact:
    users_present: "{{ (users_present_for_all + users_present_for_group \
                      + users_present_for_host | unique | difference(users_absent) }}"
            

Gestion fine des variables (2)

# group_vars/all.yml
users_present_for_all:
  - foo
users_absent_for_all:
  - qux
            
# group_vars/database.yml
users_present_for_group: []
              
# host_vars/sql00.yml
users_present_for_host:
  - bar
                

Syntaxe complexe dans un template

# /etc/filebeat/filebeat.yml
# Elasticsearch output
output.elasticsearch:
  hosts: ['192.168.10.42:9200', '192.168.10.43:9200']
            
# host_vars/sql00.yml
  ---
  filebeat__elasticsearch_hosts:
    - "192.168.10.42:9200"
    - "192.168.10.43:9200"
              
# roles/filebeat/templates/filebeat.yml.j2
  # Elasticsearch output
  output.elasticsearch:
    hosts: {{ filebeat__elasticsearch_hosts | to_yaml }}
              

Adoptez des conventions

https://gitea.evolix.org/evolix/ansible-public/
CONVENTIONS.md

Merci

à vos questions

Et la suite ?