Slide 1

Slide 1 text

#DevoxxFR Ansible Ultimate Edition Université Devoxx 2022 Aurélien MAURY Gautier LOTERMAN 1

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

#DevoxxFR WeScale est une société de service regroupant 50 passionnés, basés à Paris, Nantes et en agence Full Remote. Notre mission, c’est d’accompagner les entreprises à devenir Cloud Native. Nous avons l’ambition d’aider nos clients à Penser, Construire et Maîtriser leurs infrastructures et applications Cloud.

Slide 4

Slide 4 text

NOS PARTENARIATS 2015 +50 Création de WeScale Passionné(e)s de Cloud PARIS NANTES FULL REMOTE ON RECRUTE

Slide 5

Slide 5 text

Aurélien MAURY Gautier LOTERMAN

Slide 6

Slide 6 text

3 heures de bonheur intense Intro Concepts ● Définitions ● Terminologie ● CLI Toolbox Syntaxe ● Variables ● Templating ● Fil d'exécution Organisation de projet ● Initialisation ● Gestion de dépendances ● Packaging

Slide 7

Slide 7 text

3 heures de bonheur intense Testing ● Molecule ● Verifiers ● Conseils CI/CD & IaC ● Place d'Ansible ● Approches IaC ● Exemple avec Gitlab Développement de plugins ● La minute nécessaire ● Plugins Actions ● Plugins Filter

Slide 8

Slide 8 text

3 heures de bonheur intense SI Ansible-centré ● AWX ● ARA ● Stratégies de déploiement Anatomie d'un projet ● HashiStack Project ● Intégration Terraform ● Vault-Consul-Nomad Le mot de la fin

Slide 9

Slide 9 text

Ça… c'était le plan…

Slide 10

Slide 10 text

Le format

Slide 11

Slide 11 text

Prouver par l'exemple

Slide 12

Slide 12 text

À voir et à revoir en famille https://ansible-ultimate-edition.rtfd.io

Slide 13

Slide 13 text

Techniques validées sur le terrain

Slide 14

Slide 14 text

Mode d'emploi

Slide 15

Slide 15 text

Concepts Parés ?

Slide 16

Slide 16 text

Concepts

Slide 17

Slide 17 text

Définition Concepts

Slide 18

Slide 18 text

Orchestrateur

Slide 19

Slide 19 text

Ingrédients Jinja

Slide 20

Slide 20 text

Provisioning

Slide 21

Slide 21 text

Connectivité

Slide 22

Slide 22 text

Sans agent

Slide 23

Slide 23 text

Idempotence

Slide 24

Slide 24 text

User Space

Slide 25

Slide 25 text

Et la famille ? Imhotep ? ● Ruby ● Abstraction plus élevée ● Avec agent ● Bibliothèques plus fournies ● Communauté de relecteurs

Slide 26

Slide 26 text

Ça va, Imhotep. ● Python ● Avec agent ● Salt-SSH ● Fédération de master ● Preprocessing YAML

Slide 27

Slide 27 text

Et là, normalement vous vous dites…

Slide 28

Slide 28 text

C'est décidé on adopte.

Slide 29

Slide 29 text

Terminologie Concepts

Slide 30

Slide 30 text

Inventaires Liste de machines avec lesquelles interagir, organisées en groupes. Un inventaire peut être statique ou dynamique. # hosts.ini est un fichier statique écrit ou généré :~$ ansible --inventory=hosts.ini [...] # dyn_inventory est un exécutable retournant du JSON sur la sortie standard :~$ ansible --inventory=dyn_inventory [...]

Slide 31

Slide 31 text

Inventaire statique Écrit avec amour ou généré avec passion. web_1 ansible_host=10.10.10.101 ansible_ssh_private_key_file=... web_2 ansible_host=10.10.10.102 ansible_ssh_private_key_file=... [web_servers] web_1 web_2 [databases] db_1 ansible_host=10.10.20.201 ansible_ssh_private_key_file=... 10.10.20.202 ansible_ssh_private_key_file=... [production:children] web_servers databases

Slide 32

Slide 32 text

Inventaire dynamique Exécutable retournant du JSON sur la sortie standard. 2 options à supporter pour être conforme. Branchez vos inventaires dynamiques sur des plateformes connaissant les machines (AWS, OpenStack, Cobbler, Consul, …). :~$ ./dyn_inventory --list { "databases" : { "hosts" : [ "db_1", "10.10.20.202" ] }, "web_servers" : [ "web_1", "web_2" ], "production" : { "children": [ "web_servers", "databases" ] } } :~$ ./dyn_inventory --host web_1 { "ansible_host": "10.10.10.101" }

Slide 33

Slide 33 text

Tasks Plus petite unité d'action disponible. A l'exécution peut être : ● changed ● ok ● failed --- - name: un joli titre c’est mieux apt: pkg: "tmux" state: present

Slide 34

Slide 34 text

Playbook Liste de Play. Un play étant une liste de rôles et/ou de tâches à appliquer sur un groupe de machines. --- - name: SSH restart hosts: web_servers become: yes tasks: - service: name: sshd state: restarted - name: Nginx install hosts: web_servers become: yes tasks: - apt: name: nginx state: present - service: name: nginx enable: yes state: restarted

Slide 35

Slide 35 text

Handler Task lancée en fin de play si notifiée par une autre task. Un handler notifié plusieurs fois ne sera exécuté qu’une fois. --- - hosts: webservers tasks: - template: [...] notify: restart my service handlers: - name: restart my service service: name: my_service state: restarted

Slide 36

Slide 36 text

Rôle Unité de réutilisation de code Ansible. Peut contenir : ● des tasks ● des handlers ● des templates ● des fichiers statiques ● des variables role/ ├── defaults │ └── main.yml --> variables par défaut ├── files --> fichiers statiques ├── handlers │ └── main.yml --> handlers ├── meta │ └── main.yml --> fiche d'info et dépendances ├── tasks │ └── main.yml --> tâches (appels de modules) ├── templates --> templates Jinja2 ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml --> variables fortes

Slide 37

Slide 37 text

Collection Unité de réutilisation de code Ansible. Peut contenir : ● des rôles ● des playbooks ● des plugins collection/ ├── docs/ ├── galaxy.yml ├── meta/ │ └── runtime.yml ├── plugins/ │ ├── modules/ │ │ └── module1.py │ ├── inventory/ │ └── .../ ├── README.md ├── roles/ │ ├── role1/ │ ├── role2/ │ └── .../ ├── playbooks/ │ ├── files/ │ ├── vars/ │ ├── templates/ │ └── tasks/ └── tests/

Slide 38

Slide 38 text

Un playbook sauvage apparaît

Slide 39

Slide 39 text

CLI Toolbox Concepts

Slide 40

Slide 40 text

ansible Lancement unitaire d’un module sur un ensemble de machines, sans playbook. :~$ ansible --inventory=hosts.ini -m service -a "name=ntp state=restarted" all

Slide 41

Slide 41 text

ansible-playbook Lancement d’un playbook. :~$ ansible-playbook --inventory=hosts.ini mon_playbook.yml

Slide 42

Slide 42 text

ansible-pull Clone un repository git et exécute le playbook.yml ou local.yml se trouvant à la racine. :~$ ansible-pull -U git@github.com:me/myrepo.git

Slide 43

Slide 43 text

ansible-galaxy Installe un ou plusieurs rôles et/ou collections depuis des sources distantes. Génère le squelette d'un nouveau rôle ou d’une collection Publie rôle et collection vers un repository Galaxy. :~$ ansible-galaxy role install bennojoy.nginx :~$ ansible-galaxy collection install -fr requirements.yml :~$ ansible-galaxy role init mon_role_amoi

Slide 44

Slide 44 text

requirements.yml Fichier de requirements pour ansible-galaxy --- # requirements.yml - src: yatesr.timezone - src: https://github.com/bennojoy/nginx - src: https://github.com/bennojoy/nginx version: master name: nginx-role - src: https://example.com/files/master.tar.gz name: http-role

Slide 45

Slide 45 text

ansible-doc Obtenir la documentation d’un module en ligne de commande. # liste de tous les modules disponibles :~$ ansible-doc --list # documentation d’un module :~$ ansible-doc $module

Slide 46

Slide 46 text

ansible-vault Chiffre/déchiffre des fichiers de variables Un fichier de variable chiffré peut être utilisé par un playbook : ● par prompt si l'option --ask-vault-pass est passée ● de façon transparente si la variable d'env ANSIBLE_VAULT_PASSWORD_FILE est définie :~$ ansible-vault [create|decrypt|edit|encrypt|rekey|view] vaultfile.yml

Slide 47

Slide 47 text

Syntaxe

Slide 48

Slide 48 text

Variables Syntaxe

Slide 49

Slide 49 text

Précédence des variables Une variable peut être définie à différents endroits. Si elle est définie plusieurs fois au même niveau, ça lève un Warning et seule la dernière définition est prise en compte. role defaults inventory file or script group vars inventory group_vars/all playbook group_vars/all inventory group_vars/* playbook group_vars/* inventory file or script host vars inventory host_vars/* playbook host_vars/* host facts / cached set_facts play vars play vars_prompt play vars_files role vars (defined in role/vars/main.yml) block vars (only for tasks in block) task vars (only for the task) include_vars set_facts / registered vars role (and include_role) params * include params extra vars (always win precedence)

Slide 50

Slide 50 text

role defaults inventory file or script group vars inventory group_vars/all playbook group_vars/all inventory group_vars/* playbook group_vars/* inventory file or script host vars inventory host_vars/* playbook host_vars/* host facts / cached set_facts play vars play vars_prompt play vars_files role vars (defined in role/vars/main.yml) block vars (only for tasks in block) task vars (only for the task) include_vars set_facts / registered vars role (and include_role) params * include params extra vars (always win precedence) Précédence des variables Plus on s'étale, plus le troubleshooting se complexifie…

Slide 51

Slide 51 text

Norme de nommage Le nom d’une variable doit : ● commencer par une lettre ● contenir uniquement lettres, chiffres et underscores

Slide 52

Slide 52 text

Convention pour les variables de rôles defaults/main.yml : configuration du rôle ● rolename_* set_fact : valeurs de sortie ● rolename_fact_* vars/main.yml : variables interne ● __rolename_*

Slide 53

Slide 53 text

Variables magiques ● inventory_dir ● group_names ● groups ● hostvars ● playbook_dir ● role_path

Slide 54

Slide 54 text

Facts Le module setup, lancé par défaut au démarrage de chaque playbook, collecte des ansible_facts sur le host : ● ansible_processor_cores : Nombre de coeurs ● ansible_memtotal_mb : Mémoire ● ansible_interfaces : Interfaces réseaux ● ansible_distribution : Distribution ● ansible_architecture : Architecture $ ansible -m setup localhost

Slide 55

Slide 55 text

Custom Facts Vous pouvez créer des fichiers dans /etc/ansible/facts.d/*.fact pour créer des facts collectés par le module setup. Ces fichiers doivent contenir du JSON, du INI ou être exécutable et retourner du JSON. Ces facts seront rangés dans la variable ansible_local. /etc/ansible/facts.d/mes_miens.fact ==> contenus dans la variable ansible_local.mes_miens

Slide 56

Slide 56 text

Templating Syntaxe

Slide 57

Slide 57 text

Interpolation - name: Common private ssl directory exist file: path: "{{ vault_tls_dir }}" owner: root group: ssl-cert state: directory mode: 0750 - name: Upload CA certificate copy: src: "{{ vault_local_ca_cert }}" dest: "{{ vault_ca_certificate }}" owner: root group: ssl-cert mode: 0644 notify: Update ca trust when: vault_use_custom_ca

Slide 58

Slide 58 text

{% for partner_peer in vault_master_partners %} # Peer index in list is {{ loop.index0 }} retry_join { leader_api_addr = "{{ vault_api_protocol }}://{{ partner_peer }}:{{ vault_api_port }}" {% if vault_use_custom_ca %} # Truth must be said leader_ca_cert_file = "{{ vault_ca_certificate }}" {% endif %} leader_client_key_file = "{{ vault_self_private_key }}" leader_client_cert_file = "{{ vault_self_certificate }}" } {% endfor %} {% raw %} # Fin de boucle {% for partner_peer in vault_master_partners %} {% endraw %}

Slide 59

Slide 59 text

Filters "{{ input_var | from_json }}" "{{ input_var | to_json }}" "{{ input_var | to_nice_json(indent=2) }}" "{{ input_var | from_yaml }}" "{{ input_var | to_yaml }}" "{{ input_var | to_nice_yaml(indent=2) }}" "{{ username | default('admin') }}" Ansible propose un système de transformateurs pipables nommés filters. Les filters sont utilisables partout où une interpolation est faite.

Slide 60

Slide 60 text

default - name: touch files with an optional mode file: dest: "{{ item.path | default('/tmp/void.tmp')}}" state: touch mode: "{{ item.mode | default(omit) }}" loop: - path: /tmp/foo - mode: "0444" - path: /tmp/baz mode: "0444" Permet de gérer les cas où une variable utilisée n'est pas définie. La valeur spéciale omit invalide le set de l'attribut.

Slide 61

Slide 61 text

Listes "{{ list1 | unique }}" "{{ list1 | union(list2) }}" "{{ list1 | intersect(list2) }}" "{{ list1 | difference(list2) }}" "{{ list1 | symmetric_difference(list2) }}" Filtres de manipulation de listes de valeurs.

Slide 62

Slide 62 text

Jinja Filters

Slide 63

Slide 63 text

Fil d'exécution Syntaxe

Slide 64

Slide 64 text

Point d'entrée Une exécution Ansible commence par un playbook Ansible. Seront exécutés (dans cet ordre) : ● pre_tasks ● roles ● tasks ● post_tasks ● (handlers)

Slide 65

Slide 65 text

Condition d'exécution tasks: - name: Shut down CentOS 6 systems ansible.builtin.command: /sbin/shutdown -t now when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "6" Chaque appel de module peut être conditionné à une évaluation booléenne avec un attribut when. Si on fourni une liste à when, tous les éléments sont liés par un ET logique. Un when est systématiquement considéré comme une interpolation (pas de moustache).

Slide 66

Slide 66 text

Imports & Includes import_playbook – Importe un playbook import_role – Importe un role dans un play import_tasks – Importe un fichier de tasks include – Inclut un play / fichier de tasks include_role – Charge et exécute un role include_tasks – Charge un fichier de tasks include_vars – Charge les variables d'un fichier Les import_* sont évalués statiquement au chargement du plan d'exécution du playbook. Les include_* sont évalués en cours d'exécution et peuvent être soumis à des conditions when, des boucles, etc.

Slide 67

Slide 67 text

Loops - name: add several users user: name: "{{ item }}" state: present groups: "wheel" loop: - testuser1 - testuser2 - name: add several users user: name: "{{ item }}" state: present groups: "wheel" loop: "{{ user_list }}" Un appel de module peut être bouclé par l'ajout d'un attribut loop.

Slide 68

Slide 68 text

Better Loops - name: add several users user: name: "{{ _current_user }}" state: present groups: "wheel" loop: - testuser1 - testuser2 loop_control: loop_var: _current_user Pour éviter les collisions de nommage et les effets de bords associés, prenez l'habitude de nommer votre variable de boucle.

Slide 69

Slide 69 text

Dict Loops - name: add several users user: name: "{{ _current_user.name }}" state: present groups: "{{ _current_user.groups }}" loop: - name: "testuser1" groups: "wheel" - name: "testuser2" groups: "root" loop_control: loop_var: _current_user Bouclage sur des liste de dict.

Slide 70

Slide 70 text

Nested Loops vars: list_one: - "a" - "b" list_two: - "1" - "2" tasks: - name: with_nested -> loop debug: msg: "{{ _tuple.0 }} - {{ _tuple.1 }}" loop: "{{ list_one|product(list_two)|list }}" loop_control: loop_var: _tuple Le filtre product permet de construire des boucles imbriquées. Cet exemple donnera les messages de debug successifs : "a - 1" "a - 2" "b - 1" "b - 2"

Slide 71

Slide 71 text

Organisation de projet

Slide 72

Slide 72 text

Initialisation Organisation de projet

Slide 73

Slide 73 text

Playbook ? Rôle ? Collection ? Il n'y a que 2 cas : ● soit vous développez un rôle qui sera une dépendance plusieurs projets ● soit vous développez une collection Rôle consommé uniquement par une même collection ? => dans la collection

Slide 74

Slide 74 text

Init de projet $ ansible-galaxy role init namespace.role_name - Role namespace.role_name was created successfully $ ansible-galaxy collection init \ namespace.collection_name - Collection namespace.collection_name was created successfully Ansible-galaxy à la rescousse.

Slide 75

Slide 75 text

Les choses sérieuses commencent.

Slide 76

Slide 76 text

Gestion de dépendances Organisation de projet

Slide 77

Slide 77 text

Ayez un Virtualenv dédié Une dépendance mal considérée : ● Ansible lui-même Un virtualenv dédié vous permet d'installer des versions fixes sans perturber vos autres projets.

Slide 78

Slide 78 text

Retour de terrain Gérez vos virtualenv avec direnv, c'est ok, et ça peut rendre d'autres services (gros teasing).

Slide 79

Slide 79 text

Automatisez votre environnement de Dev ● Le démarrage doit demander un minimum de prérequis. ● Les prérequis doivent être simples à installer et documentés. ● Le projet doit contenir l'automatisation pour rapatrier ses dépendances. ● Faites en une convention. ○ git clone ○ direnv allow ○ make env

Slide 80

Slide 80 text

Aucun projet n'est un île.

Slide 81

Slide 81 text

Packaging Organisation de projet

Slide 82

Slide 82 text

Release privée # EMITTER $ git tag vX.Y.Z $ git push --tags # CONSUMER - requirements.yml - src: git@gitlab.company.com:mygroup/ansible-role.git scm: git version: "v0.1.2" Tirez vos dépendances directement depuis git.

Slide 83

Slide 83 text

Release publique $ ansible-galaxy collection build $ ansible-galaxy collection publish ns-name-version.tar.gz Upload d'archive pour les collections. Réglages du compte Galaxy pour les rôles, directement branché sur les tags. ansible-galaxy travaille sur le répertoire courant.

Slide 84

Slide 84 text

Automatiser le processus playbook: build/release_collection.yml play #1 (localhost): localhost TAGS: [] tasks: Ensure the ANSIBLE_GALAXY_TOKEN environment variable is set. Ensure $HOME/.ansible directory exists Write the galaxy token to $HOME/.ansible/galaxy_token Delete old clone Clone project at desired gitref Render galaxy.yml Build the collection Publish the collection

Slide 85

Slide 85 text

Testing

Slide 86

Slide 86 text

Molecule Testing

Slide 87

Slide 87 text

Molecule ● Framework de test pour les rôles et playbooks Ansible ● Permet de tester : ○ plusieurs instances en parallèle ○ plusieurs OS ○ différents scénarios ● Supporte 2 versions majeures d'Ansible (N et N-1)

Slide 88

Slide 88 text

Terminologie ● driver (provider) ○ gestionnaire du cycle de vie des hosts de test ● scenario ○ un test fonctionnel ● verifier ○ un outil pour valider le bon fonctionnement

Slide 89

Slide 89 text

Cycle complet ● lint ○ Analyse statique du code ● destroy ○ Destruction des éventuels environnements de tests encore existants ● dependency ○ Rapatriement des dépendances nécessaires listées dans le fichier meta.yml ● syntax ○ Validation de syntaxe avec Ansible ● create ○ Création de l'environnement de test du scénario ● prepare ○ Playbook de préparation de l'environnement de test

Slide 90

Slide 90 text

Cycle complet ● converge ○ Application du rôle testé, doit s'exécuter sans erreur ● idempotence ○ Seconde application du rôle testé, qui ne doit générer aucune task en état changed ● side_effect ○ Partie obscure du framework, cette phase doit permettre d'introduire des effets de bord à l'environnement (modification contextuelle au rôle, simulation de pannes) ● verify ○ Exécution du code de test ● destroy ○ Destruction des environnements de test

Slide 91

Slide 91 text

Dans la vraie vie ● molecule create ● code code code ● molecule verify ● repeat jusqu'à ce que … ● molecule destroy ● molecule test

Slide 92

Slide 92 text

Drivers ● Core ○ Delegated (aka DIY) ● Plugins ○ Docker ○ Podman ○ Azure ○ EC2 ○ GCE ○ Openstack ○ Vagrant ○ LXD ○ libvirt ○ …

Slide 93

Slide 93 text

Verifiers Testing

Slide 94

Slide 94 text

Ansible Verifier ● verifier par défaut ● un playbook verify.yml qui s'exécute sans erreur == OK Avantages ● Simplicité Inconvénients ● Complexe de tester sans impacter ● Temps d'exécution

Slide 95

Slide 95 text

TestInfra Verifier ● plugin pytest ● Script Python de validation Avantages ● Maturité ● Pur Python Inconvénients ● Changement de paradigme

Slide 96

Slide 96 text

Goss Verifier ● Plugin binaire Go ● Description de l'état attendu en YAML Avantages ● Pur déclaratif ● Exécution rapide Inconvénients ● YAML?

Slide 97

Slide 97 text

Goss : juste ce qu'il faut ● addr ● command ● dns ● file ● gossfile ● group ● http ● interface ● kernel-param ● mount ● matching ● package ● port ● process ● service ● user addr: tcp://ip-address-or-domain-name:80: reachable: true timeout: 500 # optional attributes local-address: 127.0.0.1

Slide 98

Slide 98 text

Goss : juste ce qu'il faut ● addr ● command ● dns ● file ● gossfile ● group ● http ● interface ● kernel-param ● mount ● matching ● package ● port ● process ● service ● user command: version: # required attributes exit-status: 0 # defaults to hash key exec: >- go version # optional attributes stdout: - go version go1.6 linux/amd64 stderr: [] timeout: 10000 # in milliseconds skip: false

Slide 99

Slide 99 text

Goss : juste ce qu'il faut ● addr ● command ● dns ● file ● gossfile ● group ● http ● interface ● kernel-param ● mount ● matching ● package ● port ● process ● service ● user file: /etc/passwd: exists: true mode: "0644" size: 2118 owner: root group: root filetype: file contains: [] md5: ... sha256: ... sha512: ... /etc/alternatives/mta: exists: true filetype: symlink linked-to: /usr/sbin/sendmail.sendmail skip: false

Slide 100

Slide 100 text

Goss : juste ce qu'il faut ● addr ● command ● dns ● file ● gossfile ● group ● http ● interface ● kernel-param ● mount ● matching ● package ● port ● process ● service ● user http: https://www.google.com: # required attributes status: 200 # optional attributes method: PUT # http method allow-insecure: false # Setting this to true will NOT follow redirects no-follow-redirects: false timeout: 1000 request-headers: # Set request header values - "Content-Type: text/html" # Check http response headers for these patterns headers: [] request-body: '{"key": "value"}' # request body body: [] # Check http response content for these patterns username: "" # username for basic auth password: "" # password for basic auth proxy: "" skip: false

Slide 101

Slide 101 text

Goss : juste ce qu'il faut ● addr ● command ● dns ● file ● gossfile ● group ● http ● interface ● kernel-param ● mount ● matching ● package ● port ● process ● service ● user package: httpd: # required attributes installed: true # optional attributes versions: - 2.2.15 skip: false

Slide 102

Slide 102 text

Goss : juste ce qu'il faut ● addr ● command ● dns ● file ● gossfile ● group ● http ● interface ● kernel-param ● mount ● matching ● package ● port ● process ● service ● user service: sshd: # required attributes enabled: true running: true skip: false # NOTE: status checked from systemd/upstart/init.

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

Stratégie Testing

Slide 105

Slide 105 text

Pour le Dev Cas ● Tests locaux ● Validation des développements ● Exécution manuelles plusieurs fois par jour Conseils ● Driver Docker ● Verifier Goss ● Architecture minimale ● Objectif de performance

Slide 106

Slide 106 text

Pour tous les jours Cas ● Tests de pipeline ● Validation pré-release ● Exécution quotidienne Conseils ● Driver Delegated Terraform ● Verifier Goss ● Architecture proche de la cible de déploiement ● Objectif de pertinence

Slide 107

Slide 107 text

CI/CD & IaC

Slide 108

Slide 108 text

Utilité d'Ansible dans un chaîne de CI/CD ● Beaucoup plus en CD qu'en CI ● Langage de scripting de premier plan ● Orchestrer les déploiements complexes ● Combler les manques de certains outils Infra-as-Code

Slide 109

Slide 109 text

Infra-as-Code CI/CD

Slide 110

Slide 110 text

Infrastructure as Code axée Ansible ● Ansible doit être le point d'entrée d'exécution de vos procédure ● Les variables Ansible sont le référentiel de travail ● Ansible est chargé des pré et post actions ● Tous les autres outils sont nourris et pilotés par Ansible ● N'utilisez PAS les modules Infra-as-Code d'Ansible pour la beauté de l'exercice ● Utilisez le meilleur outil pour l'usage considéré

Slide 111

Slide 111 text

Infrastructure as Code axée Ansible playbook pre_tasks tasks IaC avec des variables Ansible post_tasks ● Activation de page de maintenance ● Drain de flux réseau ● Rétablissement des flux réseau ● Désactivation de page de maintenance

Slide 112

Slide 112 text

Infrastructure as Code renforcée par Ansible terraform apply null_resource ● local-exec construction d'inventaire ● local-exec construction de fichier de variables ● local-exec ansible-playbook

Slide 113

Slide 113 text

Immutable Infrastructure ● Packer est un outil de Hashicorp qui permet de construire des images système de machine virtuelles, physique, Docker. ● Les Builders gèrent le cycle de vie du host et la prise d'instantané ● Les provisionners… provisionnent ● 2 provisionners Ansible sont disponibles : ○ ansible : processus ansible lancé à côté de Packer ○ ansible-local : processus ansible lancé sur la machine distante

Slide 114

Slide 114 text

Une usine d'AMI full-AWS

Slide 115

Slide 115 text

CICD Cas ● Déploiement et gestion de configuration continus ● Validation pré-release et tests ● Gestion multi environnements ● Exécution automatique Conseils ● Avoir son image Docker avec Ansible dedans ● Définir votre propre GitFlow ● Cadrez Packer finement (VPC, cleanup, etc)

Slide 116

Slide 116 text

Gitlab CI/CD

Slide 117

Slide 117 text

Builder le buildeur ansible-worker https://docs.gitlab.com/ee/ci/docker/using_kaniko.html docker push docker build

Slide 118

Slide 118 text

Alpine FROM alpine:latest MAINTAINER RUN apk --no-cache update && apk --no-cache upgrade RUN apk --no-cache add \ python3 py3-pip py3-setuptools py3-wheel RUN apk --no-cache add --virtual \ ansible-build-dependencies python3-dev \ libffi-dev openssl-dev gcc musl-dev && \ pip install --no-cache-dir -U \ pip setuptools wheel && \ pip install --no-cache-dir ansible-core && \ apk del ansible-build-dependencies ENV ANSIBLE_HOST_KEY_CHECKING False ENTRYPOINT ["/bin/sh"] Alpine Linux a tout ce qu'il faut pour une bonne image de worker Ansible.

Slide 119

Slide 119 text

Généralités ● Préparez vos runners ! ● Organisez votre bibliothèque de rôles ● Organisez votre inventaire commun (si statique) ● Organisez vos secrets (clé SSH, variable d’env, etc.) ● GitlabFlow/GitFlow

Slide 120

Slide 120 text

gitlab-ci.yml stages: - build - release - deploy # Template build .build: &build image: docker:stable stage: build services: - docker:dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -t "$CI_REGISTRY_IMAGE:latest" . - docker push "$CI_REGISTRY_IMAGE:latest" - echo Successfully push to registry ! only: - branches La description de la pipeline Stages : Les étapes de la pipeline. Le job de build pour construire l’image Docker de l’application.

Slide 121

Slide 121 text

gitlab-ci.yml .deploy: &deploy image: "$CI_REGISTRY_IMAGE:latest" stage: deploy variables: FLASK_APP: hello FLASK_ENV: development script: - flask run & - ansible-playbook playbooks/ci-quickstart.yml - echo "Successfully deployed !" Le job de déploiement

Slide 122

Slide 122 text

gitlab-ci.yml # STAGES build: <<: *build deploy: <<: *deploy only: - tags Les déclenchements

Slide 123

Slide 123 text

Extension

Slide 124

Slide 124 text

La minute nécessaire Extension

Slide 125

Slide 125 text

● Votre script Python préféré, qui vous facilite la vie au quotidien ● Une enveloppe de moins de 25 lignes de code ● L'effort d'adopter une méthode de développement documentée Les termes du troc : Vous apportez

Slide 126

Slide 126 text

● Un moteur de parallélisation ● Un moteur de templating ● La possibilité d'orchestrer l'exécution de votre script à travers tout le SI ● Un cadre de travail pérenne Les termes du troc : Vous obtenez

Slide 127

Slide 127 text

Ansible est une grosse multiprise à plugin ● Action : Enveloppe d'exécution d'un module ● Cache : Collecter des variables ● Callback : Réagir à des évènements ● Connection : Initier une connexion à une cible ● Filter : Traiter de données en mode pipe ● Inventory : Renseigner l'inventaire ● Lookup : Collecter des la données sur une source autre que la cible ● Test : Valider format ou valeur de données ● Vars : Injecter des variables dans le registre runtime de Ansible https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html

Slide 128

Slide 128 text

● Intégration avec un SI existant et complexe ● Dialogue et interactions entre Ansible et moult API ○ CMDB ○ Supervision ○ Réseau ○ Stockage ○ ITSM Développement de plugin dans la vraie vie

Slide 129

Slide 129 text

● être codé en Python ● lever des erreurs "proprement" ● renvoyer des strings unicode ● se conformer aux standards Ansible de configuration et de documentation Un plugin DOIT

Slide 130

Slide 130 text

Module & Filter plugins Extension

Slide 131

Slide 131 text

# # pour que Ansible retrouve vos modules de collection # export ANSIBLE_LIBRARY="${PWD}/plugins/modules:${ANSIBLE_LIBRARY}" # # Pour que Ansible retrouve vos filtres de collection # export ANSIBLE_FILTER_PLUGINS="${PWD}/plugins/filter_plugins:${ANSIBLE_FILTER_PLUGINS}" # Ansible Config # .envrc

Slide 132

Slide 132 text

No content

Slide 133

Slide 133 text

SI Ansible-centré

Slide 134

Slide 134 text

Boîte à outil

Slide 135

Slide 135 text

AWX SI Ansible-centré

Slide 136

Slide 136 text

● Moteur de lancement de playbook ● WebUI ● Gestion des utilisateurs et permissions ● Console d'administration AWX

Slide 137

Slide 137 text

AWX

Slide 138

Slide 138 text

Panorama DMZ Private Zone

Slide 139

Slide 139 text

Admin DMZ Private Zone Sas d'administration

Slide 140

Slide 140 text

Admin DMZ Private Zone Ops Teams L1 L2 L3

Slide 141

Slide 141 text

Admin DMZ Private Zone Contribution L1 L2 L3

Slide 142

Slide 142 text

Admin DMZ Private Zone Opérations courantes L1 L2 L3

Slide 143

Slide 143 text

Admin DMZ Private Zone Escalade L1 L2 L3

Slide 144

Slide 144 text

Admin DMZ Private Zone Escalade L1 L2 L3

Slide 145

Slide 145 text

ARA SI Ansible-centré

Slide 146

Slide 146 text

ARA (ARA Records Ansible) ● Besoin de traçabilité de toute action sur le périmètre ● Historique des plays ● Drilldown à la task ● WebUI & CLI

Slide 147

Slide 147 text

ARA enregistre vos playbook

Slide 148

Slide 148 text

Admin DMZ Private Zone Intervention L1 L2 L3

Slide 149

Slide 149 text

Gestion des secrets SI Ansible-centré

Slide 150

Slide 150 text

L'éternel dilemme ● Ranger au coffre ! ● Oui mais qui a les clés du coffre ? ● Donner les droits sur le coffre-fort est … problématique ● Réduire le périmètre de diffusion ● Faire des rotations régulières

Slide 151

Slide 151 text

ansible-vault ● Permet de chiffrer des fichiers de variables ● Pour ranger du multi-line dans une variable Ansible : ○ stored_multi: "{{ multi | base64encode }}" ○ {{ stored_multi | base64decode }} ● Le password peut être injecté : ○ en prompt ○ via une indirection avec un fichier dans lequel le password est en clair

Slide 152

Slide 152 text

ansible-vault ● Réduction du problème à un secret unique ● Au bout de la chaîne, gérer les secrets retombe sur des cérémonies et des humains ● Tant que le temps de rotation est plus rapide que le temps de cassage du chiffrement, on est bien. ● ansible-vault rekey permet de déchiffrer et rechiffrer en automatique sans écrire en clair sur le disque

Slide 153

Slide 153 text

Admin DMZ Private Zone Secrets L1 L2 L3

Slide 154

Slide 154 text

Jamais d'accès à la clé maîtresse Admin Rotation automatique via AWX Cron L1 L2 L3 Accès possible uniquement durant une intervention.

Slide 155

Slide 155 text

Problème repoussé ● Notre zone sensible/de fragilité est réduite au seul serveur AWX… ● Possibilité de pousser la clé dans un cluster Vault pour backup. ○ Spoiler : il faudra gérer les secrets pour la gestion du cluster ● Pensez à conserver une procédure "bris de glace" avec accès à un secret.

Slide 156

Slide 156 text

Anatomie d'un projet

Slide 157

Slide 157 text

The HashiStack Project Anatomie d'un projet

Slide 158

Slide 158 text

Le but

Slide 159

Slide 159 text

Le but Worker Ingress gateway Ingress gateway config entry Connect Service Connect Service mTLS mTLS mTLS exécute TCP HTTP déploie configure exécute exécute

Slide 160

Slide 160 text

Chorégraphie core vault consul nomad

Slide 161

Slide 161 text

Chorégraphie ● Let's Encrypt ● DNS Challenge ● Wildcard ● Distribution Infra OS DNS ● VM ● Réseau ● Security groups ● Update ● Prérequis ● DNS resolver local ● Délégation de sous-domaine ● Masters ● Minions core Certificats

Slide 162

Slide 162 text

Chorégraphie Install Policies ● Packages officiels ● Intégration des certificats ● Récupération du root token ● Moindre privilège ● Consul token ● Nomad token Vault Auto Unseal

Slide 163

Slide 163 text

Chorégraphie Install Policies ● Package officiels ● Intégration des certificats ● Service Mesh ● Vault en CA ● Nomad token Configure Consul

Slide 164

Slide 164 text

Chorégraphie Install Policies ● Package officiels ● Intégration des certificats ● Intégration du token Consul ● À venir Configure Nomad

Slide 165

Slide 165 text

No content

Slide 166

Slide 166 text

Intégration Terraform Anatomie d'un projet

Slide 167

Slide 167 text

Vault-Consul-Nomad Anatomie d'un projet

Slide 168

Slide 168 text

Concepts Le mot de la fin

Slide 169

Slide 169 text

● Culture ● Automation ● Lean ● Measurement ● Sharing Le centre de gravité DevSecOps

Slide 170

Slide 170 text

Le centre de gravité DevSecOps ● Ansible peut être le point de rendez-vous des équipes Dev, Sec et Ops. ● Les Ops savent quoi faire avec les systèmes et comment le faire bien. ● Les Dev savent comment optimiser du code en restant iso-fonctionnel pour exploiter un moteur. ● Les Sec surveillent, analysent, et viennent ajouter leur expertise au mix.

Slide 171

Slide 171 text

#DevoxxFR Merci à tous ! Rejoignez le mouvement !