Add slide 3: statement 'You have a server. It works.'
Some checks failed
Deploy presentation / deploy (push) Has been cancelled

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-13 22:48:15 +02:00
parent 23cf5ac65d
commit 641f7a917e

View File

@@ -25,91 +25,30 @@
} }
.reveal h1, .reveal h2 { .reveal h1, .reveal h2 {
text-align: center; text-align: left;
} }
.reveal h1 { font-size: 1.8em; } .reveal h1 { font-size: 1.8em; }
.reveal h2 { font-size: 1.3em; } .reveal h2 { font-size: 1.4em; line-height: 1.2; }
.reveal p, .reveal li { font-size: 0.78em; } .reveal p, .reveal li { font-size: 0.85em; }
.reveal code { font-size: 0.7em; } .reveal code { font-size: 0.7em; }
.reveal pre { width: 100%; } .reveal pre { width: 100%; }
.title-slide { text-align: center !important; } .title-slide { text-align: center !important; }
.title-slide h1 { font-size: 2em; margin-bottom: 0.2em; } .title-slide h1 { text-align: center; font-size: 2em; margin-bottom: 0.2em; }
.title-slide .subtitle { font-size: 1em; color: #aaa; } .title-slide .subtitle { font-size: 1em; color: #aaa; }
.title-slide .meta { font-size: 0.7em; color: #888; margin-top: 1em; } .title-slide .meta { font-size: 0.7em; color: #888; margin-top: 1em; }
.tag {
display: inline-block;
padding: 2px 10px;
border-radius: 4px;
font-size: 0.55em;
font-weight: bold;
vertical-align: middle;
margin-left: 8px;
}
.tag-puppet { background: var(--puppet-color); color: #000; }
.tag-ansible { background: var(--ansible-color); color: #fff; }
.tag-tf { background: var(--terraform-color);color: #fff; }
.card-row {
display: flex;
gap: 1em;
margin-top: 0.5em;
}
.card {
flex: 1;
border-radius: 8px;
padding: 0.7em 1em;
font-size: 0.7em;
}
.card-puppet { border: 2px solid var(--puppet-color); background: rgba(255,174,26,0.08); }
.card-ansible { border: 2px solid var(--ansible-color); background: rgba(238,0,0,0.08); }
.card-tf { border: 2px solid var(--terraform-color);background: rgba(123,66,188,0.08); }
.card h3 { margin: 0 0 0.4em; font-size: 1.1em; }
.card ul { margin: 0; padding-left: 1.2em; }
.comparison-table {
width: 100%;
border-collapse: collapse;
font-size: 0.62em;
margin-top: 0.5em;
}
.comparison-table th, .comparison-table td {
border: 1px solid rgba(255,255,255,0.2);
padding: 0.4em 0.6em;
text-align: center;
}
.comparison-table th { background: rgba(255,255,255,0.1); }
.comparison-table td:first-child { text-align: left; font-weight: bold; }
.puppet-col { color: var(--puppet-color); } .puppet-col { color: var(--puppet-color); }
.ansible-col { color: var(--ansible-color); } .ansible-col { color: var(--ansible-color); }
.tf-col { color: var(--terraform-color); } .tf-col { color: var(--terraform-color); }
.highlight-box { .filename {
border-left: 4px solid #4CAF50; font-family: monospace;
background: rgba(76,175,80,0.1); font-size: 0.65em;
padding: 0.5em 1em; color: #888;
margin: 0.5em 0; margin-bottom: 0.2em;
border-radius: 0 6px 6px 0;
font-size: 0.75em;
} }
.agenda-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.5em;
margin-top: 0.5em;
}
.agenda-item {
background: rgba(255,255,255,0.07);
border-radius: 6px;
padding: 0.5em 0.8em;
font-size: 0.75em;
}
.agenda-item .num { font-size: 1.3em; font-weight: bold; color: #888; }
.emoji { font-style: normal; }
</style> </style>
</head> </head>
<body> <body>
@@ -120,298 +59,22 @@
<section class="title-slide"> <section class="title-slide">
<h1>⚙️ Configuration as Code</h1> <h1>⚙️ Configuration as Code</h1>
<p class="subtitle">Puppet · Ansible · Terraform<br>— What's the difference and when to use what? —</p> <p class="subtitle">Puppet · Ansible · Terraform<br>— What's the difference and when to use what? —</p>
<p class="meta">Finistère Dev Meetup · 2026</p> <p class="meta">FinistDevs · 2026</p>
</section> </section>
<!-- ─── SLIDE 2 : Agenda ────────────────────────────────────────── --> <!-- ─── SLIDE 2 : Speaker intro ────────────────────────────────── -->
<section> <section>
<h2>📋 Agenda</h2> <h2>Arnaud Prémel-Cabic</h2>
<div class="agenda-grid"> <p>Tech Lead @ OVHCloud</p>
<div class="agenda-item"><span class="num">01</span><br>What is Configuration as Code?</div> <p style="color:#888; font-size:0.75em;">arnaud.premel-cabic@ovhcloud.com</p>
<div class="agenda-item"><span class="num">02</span><br>The IaC landscape</div>
<div class="agenda-item"><span class="num">03</span><br><span class="puppet-col">Puppet</span> — Declare your state</div>
<div class="agenda-item"><span class="num">04</span><br><span class="ansible-col">Ansible</span> — Automate everything</div>
<div class="agenda-item"><span class="num">05</span><br><span class="tf-col">Terraform</span> — Provision infrastructure</div>
<div class="agenda-item"><span class="num">06</span><br>Comparison & when to use what</div>
</div>
</section> </section>
<!-- ─── SLIDE 3 : What is CaC ──────────────────────────────────── --> <!-- ─── SLIDE 3 ──────────────────────────────────────────────────── -->
<section> <section>
<h2>🤔 What is Configuration as Code?</h2> <h2>You have a server. It works.</h2>
<div class="highlight-box"> <p><em>Great.</em></p>
Managing infrastructure and system configuration <strong>through machine-readable files</strong> stored in version control — just like application code.
</div>
<ul>
<li class="fragment"><strong>Reproducible</strong> — same result every time</li>
<li class="fragment"><strong>Versionable</strong> — Git history, pull requests, rollbacks</li>
<li class="fragment"><strong>Auditable</strong> — who changed what, and when</li>
<li class="fragment"><strong>Scalable</strong> — apply to 1 or 10 000 servers identically</li>
<li class="fragment"><strong>Collaborative</strong> — code review, CI/CD pipelines</li>
</ul>
</section> </section>
<!-- ─── SLIDE 4 : IaC landscape ───────────────────────────────── -->
<section>
<h2>🌍 The IaC Landscape</h2>
<p>Three main problem spaces:</p>
<div class="card-row">
<div class="card card-puppet">
<h3>🐾 Configuration<br>Management</h3>
<ul>
<li>Install / configure software</li>
<li>Enforce desired state on servers</li>
<li><strong>Puppet, Chef, Salt</strong></li>
</ul>
</div>
<div class="card card-ansible">
<h3>⚡ Orchestration &amp;<br>Automation</h3>
<ul>
<li>Run tasks across many hosts</li>
<li>Deploy apps, pipelines</li>
<li><strong>Ansible, Fabric</strong></li>
</ul>
</div>
<div class="card card-tf">
<h3>🏗️ Infrastructure<br>Provisioning</h3>
<ul>
<li>Create VMs, networks, DNS…</li>
<li>Cloud-agnostic</li>
<li><strong>Terraform, Pulumi, OpenTofu</strong></li>
</ul>
</div>
</div>
</section>
<!-- ─── SLIDE 5 : Puppet overview ─────────────────────────────── -->
<section>
<h2>🐾 Puppet <span class="tag tag-puppet">Configuration Management</span></h2>
<ul>
<li><strong>Born:</strong> 2005 — one of the oldest IaC tools</li>
<li><strong>Language:</strong> Puppet DSL (Ruby-based) or YAML (Hiera)</li>
<li><strong>Model:</strong> <em>Pull</em> — agents poll a central Puppet Server every 30 min</li>
<li><strong>Approach:</strong> <em>Declarative</em> — you describe the desired state</li>
<li><strong>Agent required:</strong> Yes (puppet-agent on each node)</li>
</ul>
<div class="highlight-box" style="margin-top:0.8em;">
💡 Great for large fleets where <strong>continuous compliance</strong> and drift detection matter.
</div>
</section>
<!-- ─── SLIDE 6 : Puppet code ─────────────────────────────────── -->
<section>
<h2>🐾 Puppet — Example</h2>
<pre><code class="language-puppet" data-trim>
# manifests/webserver.pp
class webserver {
package { 'nginx':
ensure => installed,
}
file { '/etc/nginx/nginx.conf':
ensure => file,
content => template('webserver/nginx.conf.erb'),
notify => Service['nginx'],
}
service { 'nginx':
ensure => running,
enable => true,
}
}
</code></pre>
<p>🔁 Run again → <strong>idempotent</strong>: only changes what diverged from the desired state</p>
</section>
<!-- ─── SLIDE 7 : Ansible overview ───────────────────────────── -->
<section>
<h2>⚡ Ansible <span class="tag tag-ansible">Automation &amp; Orchestration</span></h2>
<ul>
<li><strong>Born:</strong> 2012, acquired by Red Hat in 2015</li>
<li><strong>Language:</strong> YAML (Playbooks)</li>
<li><strong>Model:</strong> <em>Push</em> — the control node connects via SSH</li>
<li><strong>Approach:</strong> <em>Procedural</em> (tasks run in order) with idempotent modules</li>
<li><strong>Agent required:</strong> <strong>No</strong> — agentless, just Python + SSH</li>
</ul>
<div class="highlight-box" style="margin-top:0.8em;">
💡 Great for <strong>ad-hoc tasks</strong>, app deployments, and quick automation without setup overhead.
</div>
</section>
<!-- ─── SLIDE 8 : Ansible code ───────────────────────────────── -->
<section>
<h2>⚡ Ansible — Example</h2>
<pre><code class="language-yaml" data-trim>
# playbook/webserver.yml
- name: Configure web server
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.package:
name: nginx
state: present
- name: Copy nginx config
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
</code></pre>
</section>
<!-- ─── SLIDE 9 : Terraform overview ─────────────────────────── -->
<section>
<h2>🏗️ Terraform <span class="tag tag-tf">Infrastructure Provisioning</span></h2>
<ul>
<li><strong>Born:</strong> 2014 by HashiCorp (open-source fork: <em>OpenTofu</em>)</li>
<li><strong>Language:</strong> HCL (HashiCorp Configuration Language)</li>
<li><strong>Model:</strong> <em>Plan → Apply</em> — preview changes before applying</li>
<li><strong>Approach:</strong> <em>Declarative</em> — describe your infrastructure graph</li>
<li><strong>Agent required:</strong> No — uses provider APIs (AWS, GCP, Azure, etc.)</li>
</ul>
<div class="highlight-box" style="margin-top:0.8em;">
💡 Great for <strong>creating and managing cloud resources</strong> — VMs, networks, DNS, databases…
</div>
</section>
<!-- ─── SLIDE 10 : Terraform code ────────────────────────────── -->
<section>
<h2>🏗️ Terraform — Example</h2>
<pre><code class="language-hcl" data-trim>
# main.tf
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" { region = "eu-west-3" }
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = { Name = "meetup-webserver" }
}
output "public_ip" {
value = aws_instance.web.public_ip
}
</code></pre>
<p>🗺️ <code>terraform plan</code> shows a diff · <code>terraform apply</code> creates resources · <code>terraform destroy</code> removes them</p>
</section>
<!-- ─── SLIDE 11 : Comparison table ──────────────────────────── -->
<section>
<h2>📊 Comparison at a Glance</h2>
<table class="comparison-table">
<thead>
<tr>
<th></th>
<th class="puppet-col">🐾 Puppet</th>
<th class="ansible-col">⚡ Ansible</th>
<th class="tf-col">🏗️ Terraform</th>
</tr>
</thead>
<tbody>
<tr><td>Primary focus</td><td>Config management</td><td>Automation / Orchestration</td><td>Infrastructure provisioning</td></tr>
<tr><td>Language</td><td>Puppet DSL</td><td>YAML</td><td>HCL</td></tr>
<tr><td>Approach</td><td>Declarative</td><td>Procedural + idempotent</td><td>Declarative</td></tr>
<tr><td>Push / Pull</td><td>Pull</td><td>Push</td><td>Push (via API)</td></tr>
<tr><td>Agent needed</td><td>Yes</td><td>No</td><td>No</td></tr>
<tr><td>State file</td><td>Catalog (server)</td><td>None (stateless)</td><td>Yes (.tfstate)</td></tr>
<tr><td>Cloud resources</td><td>Limited</td><td>Yes (modules)</td><td>Excellent</td></tr>
<tr><td>Learning curve</td><td>High</td><td>Low</td><td>Medium</td></tr>
</tbody>
</table>
</section>
<!-- ─── SLIDE 12 : When to use what ─────────────────────────── -->
<section>
<h2>🎯 When to Use What?</h2>
<div class="card-row">
<div class="card card-puppet">
<h3>🐾 Use Puppet when…</h3>
<ul>
<li>Large fleet (100s1000s of servers)</li>
<li>Continuous compliance / drift detection</li>
<li>Enterprise, strict governance</li>
<li>Long-running servers (pets)</li>
</ul>
</div>
<div class="card card-ansible">
<h3>⚡ Use Ansible when…</h3>
<ul>
<li>Agentless is a must</li>
<li>Quick automation or one-off tasks</li>
<li>App deployment & pipelines</li>
<li>Already using Red Hat / AWX</li>
</ul>
</div>
<div class="card card-tf">
<h3>🏗️ Use Terraform when…</h3>
<ul>
<li>Creating cloud infrastructure</li>
<li>Multi-cloud or hybrid environments</li>
<li>Preview changes before applying</li>
<li>Immutable infra (cattle, not pets)</li>
</ul>
</div>
</div>
</section>
<!-- ─── SLIDE 13 : They work together ───────────────────────── -->
<section>
<h2>🤝 They Work Together!</h2>
<div class="highlight-box">
These tools are <strong>complementary</strong>, not mutually exclusive.
</div>
<p>A common real-world stack:</p>
<ol>
<li class="fragment"><strong class="tf-col">Terraform</strong> provisions the VM on AWS/Azure/GCP</li>
<li class="fragment"><strong class="ansible-col">Ansible</strong> bootstraps the OS, installs base packages, deploys the app</li>
<li class="fragment"><strong class="puppet-col">Puppet</strong> continuously enforces compliance and manages config drift</li>
</ol>
<p class="fragment" style="margin-top:0.8em; font-style:italic; color:#aaa;">
→ Right tool for the right layer of the stack
</p>
</section>
<!-- ─── SLIDE 14 : Key Takeaways ────────────────────────────── -->
<section>
<h2>💡 Key Takeaways</h2>
<ul>
<li class="fragment">Configuration as Code → <strong>reproducible, auditable, scalable</strong> infrastructure</li>
<li class="fragment"><strong class="puppet-col">Puppet</strong> — continuous compliance on large server fleets (pull, agent)</li>
<li class="fragment"><strong class="ansible-col">Ansible</strong> — agentless automation & orchestration (push, YAML)</li>
<li class="fragment"><strong class="tf-col">Terraform</strong> — cloud infrastructure provisioning (plan/apply, HCL)</li>
<li class="fragment">They <strong>complement each other</strong> — choose based on the layer of your stack</li>
</ul>
</section>
<!-- ─── SLIDE 15 : Q&A ──────────────────────────────────────── -->
<section class="title-slide">
<h1>🙋 Questions?</h1>
<p class="subtitle">Thank you!</p>
<p class="meta" style="margin-top:2em;">
Slides made with <a href="https://revealjs.com" target="_blank">Reveal.js</a><br>
Finistère Dev Meetup · 2026
</p>
</section>
</div> </div>
</div> </div>