# 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

GC
Bonjour à tous,
Jérémy et moi-même faisons partie d'Evolix, entreprise créée en 2004,
on propose des services d'hébergement et d'infogérance à base de Logiciels Libres.
Nous avons des bureaux et une équipe en France et au Canada.
Pour situer, nous infogérons 800 serveurs pour 120 infras client.

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

GC
Notre 1er métier, l'infogérance = prendre soin des serveurs
Infra d'hébergement sur 4 datacenters, opère notre réseau
On fait du conseil et de la formation sur mesure.
contrairement à nos concurrents, 22h00 pas une astreinte, une vraie équipe.
Mots clés, technologies d'expertise.
Nos clients. On a des supers clients, on a le luxe de les choisir, on aime les défis !

#### Automatisation de configuration d'infrastructure et déploiement

# Ansible

#

- outil d’automatisation de configuration et gestion de serveurs
- déploiement de logiciels et l’exécution de tâches via une connexion SSH
- principes : agent-less et idempotence

# 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 2018

- v2.5.15
- v2.6.15
- v2.7.9

### 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 ?

- dites-nous ce que vous espérez
- venez parler de vos cas d'usages
- www.meetup.com/Ansible-Marseille/
- @ansible_mrs