content: add review step to Terraform flow, restructure slide text

- Slide 13: add 'review' step between plan and apply in SVG + text
- Convert wall-of-text paragraphs to structured <ul> lists on:
  slides 14, 15, 17, 20, 22, 23, 26, 28, 29, 30
- Separate key points from emphasis/taglines for better readability

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-14 01:42:20 +02:00
parent f33b3914cd
commit e2acdc5880

View File

@@ -526,54 +526,73 @@
<!-- ─── SLIDE 13 : Terraform concepts ───────────────────────────── -->
<section class="s-tf">
<h2>HCL: HashiCorp Configuration Language.</h2>
<p>Declarative, human-readable — and pure JSON works too.<br>
<code>terraform plan</code> previews &nbsp;·&nbsp; <code>terraform apply</code> creates &nbsp;·&nbsp; <code>terraform destroy</code> removes.</p>
<svg width="800" height="180" style="margin-top:0.5em;" viewBox="0 0 800 180" xmlns="http://www.w3.org/2000/svg">
<h2>HCL: HashiCorp Configuration Language</h2>
<p>Declarative, human-readable — pure JSON works too.</p>
<ul>
<li><code>terraform plan</code> — preview what will change</li>
<li><strong>Review</strong> — validate the plan before proceeding</li>
<li><code>terraform apply</code> — create or update resources</li>
<li><code>terraform destroy</code> — tear everything down</li>
</ul>
<svg width="900" height="150" style="margin-top:0.5em;" viewBox="0 0 900 150" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="wf-arrow" viewBox="0 0 10 7" refX="10" refY="3.5" markerWidth="10" markerHeight="7" orient="auto-start-auto">
<path d="M0,0 L10,3.5 L0,7z" fill="#7B42BC"/>
</marker>
</defs>
<rect x="10" y="30" width="150" height="120" rx="14" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(60,50)">
<!-- Box 1: HCL Code -->
<rect x="10" y="15" width="140" height="100" rx="12" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(50,28)">
<path d="M0,4 L0,30 Q0,33 3,33 L27,33 Q30,33 30,30 L30,10 L20,0 L3,0 Q0,0 0,4z" fill="none" stroke="#7B42BC" stroke-width="1.6"/>
<path d="M20,0 L20,7 Q20,10 23,10 L30,10" fill="none" stroke="#7B42BC" stroke-width="1.4"/>
<line x1="7" y1="15" x2="23" y2="15" stroke="#7B42BC" stroke-width="1.2"/>
<line x1="7" y1="20" x2="20" y2="20" stroke="#7B42BC" stroke-width="1.2"/>
<line x1="7" y1="25" x2="17" y2="25" stroke="#7B42BC" stroke-width="1.2"/>
</g>
<text x="85" y="115" text-anchor="middle" font-family="system-ui,sans-serif" font-size="16" font-weight="600" fill="#00185e">HCL Code</text>
<line x1="168" y1="90" x2="210" y2="90" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<rect x="218" y="30" width="150" height="120" rx="14" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(268,48)">
<text x="80" y="92" text-anchor="middle" font-family="system-ui,sans-serif" font-size="14" font-weight="600" fill="#00185e">HCL Code</text>
<!-- Arrow 1→2 -->
<line x1="158" y1="65" x2="195" y2="65" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<!-- Box 2: plan -->
<rect x="203" y="15" width="140" height="100" rx="12" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(248,30)">
<ellipse cx="15" cy="15" rx="18" ry="12" fill="none" stroke="#7B42BC" stroke-width="1.6"/>
<circle cx="15" cy="15" r="6" fill="none" stroke="#7B42BC" stroke-width="1.6"/>
<circle cx="15" cy="15" r="2.5" fill="#7B42BC"/>
</g>
<text x="293" y="110" text-anchor="middle" font-family="monospace" font-size="15" font-weight="600" fill="#00185e">plan</text>
<line x1="376" y1="90" x2="418" y2="90" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<rect x="426" y="30" width="150" height="120" rx="14" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(476,48)">
<text x="273" y="92" text-anchor="middle" font-family="monospace" font-size="14" font-weight="600" fill="#00185e">plan</text>
<!-- Arrow 2→3 -->
<line x1="351" y1="65" x2="388" y2="65" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<!-- Box 3: review (new) -->
<rect x="396" y="15" width="140" height="100" rx="12" fill="#f6f0ff" stroke="#7B42BC" stroke-width="2.2" stroke-dasharray="6,3"/>
<g transform="translate(446,28)">
<polyline points="3,18 10,25 25,8" fill="none" stroke="#7B42BC" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<text x="466" y="92" text-anchor="middle" font-family="system-ui,sans-serif" font-size="14" font-weight="600" fill="#00185e">review</text>
<!-- Arrow 3→4 -->
<line x1="544" y1="65" x2="581" y2="65" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<!-- Box 4: apply -->
<rect x="589" y="15" width="140" height="100" rx="12" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(634,30)">
<polygon points="5,2 30,15 5,28" fill="none" stroke="#7B42BC" stroke-width="1.8" stroke-linejoin="round"/>
</g>
<text x="501" y="110" text-anchor="middle" font-family="monospace" font-size="15" font-weight="600" fill="#00185e">apply</text>
<line x1="584" y1="90" x2="626" y2="90" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<rect x="634" y="30" width="156" height="120" rx="14" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(678,44)">
<text x="659" y="92" text-anchor="middle" font-family="monospace" font-size="14" font-weight="600" fill="#00185e">apply</text>
<!-- Arrow 4→5 -->
<line x1="737" y1="65" x2="774" y2="65" stroke="#7B42BC" stroke-width="2" marker-end="url(#wf-arrow)"/>
<!-- Box 5: Resources -->
<rect x="782" y="15" width="108" height="100" rx="12" fill="none" stroke="#7B42BC" stroke-width="2.2"/>
<g transform="translate(810,28)">
<path d="M12,28 Q0,28 0,20 Q0,14 6,12 Q6,4 15,2 Q24,0 28,6 Q29,5 32,5 Q38,5 38,11 Q44,12 44,18 Q44,24 38,25 Q38,28 34,28z" fill="none" stroke="#7B42BC" stroke-width="1.6"/>
</g>
<text x="712" y="110" text-anchor="middle" font-family="system-ui,sans-serif" font-size="15" font-weight="600" fill="#00185e">Resources</text>
<text x="400" y="18" text-anchor="middle" font-family="system-ui,sans-serif" font-size="12" fill="#666666" letter-spacing="1">WRITE → PLAN → APPLY</text>
<text x="836" y="92" text-anchor="middle" font-family="system-ui,sans-serif" font-size="13" font-weight="600" fill="#00185e">Resources</text>
</svg>
</section>
<!-- ─── SLIDE 14 : Terraform state ──────────────────────────────── -->
<section class="s-tf">
<h2>Terraform remembers what it built.</h2>
<p>The <code>.tfstate</code> file maps code to real-world resources. Store it remotely.<br>
Depending on what you manage, it can contain plaintext sensitive values — credentials, tokens, secrets.<br>
<em>Handle it with care. Don't feed it to your LLM.</em></p>
<ul>
<li>The <code>.tfstate</code> file maps code to real-world resources</li>
<li>Store it <strong>remotely</strong> — never commit it to Git</li>
<li>May contain sensitive values: credentials, tokens, secrets</li>
</ul>
<p><em>Handle it with care. Don't feed it to your LLM.</em></p>
<svg width="750" height="220" style="margin-top:0.5em;" viewBox="0 0 750 220" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="st-arrow" viewBox="0 0 8 6" refX="8" refY="3" markerWidth="8" markerHeight="6" orient="auto-start-auto">
@@ -639,9 +658,11 @@
<!-- ─── SLIDE 15 : Terraform providers ──────────────────────────── -->
<section class="s-tf">
<h2>One tool. Every API.</h2>
<p>1000+ providers: AWS, GCP, Azure, Cloudflare, GitHub, Kubernetes…<br>
Not just cloud — manage GitHub teams, Datadog monitors, PagerDuty schedules, DNS records.<br>
<em>If it has an API, there's a Terraform provider for it.</em></p>
<ul>
<li><strong>1000+ providers</strong> — AWS, GCP, Azure, Cloudflare, GitHub, Kubernetes…</li>
<li>Not just cloud — GitHub teams, Datadog monitors, PagerDuty schedules, DNS records</li>
</ul>
<p><em>If it has an API, there's a Terraform provider for it.</em></p>
</section>
<!-- ─── SLIDE 16 : Terraform code ───────────────────────────────── -->
@@ -674,9 +695,11 @@ resource "ovh_domain_zone_record" "web" {
<!-- ─── SLIDE 17 : OpenTofu ──────────────────────────────────────── -->
<section class="s-tf">
<h2>In 2023, HashiCorp changed Terraform's license.</h2>
<p>BSL instead of MPL — no longer truly open-source.<br>
The community responded: <strong>OpenTofu</strong>, by the OpenTF Foundation, is the open-source fork.<br>
<em>Drop-in replacement. Fully compatible. Community-driven.</em></p>
<ul>
<li><strong>BSL</strong> instead of MPL — no longer truly open-source</li>
<li>The community responded: <strong>OpenTofu</strong>, by the OpenTF Foundation</li>
</ul>
<p><em>Drop-in replacement. Fully compatible. Community-driven.</em></p>
</section>
<!-- ─── SLIDE 18 : Terraform platforms ──────────────────────────── -->
@@ -699,9 +722,11 @@ resource "ovh_domain_zone_record" "web" {
<!-- ─── SLIDE 20 : Ansible concepts ──────────────────────────────── -->
<section class="s-ansible">
<h2>Push, not pull. SSH, not agents.</h2>
<p>YAML playbooks run tasks in order, across any number of hosts.<br>
No daemon. No certificate authority. Just Python + SSH.<br>
<em>Idempotent modules ensure the same playbook can run safely again and again.</em></p>
<ul>
<li>YAML playbooks run tasks in order, across any number of hosts</li>
<li>No daemon. No certificate authority. Just <strong>Python + SSH</strong></li>
<li>Idempotent modules — same playbook runs safely again and again</li>
</ul>
<svg width="750" height="250" viewBox="0 0 750 250" xmlns="http://www.w3.org/2000/svg" style="margin-top:0.5em;">
<defs>
<marker id="a-push" viewBox="0 0 10 7" refX="9" refY="3.5" markerWidth="9" markerHeight="7" orient="auto">
@@ -770,16 +795,22 @@ resource "ovh_domain_zone_record" "web" {
<!-- ─── SLIDE 22 : Ansible operations ───────────────────────────── -->
<section class="s-ansible">
<h2>Not just configuration. Operations.</h2>
<p>Patch 200 servers tonight. Roll out a kernel upgrade with a canary strategy. Run a compliance audit across your whole fleet.<br>
<em>Ansible is the tool you reach for when you need to do something — once, or every week.</em></p>
<ul>
<li>Patch 200 servers tonight</li>
<li>Roll out a kernel upgrade with a canary strategy</li>
<li>Run a compliance audit across your whole fleet</li>
</ul>
<p><em>Ansible is the tool you reach for when you need to do something — once, or every week.</em></p>
</section>
<!-- ─── SLIDE 23 : Ansible Galaxy ────────────────────────────────── -->
<section class="s-ansible">
<h2>The community does the heavy lifting.</h2>
<p><strong>Ansible Galaxy</strong> — 10,000+ ready-made roles and collections.<br>
Don't write a playbook to install Docker from scratch. Someone already did.<br>
<em>Just <code>ansible-galaxy install geerlingguy.docker</code>.</em></p>
<ul>
<li><strong>Ansible Galaxy</strong> — 10,000+ ready-made roles and collections</li>
<li>Don't write a playbook to install Docker from scratch — someone already did</li>
</ul>
<p><em>Just <code>ansible-galaxy install geerlingguy.docker</code>.</em></p>
</section>
<!-- ─── SLIDE 24 : Ansible platforms ────────────────────────────── -->
@@ -802,8 +833,11 @@ resource "ovh_domain_zone_record" "web" {
<!-- ─── SLIDE 26 : Puppet concepts ─────────────────────────────── -->
<section class="s-puppet">
<h2>Pull, not push. Agents, not SSH.</h2>
<p>Every 30 minutes, each puppet-agent polls the Puppet Server, compiles a catalog, and enforces it.<br>
<em>Drift is corrected automatically — without anyone lifting a finger.</em></p>
<ul>
<li>Every 30 minutes, each <code>puppet-agent</code> polls the Puppet Server</li>
<li>Compiles a catalog and enforces it locally</li>
</ul>
<p><em>Drift is corrected automatically — without anyone lifting a finger.</em></p>
<svg width="750" height="250" viewBox="0 0 750 250" xmlns="http://www.w3.org/2000/svg" style="margin-top:0.5em;">
<defs>
<marker id="a-pull" viewBox="0 0 10 7" refX="9" refY="3.5" markerWidth="9" markerHeight="7" orient="auto">
@@ -866,9 +900,11 @@ class webserver {
<!-- ─── SLIDE 28 : Puppet drift detection ──────────────────────── -->
<section class="s-puppet">
<h2>Someone SSH'd in and changed something.</h2>
<p>Puppet noticed. Puppet fixed it.<br>
<em>Continuous compliance — not just at deploy time. Every. 30. Minutes.</em><br>
No more gardening your servers by hand.</p>
<ul>
<li>Puppet noticed. Puppet fixed it.</li>
<li>Continuous compliance — not just at deploy time. <strong>Every. 30. Minutes.</strong></li>
<li>No more gardening your servers by hand</li>
</ul>
<svg width="750" height="200" viewBox="0 0 750 200" xmlns="http://www.w3.org/2000/svg" style="margin-top:0.5em;">
<defs>
<marker id="a-cycle" viewBox="0 0 10 7" refX="9" refY="3.5" markerWidth="9" markerHeight="7" orient="auto">
@@ -905,18 +941,22 @@ class webserver {
<!-- ─── SLIDE 29 : Puppet platforms ────────────────────────────── -->
<section class="s-puppet">
<h2>Puppet is for large fleets that can't afford drift.</h2>
<p>Continuous compliance, auditability, and guaranteed state — at scale.<br>
Best suited for enterprises with hundreds or thousands of long-lived servers.<br>
<em>Fewer friendly SaaS options than Terraform or Ansible.<br>
Puppet Enterprise and Foreman are self-hosted. No managed cloud offering.</em></p>
<ul>
<li>Continuous compliance, auditability, and guaranteed state — at scale</li>
<li>Best suited for enterprises with hundreds or thousands of long-lived servers</li>
<li>Fewer SaaS options than Terraform or Ansible</li>
</ul>
<p><em>Puppet Enterprise and Foreman are self-hosted. No managed cloud offering.</em></p>
</section>
<!-- ─── SLIDE 30 : Puppet community ────────────────────────────── -->
<section class="s-puppet">
<h2>The ecosystem outlives the company.</h2>
<p><strong>Vox Pupuli</strong> — 100+ open-source Puppet modules, community-maintained.<br>
<strong>OpenVox</strong>an emerging open-source fork of the Puppet core.<br>
<em>The community is strong, with or without Puppet Inc.</em></p>
<ul>
<li><strong>Vox Pupuli</strong>100+ open-source Puppet modules, community-maintained</li>
<li><strong>OpenVox</strong> — an emerging open-source fork of the Puppet core</li>
</ul>
<p><em>The community is strong, with or without Puppet Inc.</em></p>
</section>
<!-- ─── SLIDE 31 : They're complementary ───────────────────────── -->