470 lines
15 KiB
HTML
470 lines
15 KiB
HTML
<!doctype html>
|
||
<html>
|
||
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||
|
||
<title>Meetup Ansible #2 – Grégory Colpart & Jérémy Lecour – 28 mars 2018</title>
|
||
|
||
<link rel="stylesheet" href="css/reveal.css">
|
||
<link rel="stylesheet" href="css/theme/evolix_blue.css">
|
||
|
||
<!-- Theme used for syntax highlighting of code -->
|
||
<link rel="stylesheet" href="lib/css/zenburn.css">
|
||
|
||
<!-- Printing and PDF exports -->
|
||
<script>
|
||
var link = document.createElement( 'link' );
|
||
link.rel = 'stylesheet';
|
||
link.type = 'text/css';
|
||
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
|
||
document.getElementsByTagName( 'head' )[0].appendChild( link );
|
||
</script>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="reveal">
|
||
<div class="slides">
|
||
<section>
|
||
<h1>Meetup Ansible #2</h1>
|
||
<p>
|
||
<small>28 mars 2019 – organisé par Evolix</small>
|
||
</p>
|
||
<ul>
|
||
<li>18h – accueil, discussions…</li>
|
||
<li>19h – présentation</li>
|
||
<li>20h – apéro</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section>
|
||
<pre style="max-width: 55%;"><code class="hljs nohighlight" data-noescape data-trim style="max-height: 600px;">
|
||
<b>$ who</b>
|
||
Jérémy Lecour <jlecour@evolix.fr>
|
||
Grégory Colpart <reg@evolix.fr>
|
||
|
||
<b>$ whois Evolix</b>
|
||
EVOLIX-AS : AS 197696
|
||
|
||
<b>$ man Evolix</b>
|
||
Open Source managed hosting provider
|
||
|
||
<b>$ uptime</b>
|
||
up 14 years, 20 users
|
||
|
||
<b>$ whereis Evolix</b>
|
||
/fr/Marseille, /fr/Aix, /fr/Paris, /ca/Montréal
|
||
|
||
<b>$ top</b>
|
||
Linux/BSD servers: 800, customers: 120
|
||
</code></pre>
|
||
|
||
<aside class="notes">
|
||
<b>GC</b>
|
||
<br>Bonjour à tous,
|
||
<br>Jérémy et moi-même faisons partie d'Evolix, entreprise créée en 2004,
|
||
<br>on propose des services d'hébergement et d'infogérance à base de Logiciels Libres.
|
||
<br>Nous avons des bureaux et une équipe en France et au Canada.
|
||
<br>Pour situer, nous infogérons 800 serveurs pour 120 infras client.
|
||
</aside>
|
||
</section>
|
||
|
||
<section>
|
||
<img width="400" src="img/Evolix-400x150px.png" class="plain">
|
||
|
||
<br>
|
||
|
||
<ul>
|
||
<li class="fragment">Infogérance / Hébergement dédié et Cloud / Conseil et Formations</li>
|
||
<li class="fragment">Linux, infra web, HA, virtualisation, conteneurs, Ansible</li>
|
||
<li class="fragment">Clients : agences web, SaaS, médias</li>
|
||
</ul>
|
||
|
||
<aside class="notes">
|
||
<b>GC</b>
|
||
<br>Notre 1er métier, l'infogérance = prendre soin des serveurs
|
||
<br>Infra d'hébergement sur 4 datacenters, opère notre réseau
|
||
<br>On fait du conseil et de la formation sur mesure.
|
||
<br>contrairement à nos concurrents, 22h00 pas une astreinte, une vraie équipe.
|
||
<br>Mots clés, technologies d'expertise.
|
||
<br>Nos clients. On a des supers clients, on a le luxe de les choisir, on aime les défis !
|
||
</aside>
|
||
|
||
</section>
|
||
|
||
<section>
|
||
<img width="300" src="img/logo-ansible.png" border="0" alt="Ansible" class="plain">
|
||
<h4 class="fragment">Automatisation de configuration d'infrastructure et déploiement</h4>
|
||
</section>
|
||
|
||
<section>
|
||
<!-- <img width="300" src="img/logo-ansible.png" border="0" alt="Ansible" class="plain"> -->
|
||
<h1 class="">Des nouvelles d'Ansible</h1>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>releases Ansible</h3>
|
||
<ul>
|
||
<li class="fragment">Ansible 2.5 : mars 2018</li>
|
||
<li class="fragment">Ansible 2.6 : juin 2018</li>
|
||
<li class="fragment">Ansible 2.7 : octobre 2018</li>
|
||
<li class="fragment">Ansible 2.8 : prévue pour le 2 mai 2018</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>depuis décembre</h3>
|
||
<ul>
|
||
<li class="fragment">v2.5.15</li>
|
||
<li class="fragment">v2.6.15</li>
|
||
<li class="fragment">v2.7.9</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section>
|
||
<img width="300" src="img/ansible-PR.png" border="0" alt="Ansible" class="plain">
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Ansible et Debian</h3>
|
||
<ul>
|
||
<li class="fragment">ansible 2.7 sera dans Debian 10</li>
|
||
<li class="fragment">...déjà disponible via backports Debian 9</li>
|
||
<li class="fragment">ansible-lint 4.1 sera dans Debian 10</li>
|
||
<li class="fragment">...déjà disponible via backports Debian 9</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>#AnsibleFest</h3>
|
||
<p>24-26 septembre 2019 à Atlanta</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>ansible.com/blog</h3>
|
||
<ul>
|
||
<li class="fragment">Ansible Tips and Tricks: Dealing with Unreliable Connections and Services</li>
|
||
<li class="fragment">Deep Dive on cli_command for Network Automation</li>
|
||
<li class="fragment">Ansible Community Update — February 2019</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>webinar</h3>
|
||
<p>Ansible Best Practices: Roles and Modules</h3>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Commentaires de commande</h3>
|
||
<pre><code class="hljs yaml" data-trim>
|
||
###
|
||
# 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
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Commentaires de commande (2)</h3>
|
||
<pre><code class="hljs yaml" data-trim>
|
||
###
|
||
# 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
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Handler conditionnel</h3>
|
||
<pre class="fragment"># roles/minifirewall/handlers/main.yml
|
||
<code class="hljs yaml" data-trim>
|
||
---
|
||
- 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
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Handler conditionnel (3)</h3>
|
||
<pre># roles/minifirewall/tasks/main.yml
|
||
<code class="hljs yaml" data-trim>
|
||
- set_fact:
|
||
minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed \
|
||
| ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
|
||
</code></pre>
|
||
<pre class="fragment"># roles/minifirewall/defaults/main.yml
|
||
<code class="hljs yaml" data-trim>
|
||
minifirewall_restart_if_needed: True
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Handler conditionnel (4)</h3>
|
||
<pre class=""># firewall.yml
|
||
<code class="hljs yaml" data-trim>
|
||
##
|
||
# 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
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Handler conditionnel (2)</h3>
|
||
<pre><code class="hljs yaml" data-trim>
|
||
---
|
||
- blockinfile:
|
||
dest: "{{ minifirewall_tail_file }}"
|
||
marker: "# {mark} PRIVATE LAN"
|
||
block: |
|
||
/sbin/iptables -A INPUT -i eth0 -j ACCEPT
|
||
notify: "{{ minifirewall_restart_handler_name }}"
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Vérification avant de se lancer</h3>
|
||
<pre># roles/upgrade-jessie-to-stretch/tasks/main.yml<code class="hljs yaml" data-trim>
|
||
---
|
||
- 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
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Découpage des gros rôles</h3>
|
||
<pre class="fragment"><code class="hljs yaml" data-trim style="max-height: 600px;">
|
||
- 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
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Capture de tâches et debug</h3>
|
||
<pre class="fragment"><code class="hljs yaml" data-trim>
|
||
- 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 != ""
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>with_first_found</h3>
|
||
<pre class="fragment"># roles/haproxy/tasks/main.yml<code class="hljs yaml" data-trim>
|
||
- 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"
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Une sorte d'annuaire local</h3>
|
||
<pre class="fragment"># vars/main.yml<code class="hljs yaml" data-trim>
|
||
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=="
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Une sorte d'annuaire local (2)</h3>
|
||
<pre class="fragment"># roles/users/tasks/main.yml<code class="hljs yaml" data-trim>
|
||
- 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([]) }}"
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Gestion fine des variables</h3>
|
||
<pre class="fragment"># roles/users/tasks/main.yml<code class="hljs yaml" data-trim>
|
||
- 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) }}"
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Gestion fine des variables (2)</h3>
|
||
<pre class=""># group_vars/all.yml<code class="hljs yaml" data-trim>
|
||
users_present_for_all:
|
||
- foo
|
||
users_absent_for_all:
|
||
- qux
|
||
</code></pre>
|
||
<pre class=""># group_vars/database.yml<code class="hljs yaml" data-trim>
|
||
users_present_for_group: []
|
||
</code></pre>
|
||
<pre class=""># host_vars/sql00.yml<code class="hljs yaml" data-trim>
|
||
users_present_for_host:
|
||
- bar
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Syntaxe complexe dans un template</h3>
|
||
<pre class="fragment"># /etc/filebeat/filebeat.yml<code class="hljs yaml" data-trim>
|
||
# Elasticsearch output
|
||
output.elasticsearch:
|
||
hosts: ['192.168.10.42:9200', '192.168.10.43:9200']
|
||
</code></pre>
|
||
<pre class="fragment"># host_vars/sql00.yml<code class="hljs yaml" data-trim>
|
||
---
|
||
filebeat__elasticsearch_hosts:
|
||
- "192.168.10.42:9200"
|
||
- "192.168.10.43:9200"
|
||
</code></pre>
|
||
<pre class="fragment"># roles/filebeat/templates/filebeat.yml.j2<code class="hljs yaml" data-trim>
|
||
# Elasticsearch output
|
||
output.elasticsearch:
|
||
hosts: {{ filebeat__elasticsearch_hosts | to_yaml }}
|
||
</code></pre>
|
||
</section>
|
||
|
||
<section>
|
||
<h3>Adoptez des conventions</h3>
|
||
https://gitea.evolix.org/evolix/ansible-public/
|
||
<br>CONVENTIONS.md
|
||
</section>
|
||
|
||
<section>
|
||
<h1>Merci</h1>
|
||
<h2>à vos questions</h2>
|
||
</section>
|
||
|
||
<section>
|
||
<h1>Et la suite ?</h1>
|
||
<ul>
|
||
<li>dites-nous ce que vous espérez</li>
|
||
<li>venez parler de vos cas d'usages</li>
|
||
<li><a href="https://www.meetup.com/fr-FR/Ansible-Marseille/">www.meetup.com/Ansible-Marseille/</a></li>
|
||
<li><a href="https://twitter.com/ansible_mrs">@ansible_mrs</a></li>
|
||
</ul>
|
||
</section>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<script src="lib/js/head.min.js"></script>
|
||
<script src="js/reveal.js"></script>
|
||
|
||
<script>
|
||
// More info about config & dependencies:
|
||
// - https://github.com/hakimel/reveal.js#configuration
|
||
// - https://github.com/hakimel/reveal.js#dependencies
|
||
Reveal.initialize({
|
||
controls: false,
|
||
progress: true,
|
||
history: true,
|
||
center: true,
|
||
|
||
transition: 'none', // none/fade/slide/convex/concave/zoom
|
||
// specified using percentage units.
|
||
width: 1280,
|
||
height: 720,
|
||
dependencies: [
|
||
{ src: 'plugin/markdown/marked.js' },
|
||
{ src: 'plugin/markdown/markdown.js' },
|
||
{ src: 'plugin/notes/notes.js', async: true },
|
||
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
|
||
]
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|