<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Beerus blog]]></title><description><![CDATA[Le blog d'un passionné de sysadmin et de Devops !]]></description><link>https://blog.beerus.fr/</link><image><url>https://blog.beerus.fr//favicon/favicon-48.png</url><title>Beerus blog</title><link>https://blog.beerus.fr/</link></image><generator>Beerus inc.</generator><lastBuildDate>Sat, 10 Sep 2022 16:59:21 GMT</lastBuildDate><atom:link href="https://blog.beerus.fr//rss.xml" rel="self" type="application/rss+xml"/><item><title><![CDATA[Fix le "joycon drift" de ma switch]]></title><description><![CDATA[Contexte C'est fait ! J'ai enfin eu le fameux joycon drift sur les deux joycons de ma switch. Pour rappel ce qu'est le joycon drit voir ici. Cela ne m'empêche pas réellement de…]]></description><link>https://blog.beerus.fr/repair-joycon</link><guid isPermaLink="false">https://blog.beerus.fr/repair-joycon</guid><category><![CDATA[switch]]></category><category><![CDATA[DIY]]></category><pubDate>Thu, 08 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;contexte&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#contexte&quot; aria-label=&quot;contexte permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Contexte&lt;/h1&gt;
&lt;p&gt;C&apos;est fait ! J&apos;ai enfin eu le fameux joycon drift sur les deux joycons de ma switch. Pour rappel ce qu&apos;est le joycon drit voir &lt;a href=&quot;https://www.pocket-lint.com/fr-fr/jeux-video/actualites/nintendo/148751-comment-reparer-nintendo-switch-joy-con-drift&quot;&gt;ici&lt;/a&gt;.&lt;br&gt;
Cela ne m&apos;empêche pas réellement de jouer mais cela reste très pénible voir même parfois handicapant dans certains jeux, j&apos;ai donc commencé à réfléchir à changer ou réparer mes joycons.&lt;/p&gt;
&lt;h1 id=&quot;outils&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#outils&quot; aria-label=&quot;outils permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Outils&lt;/h1&gt;
&lt;p&gt;Forcément c&apos;est un problème rencontré par tous les utilisateurs de la switch à un moment donné donc il existe une foison de tutoriels/vidéos sur internet.&lt;br&gt;
Ce qui ressorti des ressources que j&apos;ai pu consultées c&apos;est qu&apos;il me fallait deux tournevis spécifiques :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Y00 Triwing Screwdriver&lt;/li&gt;
&lt;li&gt;PH000 Phillips Screwdriver&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Au début je voulais prendre uniquement ces deux tournevis et utiliser une feuille de papier cartonnée (type business card) qui est censée être placée juste en dessous du joycon. Mais j&apos;ai eu du mal à trouver ces deux tournevis seuls (hors site chinois type Aliexpress par lesquels je ne veux pas passer...)&lt;br&gt;
Je suis donc parti sur ce &lt;a href=&quot;https://www.amazon.ca/gp/product/B08CS7DS5V/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&amp;#x26;psc=1&quot;&gt;pack&lt;/a&gt; à 20 CAD soit environ 15€ ! Peut-être un peu cher mais là il y a tout dedans :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Y00 Triwing Screwdriver&lt;/li&gt;
&lt;li&gt;PH000 Phillips Screwdriver&lt;/li&gt;
&lt;li&gt;4 joysticks neufs&lt;/li&gt;
&lt;li&gt;Un tweezer&lt;/li&gt;
&lt;li&gt;Un &quot;Plastic crowbar&quot; (pas trouvé le nom en français)&lt;/li&gt;
&lt;li&gt;De la visserie en tout genre (ressort boutons L/R, Slider Lock, vis etc...)&lt;/li&gt;
&lt;li&gt;De la cosmétique pour les joycons&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/62c092bef9391375c7240439abee45ec/62aaf/full_box.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75.11737089201877%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFA//EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAFVhCiTjcl//8QAGxAAAQQDAAAAAAAAAAAAAAAAAQACAxEQEjH/2gAIAQEAAQUCj6x4OLpARaAWP//EABURAQEAAAAAAAAAAAAAAAAAABEQ/9oACAEDAQE/ARn/xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPwGn/8QAGRABAAIDAAAAAAAAAAAAAAAAARARAFFh/9oACAEBAAY/AnWNFs9j/8QAGhAAAwEAAwAAAAAAAAAAAAAAAAERIVFhgf/aAAgBAQABPyFpS40gLizo8HLGxik2p5ZuH//aAAwDAQACAAMAAAAQt8//xAAWEQEBAQAAAAAAAAAAAAAAAAABEDH/2gAIAQMBAT8QHif/xAAVEQEBAAAAAAAAAAAAAAAAAAAQIf/aAAgBAgEBPxCD/8QAHBABAQACAwEBAAAAAAAAAAAAAREAIUFhkVGh/9oACAEBAAE/ELsKLHBTf7iyGgJ79w7V5xEgumMxb89jkQLHvP/Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;full box&quot;
        title=&quot;full box&quot;
        src=&quot;/static/62c092bef9391375c7240439abee45ec/8a34a/full_box.jpg&quot;
        srcset=&quot;/static/62c092bef9391375c7240439abee45ec/08b27/full_box.jpg 213w,
/static/62c092bef9391375c7240439abee45ec/6f6b2/full_box.jpg 425w,
/static/62c092bef9391375c7240439abee45ec/8a34a/full_box.jpg 850w,
/static/62c092bef9391375c7240439abee45ec/63107/full_box.jpg 1275w,
/static/62c092bef9391375c7240439abee45ec/62aaf/full_box.jpg 1280w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;reparation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#reparation&quot; aria-label=&quot;reparation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Réparation&lt;/h1&gt;
&lt;p&gt;Ok maintenant qu&apos;on est équipé il s&apos;agit de passer à la pratique ! Pour cela il faut bien distinguer le joycon droit du gauche car ils sont montés différemment.&lt;br&gt;
Je pense qu&apos;il faut compter environ 30min pour les deux joycons pour être large.&lt;/p&gt;
&lt;h2 id=&quot;joycon-droit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#joycon-droit&quot; aria-label=&quot;joycon droit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Joycon droit&lt;/h2&gt;
&lt;p&gt;On va tout d&apos;abord enlever les 4 vis entourées sur la photo ci-dessous :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/953c0462e2beeeb94da5f70c7b0ddd80/fb816/first_screw.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEBQH/xAAXAQADAQAAAAAAAAAAAAAAAAAAAgMB/9oADAMBAAIQAxAAAAHYyloCgUasjLM6dQ4Mn//EABwQAAEEAwEAAAAAAAAAAAAAAAEAAgMREBMyIf/aAAgBAQABBQIouo7SppiVG32yu3uN4m5x/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEREP/aAAgBAwEBPwGFHn//xAAWEQEBAQAAAAAAAAAAAAAAAAAQARH/2gAIAQIBAT8B0h//xAAeEAACAQMFAAAAAAAAAAAAAAAAEQECEiAhMjNBkf/aAAgBAQAGPwIbg3R4WjTg4qTUXUY//8QAHhABAAIBBAMAAAAAAAAAAAAAAQARQRAhMWFRceH/2gAIAQEAAT8hVE5TNZZ8+FPDMdWZq5Tg9wV0Jbb1NsOCiL2wb3X/2gAMAwEAAgADAAAAEAQRs//EABkRAAIDAQAAAAAAAAAAAAAAAAAhARARcf/aAAgBAwEBPxCco4FVf//EABcRAAMBAAAAAAAAAAAAAAAAAAEQESH/2gAIAQIBAT8QForq/8QAHRABAAMAAgMBAAAAAAAAAAAAAQARITFRQXGhsf/aAAgBAQABPxC4pDOWW+onNvZsE2r01+ypruXZ8dVG42EB5Ou4YF3pcCAXocJfalZ4yKt/SAAKc0jLn//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;first screw&quot;
        title=&quot;first screw&quot;
        src=&quot;/static/953c0462e2beeeb94da5f70c7b0ddd80/8a34a/first_screw.jpg&quot;
        srcset=&quot;/static/953c0462e2beeeb94da5f70c7b0ddd80/08b27/first_screw.jpg 213w,
/static/953c0462e2beeeb94da5f70c7b0ddd80/6f6b2/first_screw.jpg 425w,
/static/953c0462e2beeeb94da5f70c7b0ddd80/8a34a/first_screw.jpg 850w,
/static/953c0462e2beeeb94da5f70c7b0ddd80/fb816/first_screw.jpg 960w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Une fois les 4 vis enlevées, passer le &quot;plastic crowbar&quot; dans la fente qui vient d&apos;apparaître suite aux vis enlevées :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/16f890d9d78e6e6e459b399ad64ebd78/67200/unplug.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAABvXJgtJyXk0YkHCRP/8QAHBAAAgEFAQAAAAAAAAAAAAAAAQIAAxAREiEx/9oACAEBAAEFAsRl7rHrYArFwC4CqWnAm7R/Lf/EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPwGzGK1//8QAFhEAAwAAAAAAAAAAAAAAAAAAARAR/9oACAECAQE/AbUCv//EAB0QAAECBwAAAAAAAAAAAAAAAAABEBIgISIxMlH/2gAIAQEABj8CfNS5YTZl7L//xAAdEAEAAwABBQAAAAAAAAAAAAABABEhEDFhcYGh/9oACAEBAAE/ISbj44NGTdlZABR9XLp+rDIWhlOSrowb5//aAAwDAQACAAMAAAAQ0Caz/8QAFxEBAQEBAAAAAAAAAAAAAAAAABEBIf/aAAgBAwEBPxCDurZin//EABcRAAMBAAAAAAAAAAAAAAAAAAABERD/2gAIAQIBAT8QQXKI/8QAHRABAAICAwEBAAAAAAAAAAAAAQARITFBUXGh8P/aAAgBAQABPxBK1Km/lxBomHi2uV8IkHQwXD733MIQbp9LEz4LQC+XBWW2AU84mpSdQNZqLmWz/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;unplug&quot;
        title=&quot;unplug&quot;
        src=&quot;/static/16f890d9d78e6e6e459b399ad64ebd78/8a34a/unplug.jpg&quot;
        srcset=&quot;/static/16f890d9d78e6e6e459b399ad64ebd78/08b27/unplug.jpg 213w,
/static/16f890d9d78e6e6e459b399ad64ebd78/6f6b2/unplug.jpg 425w,
/static/16f890d9d78e6e6e459b399ad64ebd78/8a34a/unplug.jpg 850w,
/static/16f890d9d78e6e6e459b399ad64ebd78/67200/unplug.jpg 961w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Il suffit ensuite de &lt;strong&gt;délicatement&lt;/strong&gt; ouvrir le joycon et en voici le contenu :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 646px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6af3f7a3644c190f86fcd354a3de9200/82797/fisrt_open.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 88.26291079812205%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAASABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBA//EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHhDpENK0KB/8QAGBAAAwEBAAAAAAAAAAAAAAAAARARAAL/2gAIAQEAAQUCLs3Q0QX/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAbEAEAAQUBAAAAAAAAAAAAAAABAAIQESAxcf/aAAgBAQAGPwK+YAlXk6af/8QAGxAAAgIDAQAAAAAAAAAAAAAAABEBIRAxUUH/2gAIAQEAAT8htKFO1XcS+jKFt2J7ESViVRrR/9oADAMBAAIAAwAAABB84AH/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAWEQEBAQAAAAAAAAAAAAAAAAARABD/2gAIAQIBAT8QZ3//xAAcEAEAAwADAQEAAAAAAAAAAAABABEhMVFhQbH/2gAIAQEAAT8QQA+sptDdAeXqYVjOinB7KawFtH3RMlGK9Wv4QFpUAY0SkMuW4VHk/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;fisrt open&quot;
        title=&quot;fisrt open&quot;
        src=&quot;/static/6af3f7a3644c190f86fcd354a3de9200/82797/fisrt_open.jpg&quot;
        srcset=&quot;/static/6af3f7a3644c190f86fcd354a3de9200/08b27/fisrt_open.jpg 213w,
/static/6af3f7a3644c190f86fcd354a3de9200/6f6b2/fisrt_open.jpg 425w,
/static/6af3f7a3644c190f86fcd354a3de9200/82797/fisrt_open.jpg 646w&quot;
        sizes=&quot;(max-width: 646px) 100vw, 646px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;On peut remarquer que les deux parties sont reliées avec des câbles plats flexibles. Maintenant il faut retirer la batterie, légèrement pousser à l&apos;endroit entouré en rouge.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6125f2f94a74156411c3b00f682c1121/fb816/remove_battery.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAMBBAUC/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAIB/9oADAMBAAIQAxAAAAHumXSkbJlYCmymBAf/xAAcEAACAgIDAAAAAAAAAAAAAAAAAQIDEjIQISL/2gAIAQEAAQUCUK8nt7HZIplWjJDJCfT2fH//xAAXEQEAAwAAAAAAAAAAAAAAAAABABAR/9oACAEDAQE/AQmX/8QAFxEBAAMAAAAAAAAAAAAAAAAAAQAQEf/aAAgBAgEBPwFZt//EAB4QAAECBwEAAAAAAAAAAAAAAAARIQECECAxMkJR/9oACAEBAAY/AhIHRsZWb2rNb//EABsQAQACAwEBAAAAAAAAAAAAAAEAESExUUGh/9oACAEBAAE/IaUQ3TLDRw4qNXPyxu1uJ47o5MLUBYhB5cu2YaodmzLpn//aAAwDAQACAAMAAAAQFA9P/8QAFhEBAQEAAAAAAAAAAAAAAAAAEQAQ/9oACAEDAQE/EEjjf//EABYRAQEBAAAAAAAAAAAAAAAAABEAEP/aAAgBAgEBPxAJzn//xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFhcZH/2gAIAQEAAT8QaF10KmXy4tlECb7mRIK37RK7ehMr8iitdc1X2x8Sn2YAguD2CLYCb2+W6moB9YHECAUVkUgNFz//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;remove battery&quot;
        title=&quot;remove battery&quot;
        src=&quot;/static/6125f2f94a74156411c3b00f682c1121/8a34a/remove_battery.jpg&quot;
        srcset=&quot;/static/6125f2f94a74156411c3b00f682c1121/08b27/remove_battery.jpg 213w,
/static/6125f2f94a74156411c3b00f682c1121/6f6b2/remove_battery.jpg 425w,
/static/6125f2f94a74156411c3b00f682c1121/8a34a/remove_battery.jpg 850w,
/static/6125f2f94a74156411c3b00f682c1121/fb816/remove_battery.jpg 960w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Afin de donner ça :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/81b59f57a7d669648d2d6b3ebaada005/fb816/without_battery.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAgH/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAABkW15KbFVpPJHkxX/xAAbEAACAgMBAAAAAAAAAAAAAAAAAQIDERIiMf/aAAgBAQABBQJmGYF7dPaCM9t8po2cJO2diP/EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABoQAAIDAQEAAAAAAAAAAAAAAAABEBEhAhL/2gAIAQEABj8Co2dhI1Gqj1y6YvfVx//EABwQAQADAAIDAAAAAAAAAAAAAAEAESExUUFhgf/aAAgBAQABPyHTTPcBgxHXbSooRRJr6JzkQ8dyjouhhnJMYUJTiHE//9oADAMBAAIAAwAAABA0BfH/xAAWEQEBAQAAAAAAAAAAAAAAAAAAERD/2gAIAQMBAT8QVc//xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8QcP/EAB4QAQEAAgEFAQAAAAAAAAAAAAERACExEEFRYZHR/9oACAEBAAE/EC0BJyOMtEztOXpBJRo4ZG3fzO6gm/R2xBcGQapVSy/uG22TaV48433JpH3ByG47Sm+cNTta1F54xuP/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;without battery&quot;
        title=&quot;without battery&quot;
        src=&quot;/static/81b59f57a7d669648d2d6b3ebaada005/8a34a/without_battery.jpg&quot;
        srcset=&quot;/static/81b59f57a7d669648d2d6b3ebaada005/08b27/without_battery.jpg 213w,
/static/81b59f57a7d669648d2d6b3ebaada005/6f6b2/without_battery.jpg 425w,
/static/81b59f57a7d669648d2d6b3ebaada005/8a34a/without_battery.jpg 850w,
/static/81b59f57a7d669648d2d6b3ebaada005/fb816/without_battery.jpg 960w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;A partir de ce point il va falloir enlever les 5 vis entourées pour pouvoir retirer le cache de la batterie :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4de449b7a3732bb96afe06fa07a3cbfa/fb816/without_battery_cache.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAABAQADAAAAAAAAAAAAAAAABAACAwX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB5tmqBSqiIBtF1Wf/xAAcEAABBAMBAAAAAAAAAAAAAAABAAIDESIxMhL/2gAIAQEAAQUCpUQqpDUrvRfu1i8nIlQ9v6//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARAhUQMRIjGR/9oACAEBAAY/AjZq503ijJ3RwfsoZ//EAB0QAAMBAAIDAQAAAAAAAAAAAAABESExQRBRYaH/2gAIAQEAAT8h4YNyheg2aNHIXSfASa6ctHROK0cCqluI2Po88f1mJH//2gAMAwEAAgADAAAAEPwZgf/EABYRAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAwEBPxC2XCG//8QAFhEBAQEAAAAAAAAAAAAAAAAAAQAR/9oACAECAQE/ELINZMv/xAAeEAEAAwABBQEAAAAAAAAAAAABABEhQTFRYXGxof/aAAgBAQABPxAwBl0Tt8xGszCYdmq35K91QOiy/cMQi8l+RJ9qTmNDPcKMoC3iZ3YyhSoldY0qauj6gAYLZ//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;without battery cache&quot;
        title=&quot;without battery cache&quot;
        src=&quot;/static/4de449b7a3732bb96afe06fa07a3cbfa/8a34a/without_battery_cache.jpg&quot;
        srcset=&quot;/static/4de449b7a3732bb96afe06fa07a3cbfa/08b27/without_battery_cache.jpg 213w,
/static/4de449b7a3732bb96afe06fa07a3cbfa/6f6b2/without_battery_cache.jpg 425w,
/static/4de449b7a3732bb96afe06fa07a3cbfa/8a34a/without_battery_cache.jpg 850w,
/static/4de449b7a3732bb96afe06fa07a3cbfa/fb816/without_battery_cache.jpg 960w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;C&apos;est ici que la partie la plus technique va s&apos;opérer. Il va falloir dans un premier temps retirer les 3 câbles plats entourés par un carré rouge. Pour faire cela il faut réaliser les deux tâches suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Relever le petit ergot noir (ou gris pour le carré n°1)&lt;/li&gt;
&lt;li&gt;Avec les doigts ou le tweezer délicatement retirer le câble&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Puis retirer les deux vis entourées ce qui va libérer le joycon et vous pourrez mettre à sa place un des nouveaux joycon.&lt;/p&gt;
&lt;p&gt;Et voilà ! Il &quot;suffit&quot; de faire toutes les opérations précédentes à l&apos;envers et ainsi remonter le joycon. Attention pour mettre le câble plat je recommande vivement d&apos;utiliser le tweezer afin d&apos;être plus précis :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4d6ca88fdb52bec098de4e68d856d000/62aaf/tweezer_ex.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75.11737089201877%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAAD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAQauLB7Wr//EABgQAAMBAQAAAAAAAAAAAAAAAAABEgIi/9oACAEBAAEFAp2nPJt5RKHJ/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQIQ/9oACAEDAQE/AaQz/8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8BJ//EABwQAAEDBQAAAAAAAAAAAAAAAAACESEBEDFBYf/aAAgBAQAGPwLg+rMpNMEkOf/EAB0QAAIBBAMAAAAAAAAAAAAAAAERACExYXFBocH/2gAIAQEAAT8hLE3Hcb1R5iAWCxp1ATllQGoTc//aAAwDAQACAAMAAAAQyC//xAAWEQADAAAAAAAAAAAAAAAAAAABEDH/2gAIAQMBAT8QIVf/xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPxAKT//EAB0QAQACAgIDAAAAAAAAAAAAAAEAESExQVFhcYH/2gAIAQEAAT8QYmD0Rw9hqJ1rlV0LfBaxN6RQK1KUXQ+1mYh4nCo9WzpM5j//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;tweezer ex&quot;
        title=&quot;tweezer ex&quot;
        src=&quot;/static/4d6ca88fdb52bec098de4e68d856d000/8a34a/tweezer_ex.jpg&quot;
        srcset=&quot;/static/4d6ca88fdb52bec098de4e68d856d000/08b27/tweezer_ex.jpg 213w,
/static/4d6ca88fdb52bec098de4e68d856d000/6f6b2/tweezer_ex.jpg 425w,
/static/4d6ca88fdb52bec098de4e68d856d000/8a34a/tweezer_ex.jpg 850w,
/static/4d6ca88fdb52bec098de4e68d856d000/63107/tweezer_ex.jpg 1275w,
/static/4d6ca88fdb52bec098de4e68d856d000/62aaf/tweezer_ex.jpg 1280w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Pas besoin d&apos;enfoncer jusqu&apos;au bout, une fois réenfoncé il faut descendre l&apos;ergot en plastique relevé précédemment.&lt;/p&gt;
&lt;p&gt;NB : Il n&apos;est pas impossible que le bouton L/R vienne à s&apos;échapper (à droite sur la photo ci-dessus), il faut le reclipser avant de remonter la coque qui a été enlevée lors de la première étape.&lt;/p&gt;
&lt;h2 id=&quot;joycon-gauche&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#joycon-gauche&quot; aria-label=&quot;joycon gauche permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Joycon gauche&lt;/h2&gt;
&lt;p&gt;Le joycon gauche est légèrement différent du droit. En voici les différences :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/fd7820e65fab12e583161e8e17e7bd3f/fb816/left_joycon.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAQX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAABUsYJKRJaeT2DTRf/xAAcEAADAAEFAAAAAAAAAAAAAAAAAQIQEiEjMTL/2gAIAQEAAQUC8xJyIY1pexVnbw8f/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEQEf/aAAgBAwEBPwE1X//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABwQAAICAgMAAAAAAAAAAAAAAAAhARACMQNBcv/aAAgBAQAGPwKcu6RoRsRjLvh81//EABsQAAMBAQEBAQAAAAAAAAAAAAABESFBMVGh/9oACAEBAAE/Ic9RnII+usbZ0j8OkxU6OPsjU5svSb2ELpkH6f/aAAwDAQACAAMAAAAQl9PA/8QAFhEBAQEAAAAAAAAAAAAAAAAAEAEx/9oACAEDAQE/EAun/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEhEP/aAAgBAgEBPxAolM//xAAeEAEAAgMAAgMAAAAAAAAAAAABABEhMUFRwWGh0f/aAAgBAQABPxDcCoPNvD3DA9BXrHIR8jde4i1aWwphohW9sCUAHQS/qOKTzEKAUjVicr5hiXBO7MBMD+Zun//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;left joycon&quot;
        title=&quot;left joycon&quot;
        src=&quot;/static/fd7820e65fab12e583161e8e17e7bd3f/8a34a/left_joycon.jpg&quot;
        srcset=&quot;/static/fd7820e65fab12e583161e8e17e7bd3f/08b27/left_joycon.jpg 213w,
/static/fd7820e65fab12e583161e8e17e7bd3f/6f6b2/left_joycon.jpg 425w,
/static/fd7820e65fab12e583161e8e17e7bd3f/8a34a/left_joycon.jpg 850w,
/static/fd7820e65fab12e583161e8e17e7bd3f/fb816/left_joycon.jpg 960w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Retirer les 3 vis entourées ci-dessus. Une fois le cache de la batterie enlevé voilà ce que ça donne :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/3c4cf11844cee112c46e909f91e7024a/62aaf/left_joycon_explode.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75.11737089201877%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAgX/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAcrVOVhzzZ//xAAZEAEAAwEBAAAAAAAAAAAAAAABABEhAhL/2gAIAQEAAQUCBmrdTp9Dd6T/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAwEBPwFH/8QAFREBAQAAAAAAAAAAAAAAAAAAABL/2gAIAQIBAT8BU//EABkQAAIDAQAAAAAAAAAAAAAAAAARASExEP/aAAgBAQAGPwLcE4FFquaJn//EABsQAQEBAAMBAQAAAAAAAAAAAAERACExcUFR/9oACAEBAAE/IVDxK9uYO99C66JC5BkgrTp0AVPcr/hv/9oADAMBAAIAAwAAABALz//EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAEDAQE/EIl//8QAFhEBAQEAAAAAAAAAAAAAAAAAAAEx/9oACAECAQE/EMSn/8QAHBABAAMAAgMAAAAAAAAAAAAAAQARIUFRYZHR/9oACAEBAAE/ENQNgHRUsm6gqQdOeYLSlYUo1BnDC6fYNekHW7HNheqVK9T/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;left joycon explode&quot;
        title=&quot;left joycon explode&quot;
        src=&quot;/static/3c4cf11844cee112c46e909f91e7024a/8a34a/left_joycon_explode.jpg&quot;
        srcset=&quot;/static/3c4cf11844cee112c46e909f91e7024a/08b27/left_joycon_explode.jpg 213w,
/static/3c4cf11844cee112c46e909f91e7024a/6f6b2/left_joycon_explode.jpg 425w,
/static/3c4cf11844cee112c46e909f91e7024a/8a34a/left_joycon_explode.jpg 850w,
/static/3c4cf11844cee112c46e909f91e7024a/63107/left_joycon_explode.jpg 1275w,
/static/3c4cf11844cee112c46e909f91e7024a/62aaf/left_joycon_explode.jpg 1280w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Retirer les deux câbles plats entourés ci-dessus puis les deux vis entourées. Et voilà !&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Rien de bien compliqué dans ce changement de sticks sur les joycons, il faut juste être minutieux et bien équipé !&lt;/p&gt;</content:encoded><author>Beerus Inc.</author></item><item><title><![CDATA[Redondance "du pauvre" d'un site personnel]]></title><description><![CDATA[Contexte Mon serveur hébergé a des petits soucis en ce moment, il a tendance à planter régulièrement malgré le fait que je le supervise activement. J'ai très longtemps pensé que c…]]></description><link>https://blog.beerus.fr/redondance-sites</link><guid isPermaLink="false">https://blog.beerus.fr/redondance-sites</guid><category><![CDATA[ovh]]></category><category><![CDATA[python]]></category><pubDate>Thu, 18 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;contexte&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#contexte&quot; aria-label=&quot;contexte permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Contexte&lt;/h1&gt;
&lt;p&gt;Mon serveur hébergé a des petits soucis en ce moment, il a tendance à planter régulièrement malgré le fait que je le supervise activement.&lt;br&gt;
J&apos;ai très longtemps pensé que c&apos;était l&apos;un de mes containers docker qui s&apos;emballait (malgré le fait qu&apos;il y ait des options de runtime de paramétrées) mais il s&apos;avère que c&apos;est le metrics scraper d&apos;OVH installé qui posait problème !&lt;br&gt;
Bref avant de résoudre le problème, mes services hébergés ne répondaient plus de temps en temps et cela reste tout de même très embêtant. Il a donc fallu que je pense à une potentielle redondance !&lt;/p&gt;
&lt;h1 id=&quot;etude-des-solutions&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#etude-des-solutions&quot; aria-label=&quot;etude des solutions permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Etude des solutions&lt;/h1&gt;
&lt;p&gt;Il fallait donc que je trouve une solution pour avoir les sites les plus importants toujours en fonction en cas de défaillance majeure de mon serveur dédié le temps que je trouve une solution à long terme. Pour simplifier la problématique je ne souhaite basculer qu&apos;un seul site pour le moment car il est consulté fréquemment pour des raisons professionnelles, les autres n&apos;ont pas d&apos;importance cruciale.&lt;/p&gt;
&lt;p&gt;J&apos;ai les équipements suivants avec moi :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une IP publique dédiée d&apos;OVH&lt;/li&gt;
&lt;li&gt;Un serveur hébergé chez OVH&lt;/li&gt;
&lt;li&gt;Un micro serveur avec des ressources équivalentes de celle d&apos;OVH chez moi&lt;/li&gt;
&lt;li&gt;La fibre et une IP publique dynamique (celle de ma box)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voici les quelques techniques auxquelles j&apos;ai pensé en premier lieu :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backup, Replica&lt;/li&gt;
&lt;li&gt;Cluster&lt;/li&gt;
&lt;li&gt;Solution de fail over&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La solution &lt;strong&gt;backup/réplica&lt;/strong&gt; a tout de suite été écartée du fait qu&apos;elle ne soit pas du tout flexible. Je fais déjà du backup de mon serveur vers chez moi mais c&apos;est cela concerne plus la conf de mon dockerfile et les datas de certains containers mais rien qui ne me permet de remonter une infra en 10min automatiquement (surtout pour une solution censée rester temporaire).&lt;br&gt;
Pour le &lt;strong&gt;cluster&lt;/strong&gt; ça serait la solution idéale, dans mon cas passer sous Docker Swarm ou encore mieux tout migrer sous K8s/K3s. Le problème est que je veux une solution rapide à mettre en place ne necessitant pas une refonte complète de mon infra. D&apos;autant plus que je n&apos;ai pas du tout réfléchi à la conception de ma future infra et comment cela est géré avec une IP publique dynamique.&lt;br&gt;
La dernière proposition est surement la plus adaptée pour moi, trouver une &lt;strong&gt;solution de failover&lt;/strong&gt; simple et efficace avec le moins d&apos;intervention humaine sans toucher à la configuration déjà en place.&lt;/p&gt;
&lt;p&gt;Une fois choisie il a fallu que je compare les solutions avec les contraintes suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une bascule faite en 5 minutes max en cas de problème.&lt;/li&gt;
&lt;li&gt;L&apos;ensemble des données doivent être identique et synchronisé (si modification d&apos;un fichier html réplication immédiate sur le backup).&lt;/li&gt;
&lt;li&gt;Rapide et simple à mettre en place, pas de service payant etc...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Après un moment de réflexion voici le workflow imaginé :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 799px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0b40409ff0374b8d105c68dfa76bfa3f/dd6e8/schema_failover.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 81.69014084507043%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACdElEQVQ4y21Ua5OiQAzk//+w+3BVt+4pyCpvmAEGUN4goPZVsovluUtVagaS6XQ6E7TLNOPZxsuEeVlQtz38SCFWJTyRIy1q+DJHFOfIzzWm+TOWbD1Hpr2CUWBDYELxNyklHNdlEzLGNC8I4wLzcn2APZu2IpMN44UPnKsWvsjQdANknCASAkIIpCpj/8EJeb9cb2i7ns/S2vUDNAogx2qUhVl2A5wg5VLjrELbT0jzGoHMEac5LNuBHwQIghDmxxFHy0IkJLSm7RAnKZJU8doPI5dD4HXTIFUKoYhxtH2EkWQW5L/e7ggjAV03OIbOs4ZBGPFLXTcQQmK73XEglWqaH3jbvGOnG9jqOu8d12MtbceFsTc5tqobZkyrRjSJJTE6nUumTSzoG7EdxwuGfsDYD5i+GrdqTRURCD20L6saGmUj+zhaXJKUMQMRKFk7jOhtD8POREvvXY+27Rg4TRU2m3e4js9siYQWyhidynE3LZzLCtudDpXlUCrjTqZ5gTwUOB1s3qssY39xOsH1fGZ26mv4YYi6bqGFQiJ0XOReAN/zWaumaXG749H56cvmeeFSyUfaGYaJQEYQVcracslU3qmsUFQ1a0jvlJUSOZ4HahppR7p9TtGVJcrygiUhzZNEcRMphieFMq/Z+R4uVyR+gOLXb1wI6GsKCMzzA9iOw6Ck2fWOxzX7NikPm2fMTYuz6+Ng2Xx5ialu7FGWFeqmRRwnDPg8xz/O8iOAGN/u2O9Nvqek0fvfLXdznS5aX+f5P8DLUyYqI0lS7vrhaOFo2dz1P28b9q2aPhP5DvjClA7RvaMSadSoEbphPP40P/1t/gE/lLzSQjd27wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;schema failover&quot;
        title=&quot;schema failover&quot;
        src=&quot;/static/0b40409ff0374b8d105c68dfa76bfa3f/dd6e8/schema_failover.png&quot;
        srcset=&quot;/static/0b40409ff0374b8d105c68dfa76bfa3f/53f68/schema_failover.png 213w,
/static/0b40409ff0374b8d105c68dfa76bfa3f/df70d/schema_failover.png 425w,
/static/0b40409ff0374b8d105c68dfa76bfa3f/dd6e8/schema_failover.png 799w&quot;
        sizes=&quot;(max-width: 799px) 100vw, 799px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Le détail des flux serait donc le suivant :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Problème sur la production (serveur OVH) qui rend le site web indisponible&lt;/li&gt;
&lt;li&gt;Un script sur le serveur backup vérifie régulièrement la disponibilité du site web&lt;/li&gt;
&lt;li&gt;Le script constate l&apos;indisponibilité et via les API OVH change l&apos;IP publique du site en question en la faisant pointer sur le serveur de backup lui-même&lt;/li&gt;
&lt;li&gt;Avec un TTL assez faible (60), l&apos;utilisateur devrait avoir accès au site web via le backup&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il reste le sujet de la synchronisation des données, solutions possibles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un montage sur le dossier du site web en question&lt;/li&gt;
&lt;li&gt;Un rsync depuis le backup vers la prod à une fréquence régulière&lt;/li&gt;
&lt;li&gt;Un rsync depuis la prod vers le backup dès qu&apos;un fichier est modifié&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&apos;ai passé pas mal de temps sur ces solutions car elles ont toutes leurs problèmes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Montage&lt;/strong&gt; : Aucun intérêt car si la prod plante je n&apos;ai plus de montage et donc plus de donnée, il faut forcément une copie. Je peux toujours par la suite via un cron faire une copie régulière des données en local mais aucun intérêt par rapport aux autres solutions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rsync depuis le backup&lt;/strong&gt; : Pas trop fan de créer des accès sur mon serveur de prod même si c&apos;est du rsync via clé SSH sur un user non root. Mais surtout comment je détecte qu&apos;un fichier a changé ou été créé ? Seule la prod peut avoir ses infos. J&apos;ai tout de même essayé de créer un montage sshfs avec une surveillance du dossier via l&apos;outil inotify mais cela ne marche pas du tout ensemble, inotify fonctionne avec un système de fichier local.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rsync depuis la prod&lt;/strong&gt; : Dernière solution, celle-ci parait la plus &quot;faisable&quot; la prod surveillant ses fichiers via inotify ou un autre outil et rsync en cas de changement. Par contre avec l&apos;IP dynamique je suis toujours &quot;bloqué&quot; car à chaque redémarrage de ma box je change d&apos;IP. J&apos;ai donc dû faire appel à un service type DynDNS, ma box ne gérant que DynDNS ou NoIP j&apos;ai choisi ce dernier qui a une version freemium (il faut valider manuellement le domaine tous les mois sinon 5€/mois...)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;mise-en-place&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mise-en-place&quot; aria-label=&quot;mise en place permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Mise en place&lt;/h1&gt;
&lt;p&gt;J&apos;ai 4 parties à mettre en place :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le script de vérification de la disponibilité du site web.&lt;/li&gt;
&lt;li&gt;Le script de changement du DNS.&lt;/li&gt;
&lt;li&gt;L&apos;outil qui va permettre la synchro des données de la prod vers le backup.&lt;/li&gt;
&lt;li&gt;Des petits scripts annexes pour alerter en cas de défaillance de la prod/backup.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Toute la partie scripting va être condensée dans un seul et même script&lt;/p&gt;
&lt;h2 id=&quot;partie-scripting&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#partie-scripting&quot; aria-label=&quot;partie scripting permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Partie scripting&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;from urllib.request import urlopen, Request
from urllib.error import HTTPError, URLError
import sys
import time
import requests
import dns.resolver
import ovh

new_ip = requests.get(&apos;https://api.ipify.org&apos;).content.decode(&apos;utf8&apos;) #Dynamic public IP
domain = &quot;beerus.fr&quot;
site_name = &quot;&amp;lt;the_website_to_monitor&gt;&quot;
ifttt_event = &quot;&amp;lt;event_ifttt_name&gt;&quot; #See https://ifttt.com
ifttt_key = &quot;&amp;lt;event_ifttt_key&gt;&quot; #See https://ifttt.com
ovh_secret = &quot;&amp;lt;ovh_secret&gt;&quot; #See https://docs.ovh.com/ca/fr/api/first-steps-with-ovh-api/
ovh_key = &quot;&amp;lt;ovh_key&gt;&quot; #See https://docs.ovh.com/ca/fr/api/first-steps-with-ovh-api/
ovh_consumer = &quot;&amp;lt;ovh_consumer&gt;&quot; #See https://docs.ovh.com/ca/fr/api/first-steps-with-ovh-api/

# setting the URL you want to monitor
URL = Request(&quot;https://{0}.{1}&quot;.format(site_name, domain),
              headers={&apos;User-Agent&apos;: &apos;Mozilla/5.0&apos;})
i = 0

#Verify status of the DNS
result = dns.resolver.query(site_name, &apos;A&apos;)
for ipval in result:
    if ipval.to_text() == new_ip:
        print(&quot;Already switched&quot;)
        sys.exit(0)

#The site is answering ?
while i &amp;lt; 10:
    time.sleep(5)
    print(URL.full_url)
    try:
        response = urlopen(URL, timeout=2)
    except (HTTPError, URLError) as error:
        i = i+1
        continue
    if response.status == 200:
        print(&quot;Prod is okay&quot;)
        break
    i = i+1

#The website is down so we can switch and alert
if i == 10:
    response = requests.post(&apos;https://maker.ifttt.com/trigger/{0}/with/key/{1}&apos;.format(ifttt_event, ifttt_key))
    client = ovh.Client(
        endpoint=&apos;ovh-eu&apos;,
        application_key=ovh_key,
        application_secret=ovh_secret,
        consumer_key=ovh_consumer,
    )

    result = client.put(
        &apos;/domain/zone/{0}/record/5206233547&apos;.format(domain),
        subDomain=site_name,
        target=new_ip,
        ttl=60,
    )

    result = client.post(&apos;/domain/zone/{0}/refresh&apos;.format(domain))&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Le script ci-dessus a été passé en cron sur le serveur backup et est exécuté toutes les 10 minutes.&lt;br&gt;
Il exécute les actions suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vérification du DNS (le site a-t-il déjà basculé ?)&lt;/li&gt;
&lt;li&gt;Curl vers le site en question, 10 tests avec un intervalle de 5s&lt;/li&gt;
&lt;li&gt;Si down bascule vers le backup via les API d&apos;OVH&lt;/li&gt;
&lt;li&gt;Notification (on verra ça dans une autre partie)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;synchronisation-donnees&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#synchronisation-donnees&quot; aria-label=&quot;synchronisation donnees permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Synchronisation données&lt;/h2&gt;
&lt;p&gt;Pour la synchro j&apos;avais dans un premier temps pensé à inotify avec rsync.&lt;br&gt;
Il aurait suffi de lancer le binaire (via systemd dans l&apos;idéal) et dès lors qu&apos;il aurait remarqué un event qui match avec les options précisées (create, delete, move etc...) il effectuerait un rsync.&lt;br&gt;
Le problème étant que cela nécessite pas mal de bricolage (script, création d&apos;un systemd etc...) et j&apos;aurais aimé en éviter le plus possible.
Heureusement je suis tombé sur l&apos;outil &lt;strong&gt;lsyncd&lt;/strong&gt; qui fait exactement ce travail, pas besoin de réinventer la roue !
En plus il peut se baser sur rsync pour faire ses actions ce qui est parfait pour moi. J&apos;ai fait deux configurations :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une pour le webroot de mon site, en cas de modification/ajout/suppression lsyncd exécute un rsync immédiatement vers mon backup&lt;/li&gt;
&lt;li&gt;Une pour le dossier des certificats de mon site web, étant donné que je suis sous LetsEncrypt les certificats sont renouvelés régulièrement. De la même façon dès qu&apos;il y a une modification de ceux-ci (le certificat public à priori) il copie le nouveau certificat sur le backup&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tous cela est parfait mais il me manque encore la partie SSH pure car mon serveur backup est hébergé chez moi derrière ma box. J&apos;utilise déjà le port 22 pour d&apos;autres usages donc il va falloir faire de la configuration additionnelle.&lt;br&gt;
J&apos;avais deux possibilités :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Je fais un NAT sur un port différent du 22 (du style IP_PUB:2222 --&gt; backup:22)&lt;/li&gt;
&lt;li&gt;Je fais un bastion SSH avec un hardenning et qui forward mes requêtes vers mon backup&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&apos;ai décidé de faire la deuxième solution, ça permet de s&apos;entrainer sur quelque chose que je n&apos;ai pas l&apos;habitude de faire 🙂. Je passe la partie hardenning car ce n&apos;est pas ce que j&apos;ai envie d&apos;aborder dans ce post mais ça consiste à faire les choses suivantes (non exhaustives) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fail2ban&lt;/li&gt;
&lt;li&gt;No PermitRoot&lt;/li&gt;
&lt;li&gt;Authentification par clé uniquement&lt;/li&gt;
&lt;li&gt;Un Jail chroot avec un nombre de binaire limité (adios su et sudo 😈)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par rapport au bastion, 3 solutions pour faire ce jump :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stockage des clés SSH sur le bastion&lt;/li&gt;
&lt;li&gt;Forwarding SSH agent&lt;/li&gt;
&lt;li&gt;Utiliser ProxyCommand/ProxyJump&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Stockage des clés SSH sur le bastion&lt;/strong&gt;: Cela signifie que le bastion possède la clé SSH privée de mon serveur backup, étant donné qu&apos;il reste public cela est toujours dangereux. On met cette idée de côté pour l&apos;instant.&lt;br&gt;
&lt;strong&gt;Forwarding SSH agent&lt;/strong&gt;: On passe nos clés privées à un agent SSH puis on forward cet agent sur notre bastion. L&apos;agent SSH étant une socket Unix (lié à la variable $SSH_AUTH_SOCK) le jump host va pointer vers notre agent local au lieu de pointer sur le sien. Mais il suffit d&apos;être root sur le bastion pour faire pointer sa variable $SSH_AUTH_SOCK sur notre socket et accéder au backup. Pas terrible niveau sécu également.&lt;br&gt;
&lt;strong&gt;ProxyCommand/ProxyJump&lt;/strong&gt;: La meilleure solution, le serveur intermédiaire (le bastion) exécute une &lt;code class=&quot;language-text&quot;&gt;ProxyCommand&lt;/code&gt; lors de la connexion et forward l&apos;input et l&apos;output vers le backup. Il suffit pour cela d&apos;utiliser l&apos;option &lt;code class=&quot;language-text&quot;&gt;-J&lt;/code&gt; du binaire SSH.&lt;br&gt;
Ex : &lt;code class=&quot;language-text&quot;&gt;ssh -J username@bastion username@backup&lt;/code&gt;. Le seul problème de cette solution c&apos;est que si je veux préciser une clé SSH privée la commande ne peut pas deviner si cela s&apos;applique au bastion ou au backup. Je suis donc passé via la config SSH :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Host bastion
    User linux
    HostName bastion.domain.tld
    IdentityFile ~/.ssh/bastion_rsa

Host backup #Pas besoin d&apos;être accessible depuis internet donc
    User backup
    HostName backup.domain.lan
    IdentityFile ~/.ssh/backup_rsa
    ProxyJump bastion.domain.tld&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Et lorsque je fais un simple &lt;code class=&quot;language-text&quot;&gt;ssh backup&lt;/code&gt; (après recopie des clés publiques sur les bons serveurs) la magie opère ! Petit test de modification d&apos;un fichier ça fonctionne bien, le fichier modifié est bien propagé sur le backup 🙂&lt;/p&gt;
&lt;h2 id=&quot;notifications&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#notifications&quot; aria-label=&quot;notifications permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Notifications&lt;/h2&gt;
&lt;p&gt;Dernier point : le fignolage ! Il s&apos;agit désormais de m&apos;avertir en cas de défaillance de la prod OU du backup (on ne sait jamais lui aussi il peut planter !).&lt;br&gt;
Pour le backup je fais presque que la même chose que le script ci-dessus, j&apos;ai des curl qui interroge régulièrement le nom DynDNS pointant vers mon site web (j&apos;ai configuré mon reverse proxy Nginx pour répondre au vrai nom de mon site web et au nom DynDNS). En cas de défaillance je reçois un mail sur ma boite perso @beerus.fr.&lt;/p&gt;
&lt;p&gt;Par contre pour la prod c&apos;est plus complexe (et plus important aussi). En fait je pourrais faire le même mécanisme que pour le backup mais je ne recevrai jamais le mail @beerus.fr car mon serveur mail est hébergé sur la même machine que mon site web...&lt;br&gt;
J&apos;ai commencé à regarder pour pouvoir utiliser les API de Gmail mais très honnetement ça ne me tentait pas trop.&lt;br&gt;
Donc à la place j&apos;ai utilisé le service &lt;strong&gt;IFTTT&lt;/strong&gt;, j&apos;ai trouvé le concept tellement simple et efficace.
Une application Android (ou Apple) à télécharger ensuite &quot;programmer&quot; son alerte :&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 757px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7508569b10bf3ac074b7b9ce1309c7e3/70668/ifttt.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 87.79342723004696%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACqElEQVQ4y42TWUiUURSAr6aFFdGTBC0Q0UYGEYRBD70E2UPLa09B0Js9hS22Gr30olmmOaMt4+joNGlEikG0gDqbk+aWW4VMkOU4FvWQzsz94t77a5pL/fD95/yHc89/7lnE/T7IboKzfrgUNHKSM76Z+uT3+cAfLgbhWgiutEJRF4gdHljthGMvQRSDKAJxB8RtECXSyGJpYemFGG6AuAkpNnNmfRWIPY8huxk8740xsw4ONsK6Stjultppo0uypVqS8RA2uCRJpZLkUjRJpSBKTQI6YFY9pDtgaw0stsPyclhWDotshhSbJNUOqWVGV9mklUnSyphC+SfbYJsbxNAPCH6F0Ah0jkKHRZdG0j0Goc+/CIR/ar1zVE75dE7jbQT6v4FgwSeh3x+7Q7Q1v5hmk/OeEIPfwTsM7RHoG4Nei3dj0BOVWnaOxGn/Mq71rqi0QNMThe6oyVLFEidew65ayHBbHS62KDF1UQ1QtU2xq5rKqZoplpabGq51wioH7K4DcbkVrreDsx9OeSHXD3mtcLgRshokx1/BzkeSA/WSfU/hyDNJZq1kc42aAtPEybHZVA1ifwOsccLeJ3D0OZxsgkONZnyWlEk9ASqzFXcVsPKemk2p50/csigyM5n+AERFP+T44EIATvsgx2s2IjdgbOf8krw2uPxGZS/1dqituBoyN8mzdLUxelNm90lOk6bLwx96GegIztHl2d0WcQmxxCTSAibikvFYXB8ZCn+ib2BQH1C2iXhilr8invgrQynlDLnQM5+vmM8xEokQCATw+Xy0tLRolO73+wmHw/P+eM4MY7EYlZWVFBQU4HA4tO5yuahwOCgsLMRmsxGNRv+d4fSAVVVV5Ofn64Aejwe3261tKqDdbv+/gLOv7J9xZa/Xq78XuvJvVvnCPbv8G/UAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ifttt&quot;
        title=&quot;ifttt&quot;
        src=&quot;/static/7508569b10bf3ac074b7b9ce1309c7e3/70668/ifttt.png&quot;
        srcset=&quot;/static/7508569b10bf3ac074b7b9ce1309c7e3/53f68/ifttt.png 213w,
/static/7508569b10bf3ac074b7b9ce1309c7e3/df70d/ifttt.png 425w,
/static/7508569b10bf3ac074b7b9ce1309c7e3/70668/ifttt.png 757w&quot;
        sizes=&quot;(max-width: 757px) 100vw, 757px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Comme on peut le voir ci-dessus en cas de réception d&apos;un webhook on envoie une notification push à l&apos;application IFTTT reliée au compte.&lt;br&gt;
J&apos;ai juste eu à ajouter la commande curl à mon script ci-dessus et le tour était joué, ça marche parfaitement ! Très peu d&apos;infos sont également transmise à ce service tiers (surement une ip publique et peut-être des infos négligables concernant mon téléphone) ça reste acceptable de mon côté, le businness plan consiste à proposer des version premium qui permettent de développer son propre algo ou avoir plus d&apos;event.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Une grosse journée de travail pour concevoir, mettre en place et peaufiner. J&apos;espérais pas mettre plus de temps et c&apos;est chose faite.
J&apos;ai une solution, certes bricolée, mais fonctionnelle et facile. Il me reste tout de même une partie manuelle : en cas de défaillance de la prod et de bascule sur le backup, je dois manuellement refaire pointer le DNS vers la prod (bien que j&apos;utilise un script pour ça).
La solution n&apos;est de toute façon mise en place que temporairement le temps que je réfléchisse à une nouvelle architecture qui sera bien plus robuste et pensée en amont.&lt;br&gt;
Cela reste malgré tout un très bon exercice, très proche du système ça toujours fait du bien de remettre les mains dans le cambouis 🙂&lt;/p&gt;</content:encoded><author>Beerus Inc.</author></item><item><title><![CDATA[Retour d'expérience sur la certification CKA]]></title><description><![CDATA[Mon entreprise a pu cette année me financer la Certified Kubernetes Administrator (CKA), obtenue avec succès il y a quelques jours c'est l'occasion pour moi de faire un petit…]]></description><link>https://blog.beerus.fr/get-CKA</link><guid isPermaLink="false">https://blog.beerus.fr/get-CKA</guid><category><![CDATA[k8s]]></category><category><![CDATA[certification]]></category><pubDate>Thu, 11 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mon entreprise a pu cette année me financer la Certified Kubernetes Administrator (CKA), obtenue avec succès il y a quelques jours c&apos;est l&apos;occasion pour moi de faire un petit retour d&apos;expérience !&lt;/p&gt;
&lt;h1 id=&quot;contexte&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#contexte&quot; aria-label=&quot;contexte permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Contexte&lt;/h1&gt;
&lt;p&gt;Tout d&apos;abord il faut savoir qu&apos;il n&apos;existe que 4 certifications Kubernetes officielles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes and Cloud Native Associate (KCNA)&lt;/li&gt;
&lt;li&gt;Certified Kubernetes Application Developer (CKAD)&lt;/li&gt;
&lt;li&gt;Certified Kubernetes Administrator (CKA)&lt;/li&gt;
&lt;li&gt;Certified Kubernetes Security Specialist (CKS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Celle qui correspond le plus à mon profil et ce que je sais faire est la CKA.
Elle coûte environ 400$ et possède les avantages suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un certain nombre de ressources sur Kubernetes (rien d&apos;exceptionnel)&lt;/li&gt;
&lt;li&gt;Deux examens blancs (identiques cependant) pour se préparer&lt;/li&gt;
&lt;li&gt;Des accès à des plateformes d&apos;entrainement et de scénario divers&lt;/li&gt;
&lt;li&gt;L&apos;accès à certification en elle-même&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Afin d&apos;obtenir la certification il &quot;suffit&quot; d&apos;avoir 66% de réponse correcte le jour de l&apos;examen.&lt;br&gt;
Les réponses ne sont pas de type QCM mais plus en mode TP, il faut &quot;réaliser&quot; l&apos;exercice sur un environnement Kubernetes.&lt;br&gt;
L&apos;examen se décompose de la façon suivante :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Storage 10%&lt;/li&gt;
&lt;li&gt;Troubleshooting 30%&lt;/li&gt;
&lt;li&gt;Workloads &amp;#x26; Scheduling 15%&lt;/li&gt;
&lt;li&gt;Cluster Architecture, Installation &amp;#x26; Configuration 25%&lt;/li&gt;
&lt;li&gt;Services &amp;#x26; Networking 20%&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;se-preparer&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#se-preparer&quot; aria-label=&quot;se preparer permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Se préparer&lt;/h1&gt;
&lt;p&gt;Etant donné que je n&apos;ai jamais eu de réelle expérience professionnelle de Kubernetes je n&apos;ai pas pris cette certification à la légère, j&apos;ai acheté deux formations sur Udemy pour préparer cet examen :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Certified Kubernetes Administrator (CKA) with Practice Tests (~13€)&lt;/li&gt;
&lt;li&gt;Kubernetes for the Absolute Beginners (~13€)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces formations comprennent :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les cours en vidéo de 3 à 20 minutes chacune&lt;/li&gt;
&lt;li&gt;Des résumés PDF des chapitres étudiés (honnêtement pas terrible les PDF)&lt;/li&gt;
&lt;li&gt;Accès à une plateforme d&apos;entrainement scénarisée selon les chapitres&lt;/li&gt;
&lt;li&gt;Quelques examens blancs (ne représente pas les conditions de l&apos;examen cependant)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Franchement je n&apos;attendais pas grand-chose de ces formations notamment par rapport au prix investi mais j&apos;ai vraiment été agréablement surpris ! (Comme quoi ne pas juger une formation en fonction du prix).&lt;br&gt;
Par contre si j&apos;avais su je n&apos;aurais peut-être pas pris la formation &quot;Kubernetes for the Absolute Beginners&quot; qui est reprise en entier ou presque dans la formation &quot;Certified Kubernetes Administrator (CKA) with Practice Tests&quot;.&lt;/p&gt;
&lt;p&gt;Pour ceux qui ne veulent pas débourser de l&apos;argent pour cela je conseille les vidéos de Xavki sur YouTube dans la playlist Kubernetes. Elle ne prépare pas en tant que tel pour la certification mais ses vidéos sont vraiment de qualité et vont plus loin que le périmètre de la certification.&lt;/p&gt;
&lt;p&gt;Ensuite je conseille les liens suivants qui m&apos;ont été utile pour fignoler ma préparation :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kubernetes.io/docs&quot;&gt;https://kubernetes.io/docs&lt;/a&gt; : fait partie des rares sites autorisés le jour de l&apos;examen, je conseille de bien s&apos;approprier le site afin de perdre le moins de temps possible le jour J.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.linuxfoundation.org/tc-docs/certification/tips-cka-and-ckad&quot;&gt;https://docs.linuxfoundation.org/tc-docs/certification/tips-cka-and-ckad&lt;/a&gt; : concerne les détails pratique de l&apos;examen (comment cela se passe, la plateforme utilisé etc...)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/StenlyTU/K8s-training-official&quot;&gt;https://github.com/StenlyTU/K8s-training-official&lt;/a&gt; : un repo d&apos;exercices en lien avec les topics CKA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je conseille plus que vivement d&apos;utiliser la plateforme d&apos;examen blanc fourni par le site killer.sh&lt;br&gt;
Elle propose des conditions d&apos;examen &lt;strong&gt;identiques&lt;/strong&gt; et permet donc d&apos;avoir une première approche de ce qu&apos;il sera proposé le jour J.&lt;br&gt;
Personnellement je n&apos;ai eu que 75/125 soit seulement 60% donc en dessous des 66% demandé. MAIS :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les questions sont plus difficiles que celles du vrai examen&lt;/li&gt;
&lt;li&gt;Elles sont également plus nombreuses (25 au lieu de 17) pour le même temps (2h)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En lisant quelques sub reddit je me suis rendu compte que je n&apos;étais pas seul dans ce cas et que 75pts restait finalement un bon score.&lt;/p&gt;
&lt;p&gt;Enfin voici quelques conseils que j&apos;ai pu trouver ici et là sur internet.&lt;br&gt;
Ajouter des variables bash pour aller plus vite :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;export do=&quot;--dry-run=client -o yaml&quot;
export now=&quot;--force --grace-period 0&quot;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ces deux variables peuvent être ajoutées à la fin des commandes kubectl pour créer un fichier ou supprimer un pod plus rapidement.&lt;br&gt;
Ex: &lt;code class=&quot;language-text&quot;&gt;kubectl run nginx --image nginx $do &gt; pod.yml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Bien étudier ce workflow qui détaille comment troubleshoot une partie des ressources K8S, cela représente 30% de la note tout de même :
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/813069e8929197f3610ce363288e7c30/be26e/workflow_troubleshoot.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 139.90610328638496%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAcABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAEDAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB625WGBEXd1goH//EABsQAAIDAAMAAAAAAAAAAAAAAAECABAREiEi/9oACAEBAAEFAu1PItBG9GlDa2RToAyZX//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB8QAAEDAwUAAAAAAAAAAAAAACEAAhEBEoEQIGGR8f/aAAgBAQAGPwKLndITTCJVC9uNfUbp42//xAAeEAEAAgICAwEAAAAAAAAAAAABABEhMUFRYYGhwf/aAAgBAQABPyGiWrdwBQeVhoVZdxNap6RytViA+YJNm85/UoR0u1fJlL9PEFLuIW+ZR1P/2gAMAwEAAgADAAAAEBAtAP/EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8QH//EABYRAAMAAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPxAr/8QAHhABAQADAAIDAQAAAAAAAAAAAREAITFhgUFRcZH/2gAIAQEAAT8QdhAWKB5ZrEsQfAfV7lWA+kvoxiPtZC/aZ8mIGHcmpA77h0c0CzPFTHGIrr7cYnLrwj4JlgKurNH0YFZpzeQ4P5n/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;workflow troubleshoot&quot;
        title=&quot;workflow troubleshoot&quot;
        src=&quot;/static/813069e8929197f3610ce363288e7c30/8a34a/workflow_troubleshoot.jpg&quot;
        srcset=&quot;/static/813069e8929197f3610ce363288e7c30/08b27/workflow_troubleshoot.jpg 213w,
/static/813069e8929197f3610ce363288e7c30/6f6b2/workflow_troubleshoot.jpg 425w,
/static/813069e8929197f3610ce363288e7c30/8a34a/workflow_troubleshoot.jpg 850w,
/static/813069e8929197f3610ce363288e7c30/be26e/workflow_troubleshoot.jpg 1142w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;lexamen-en-lui-meme&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#lexamen-en-lui-meme&quot; aria-label=&quot;lexamen en lui meme permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;L&apos;examen en lui même&lt;/h1&gt;
&lt;p&gt;Une fois qu&apos;une date sera choisie il faudra respecter les conditions suivantes le jour J :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoir une webcam (externe ou interne)&lt;/li&gt;
&lt;li&gt;Avoir une pièce d&apos;identité non expirée (permis de conduire, passeport, CNI etc...)&lt;/li&gt;
&lt;li&gt;Être dans une pièce isolée où être seul et au calme&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bien vérifier également que la webcam puisse filmer la pièce d&apos;identité &lt;strong&gt;distinctement&lt;/strong&gt; (c&apos;est très important !).&lt;/p&gt;
&lt;p&gt;Il faut se connecter jusqu&apos;à 30min avant, une fois cela fait il sera possible de télécharger un logiciel qui fera office de plateforme d&apos;examen (attention 300Mo dans mon cas).&lt;br&gt;
Une fois téléchargé et installé il faudra prendre une photo de soi-même via la webcam et une photo de notre pièce d&apos;identité, cela enclenchera la vérification par un instructeur.&lt;br&gt;
La vérification dans mon cas n&apos;a pas duré très longtemps, cela effectué l&apos;instructeur demandera de filmer la pièce afin de vérifier que tout est ok et qu&apos;il n&apos;y a rien d&apos;interdit à proximité.&lt;br&gt;
Dans mon cas on m&apos;a demandé de poser mon téléphone dans le champ de la caméra mais hors de portée et d&apos;enlever le plastique de ma bouteille d&apos;eau !
Lorsque toutes ces vérifications sont terminées on peut enfin commencer l&apos;examen ! Comme vu précédemment l&apos;environnement est exactement le même que killer.sh mais en plus simple.&lt;br&gt;
A part un ou deux écueils je n&apos;ai pas trouvé l&apos;examen très complexe.&lt;/p&gt;
&lt;p&gt;On obtient le résultat au bout de 24h max, pour moi j&apos;ai réussi à l&apos;obtenir avec 83% donc ça passe 🙂&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Je doutais un peu que la certification m&apos;apporte réellement quelque chose mais finalement afin de l&apos;obtenir je me suis vraiment investi et cela m&apos;a apporté des connaissances théoriques sur la techno.&lt;br&gt;
Cela me donne un véritable vernis de base lorsqu&apos;il sera question de Kubernetes.&lt;/p&gt;
&lt;p&gt;Ceci dit cela ne remplacera jamais l&apos;expérience &quot;sur le terrain&quot; selon moi et la certification ne vient qu&apos;en complément. J&apos;ai donc hâte de pouvoir mettre en pratique les connaissances acquises ! 🤞&lt;/p&gt;</content:encoded><author>Beerus Inc.</author></item><item><title><![CDATA[Déployer son infra K3S sur Proxmox en mode IaC]]></title><description><![CDATA[Architecture Je suis en train de préparer la Certified Kubernetes Administrator (CKA) et il me faudrait un lab pour m'exercer. J'ai pas mal fait de Kubernetes classique en lab via…]]></description><link>https://blog.beerus.fr/deploy-k3s-proxmox</link><guid isPermaLink="false">https://blog.beerus.fr/deploy-k3s-proxmox</guid><category><![CDATA[k3s]]></category><category><![CDATA[hashicorp]]></category><category><![CDATA[packer]]></category><category><![CDATA[terraform]]></category><category><![CDATA[proxmox]]></category><pubDate>Tue, 19 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;architecture&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#architecture&quot; aria-label=&quot;architecture permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Architecture&lt;/h1&gt;
&lt;p&gt;Je suis en train de préparer la Certified Kubernetes Administrator (CKA) et il me faudrait un lab pour m&apos;exercer. J&apos;ai pas mal fait de Kubernetes classique en lab via des formations Udemy et j&apos;aimerai tester autre chose mais toujours sur une base K8S.
Je me suis penché sur K3S de Rancher. Il dispose de plusieurs qualités qui me semble intéressantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est léger et plus rapide que K8s&lt;/li&gt;
&lt;li&gt;Il peut s&apos;exécuter sur du plus petit matériel (proc ARM par ex 🥰). J&apos;ai comme projet potentiel de faire un cluster de raspberry donc K3S est plus qu&apos;indiqué.&lt;/li&gt;
&lt;li&gt;Il ne dispose pas de tous les connecteurs cloud mais vu que ça sera du &quot;on premise&quot; dans mon cas c&apos;est parfait.&lt;/li&gt;
&lt;li&gt;Plein de petits avantages : + facile et rapide à déployer, moins de surface d&apos;attaque, facile à update etc...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par contre il ne fait pas tourner docker nativement mais containerd (bien que j&apos;ai vu un projet passer s&apos;appelant k3d qui intègre docker), ça sera l&apos;occasion d&apos;apprendre autre chose surtout que le CRI (Container Runtime Interface) en soi n&apos;est pas le plus important.&lt;/p&gt;
&lt;p&gt;Une fois mon choix d&apos;orchestrateur choisi je me suis dit que j&apos;allais installer mon cluster K3s sur mon lab maison qui exécute un Proxmox et tant qu&apos;à faire autant avoir un workflow de déploiement un peu évolué pour s&apos;exercer.&lt;/p&gt;
&lt;p&gt;Parmi toutes les ressources que j&apos;ai pu voir le workflow qui me semblait au départ le plus intéressant faisait les choses suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Récupération de l&apos;ISO Ubuntu 20 sur Proxmox&lt;/li&gt;
&lt;li&gt;Création du template Proxmox &quot;à la main&quot; via des commandes qm (cli proxmox)&lt;/li&gt;
&lt;li&gt;Configuration de cloud init via l&apos;onglet promox dédié&lt;/li&gt;
&lt;li&gt;Création des VM via Terraform&lt;/li&gt;
&lt;li&gt;Ansible pour déployer K3s sur mes nouvelles VM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cela paraissait sympa sur le papier et puis ça permettait de mettre en application les quelques connaissances Terraform dont je disposais.
Mais à bien réfléchir il y avait quand même deux problèmes dans ce process :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une partie manuelle qui cassait un peu l&apos;automatisation voulue. Si je pouvais automatiser cela je serais vraiment dans un cas d&apos;IaC (&lt;strong&gt;Infra As Code&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Pas très flexible car si je veux customiser mon template ça sera à la main aussi ou à la limite via script bash&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&apos;est là que je suis tombé sur un autre outil d&apos;Hashicorp qui fait tout ce travail manuel pour moi et dispose de la flexibilité voulue : Packer !&lt;/p&gt;
&lt;p&gt;&lt;/br&gt;Voici les deux workflows qui sont ressortis au final :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Création du template --&gt; Cloud init --&gt; Terraform --&gt; Ansible --&gt; K3S&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Packer (+Cloud init) --&gt; Terraform --&gt; Ansible --&gt; K3S&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&apos;ai donc choisi le deuxième worflow&lt;br&gt;
Avantages :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Infra as code - Full automatisée&lt;/li&gt;
&lt;li&gt;Pas d&apos;interaction directe avec Proxmox, seulement via son API&lt;/li&gt;
&lt;li&gt;Peut donc être piloté depuis une machine tierce&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;⚠️ Inconvénients :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nécessite plus de développement et de temps pour un résultat équivalent dans mon cas (installation d&apos;un potentiel DHCP, création du fichier de conf packer etc...)&lt;/li&gt;
&lt;li&gt;Temps d&apos;exécution de création du template plus long&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Retrouver l&apos;ensemble du projet sur ce git : &lt;a href=&quot;https://github.com/ramuskay/k3s-proxmox-terraform-ansible-packer&quot;&gt;https://github.com/ramuskay/k3s-proxmox-terraform-ansible-packer&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;packer&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#packer&quot; aria-label=&quot;packer permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Packer&lt;/h1&gt;
&lt;p&gt;Je vais donc utiliser packer pour packager mon image Ubuntu 20.04 avec quelques packages et confs additionnelles. Il suffit d&apos;installer &lt;a href=&quot;https://www.packer.io/downloads&quot;&gt;packer&lt;/a&gt; puis nous verrons les fichiers de configuration.&lt;br&gt;
D&apos;ailleurs dans mon cas pas besoin de DHCP, celui de ma box avec ma VM template en mode bridge sera largement suffisant.&lt;br&gt;
Voici mon arborescence packer pour la config :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;├── http
│   ├── meta-data
│   └── user-data
├── ubuntu20.pkr.hcl
└── variables.pkr.hcl&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Les fichiers de conf peuvent être en json ou HCL (format hashicorp), j&apos;ai choisi HCL à la place de JSON pour deux raisons :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Langage commun avec tous les outils HashiCorp (vu qu&apos;on va aussi utiliser Terraform ça a du sens)&lt;/li&gt;
&lt;li&gt;Plus &quot;fonctionnel&quot;, on peut par exemple mettre des commentaires (dans JSON non ça fera toujours partie de la data)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On a donc 2 fichiers hcl concernant :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;variables.pkr.hcl&lt;/code&gt; : la définition des variables par défaut&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ubuntu20.pkr.hcl&lt;/code&gt; : la définition du job packer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regardons plus en détail &lt;code class=&quot;language-text&quot;&gt;ubuntu20.pkr.hcl&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ruby line-numbers&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;source &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;proxmox&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;template&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  proxmox_url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${var.proxmox_hostname}/api2/json&quot;&lt;/span&gt;&lt;/span&gt;
  username &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proxmox_username
  password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proxmox_password
  node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proxmox_node_name
  insecure_skip_tls_verify &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proxmox_insecure_skip_tls_verify
  network_adapters &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    bridge &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;vmbr0&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  disks &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scsi&quot;&lt;/span&gt;&lt;/span&gt;
    disk_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;20G&quot;&lt;/span&gt;&lt;/span&gt;
    storage_pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_storage_pool
    storage_pool_type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;lvm&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;#iso_file = &quot;local:iso/ubuntu-20.04.4-live-server-amd64.iso&quot;&lt;/span&gt;
  iso_url               &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_url
  iso_storage_pool      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_storage_pool
  iso_checksum          &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_checksum
  unmount_iso &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  boot_wait &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5s&quot;&lt;/span&gt;&lt;/span&gt;
  memory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_memory
  sockets   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_sockets
  cores     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_cores
  template_name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_name
  vm_id     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_id
  http_directory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;http_directory
  cloud_init &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  cloud_init_storage_pool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_storage_pool
  boot_command &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;esc&gt;&amp;lt;wait&gt;&amp;lt;esc&gt;&amp;lt;wait&gt;&amp;lt;f6&gt;&amp;lt;wait&gt;&amp;lt;esc&gt;&amp;lt;wait&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;bs&gt;&amp;lt;bs&gt;&amp;lt;bs&gt;&amp;lt;bs&gt;&amp;lt;bs&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ &quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;--- &amp;lt;enter&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  ssh_username &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username
  ssh_password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_password
  ssh_timeout &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;20m&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

build &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;source.proxmox.template&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  provisioner &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;shell&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    inline &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sudo rm -f /etc/cloud/cloud.cfg.d/99-installer.cfg&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sudo rm -f /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sudo cloud-init clean&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rien de bien compliqué là-dedans c&apos;est aussi l&apos;avantage en général des outils Hashicorp la configuration est très descriptive et donc compréhensible rapidement.
On va renseigner les informations suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Des credentials pour le proxmox&lt;/li&gt;
&lt;li&gt;Un peu de hardware pour le template (RAM, CPU, Disk etc...)&lt;/li&gt;
&lt;li&gt;Une config pour le template (ID, nom, boot command , ssh cred etc...)&lt;/li&gt;
&lt;li&gt;Un dossier pour la conf subiquity&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On active cloud-init car sinon on ne peut pas set les IP via Terraform&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;On tweak un peu l&apos;image car on veut qu&apos;elle soit cloud-init ready&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Justement concernant autoinstall depuis la version 20.04 preseed a été délaissé au profit de subiquity qui est (de mon point de vue) bien plus facile à utiliser car format yaml et s&apos;intègre très bien avec Packer. Ce qui donne deux fichiers :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;meta-data&lt;/code&gt; : requis. Utilisé par le cloud vu qu&apos;on déploit en local on le laisse vide&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt; : l&apos;équivalent du preseed, utilise autoinstall&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le fichier &lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt; en détail :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yml line-numbers&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#cloud-config&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;autoinstall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;locale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; en_US
  &lt;span class=&quot;token key atrule&quot;&gt;keyboard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fr
  &lt;span class=&quot;token key atrule&quot;&gt;ssh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;install-server&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;allow-pw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; qemu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;guest&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;agent
  &lt;span class=&quot;token key atrule&quot;&gt;user-data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; canadium
          &lt;span class=&quot;token key atrule&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0
          &lt;span class=&quot;token key atrule&quot;&gt;groups&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;adm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cdrom&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; plugdev&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sudo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;lock-passwd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ALL=(ALL) NOPASSWD&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;ALL
          &lt;span class=&quot;token key atrule&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /bin/bash
          &lt;span class=&quot;token key atrule&quot;&gt;ssh_authorized_keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ssh&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEXrwiuUOCpWPvwOsGuF4K+aq1ufToGMi4ra/1omOZb&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fichier de configuration ultra basique, on définit un seul user et deux confs pour le système. Les autres options peuvent être trouvées dans la &lt;a href=&quot;https://ubuntu.com/server/docs/install/autoinstall-reference&quot;&gt;doc&lt;/a&gt;&lt;br&gt;
⚠️ Ce fichier est &quot;templatiser&quot; et redéfini via Terraform voir plus bas&lt;/p&gt;
&lt;p&gt;On peut ensuite exécuter packer via Terraform pour avoir une seule et même exécution&lt;br&gt;
Ce qui nous donne un template de qualité !
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cc6a97ebfa97429c534052f94c048994/d8a90/template-proxmox.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 44.131455399061025%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA20lEQVQoz5WQy26DMBRE/f+/1nV3lNC4bkgwL2NjHoapxhKIRdSEkUawuPd45oqLzJGpB+73AnVZoqkbFEUB33tQ67qesvj4/EJyq9FPAXNYopdlQQgB0zRhnueX3ua4I26/Cs4adK7HjzbQTYfBe/gTHoZh/4o0TaHLEuM4Ql6/Ybtur/qumIxnYlKhlELbtpF+yTIYY3bYOzejeCLus7ZIkgRa60jnv5QyvngGyLoMxpYiz3NUVRXp22vHhP/pOMc9WpDunIsJnw2/0nEuAq21oDfgscqZhBvwD9YwwWrhe2wrAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;template proxmox&quot;
        title=&quot;template proxmox&quot;
        src=&quot;/static/cc6a97ebfa97429c534052f94c048994/d6170/template-proxmox.png&quot;
        srcset=&quot;/static/cc6a97ebfa97429c534052f94c048994/53f68/template-proxmox.png 213w,
/static/cc6a97ebfa97429c534052f94c048994/df70d/template-proxmox.png 425w,
/static/cc6a97ebfa97429c534052f94c048994/d6170/template-proxmox.png 850w,
/static/cc6a97ebfa97429c534052f94c048994/d8a90/template-proxmox.png 920w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;terraform&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#terraform&quot; aria-label=&quot;terraform permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Terraform&lt;/h1&gt;
&lt;p&gt;Il faut maintenant déployer notre template sous forme de VM, on va utiliser Terraform pour qui sera notre outil principal. &lt;strong&gt;Tout&lt;/strong&gt; passera par Terraform :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La création de fichier de conf pour Packer, Ansible et Terraform&lt;/li&gt;
&lt;li&gt;L&apos;exécution de Packer&lt;/li&gt;
&lt;li&gt;L&apos;exécution de Terraform bien sûr&lt;/li&gt;
&lt;li&gt;L&apos;exécution d&apos;Ansible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On installe &lt;a href=&quot;https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started&quot;&gt;Terraform&lt;/a&gt; puis on s&apos;attaque aux fichiers de configuration :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;├── main.tf
├── output.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Listons les fichiers Terraform :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;main.tf&lt;/code&gt; : On décrit notre déploiement, le fichier de job.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;output.tf&lt;/code&gt; : La sortie voulue lors de l&apos;exécution de Terraform apply (on va print les IP ici)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;provider.tf&lt;/code&gt; : On précise quel provider on utilise, ici proxmox. (voir &lt;a href=&quot;https://registry.terraform.io/providers/Telmate/proxmox/latest/docs&quot;&gt;doc&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;terraform.tfvars&lt;/code&gt; : la définition des variables pour le main.tf (même principe que Packer)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;variables.tf&lt;/code&gt; : la définition des variables par défaut (même principe que Packer)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et on a des fichiers de template qui vont nous permettre de définir notre inventory ansible, groups_vars ansible, user-data de autoinstall etc...&lt;/p&gt;
&lt;p&gt;Je vais juste décrire le fichier main.tf car les autres sont plutôt évident.
On définit les variables pour l&apos;exécution future de packer :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ruby line-numbers&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;locals &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  template_folder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${path.module}/${var.folder_packer}/${var.distrib_folder}&quot;&lt;/span&gt;&lt;/span&gt;
  packer_cfg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    PKR_VAR_proxmox_hostname  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pm_host
    PKR_VAR_proxmox_username  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pm_user
    PKR_VAR_proxmox_password  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pm_password
    PKR_VAR_proxmox_node_name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pm_node_name
    PKR_VAR_proxmox_insecure_skip_tls_verify &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pm_tls_insecure

    PKR_VAR_vm_id                 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_id
    PKR_VAR_vm_name               &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_name
    PKR_VAR_vm_storage_pool       &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_storage_pool
    PKR_VAR_vm_cores              &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_cores
    PKR_VAR_vm_memory             &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_memory
    PKR_VAR_vm_sockets            &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vm_sockets

    PKR_VAR_iso_url             &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_url
    PKR_VAR_iso_storage_pool    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_storage_pool
    PKR_VAR_iso_checksum        &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iso_checksum

    PKR_VAR_http_directory      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;http_directory

    PKR_VAR_username              &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username
    PKR_VAR_user_password         &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_password
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ici justement on définit le job packer avec l&apos;ensemble des paramètres souhaités (au final c&apos;est une exécution shell classique).&lt;br&gt;
J&apos;ai ajouté un petit sleep car parfois le template n&apos;était pas prêt pour l&apos;exécution Terraform. Également un script python pour supprimer le template créé par Packer (pas de ressource native donc obligé de &quot;hack&quot;) :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ruby line-numbers&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;resource &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;null_resource&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;packer_build&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    provisioner &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local-exec&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    working_dir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; local&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;template_folder
    command     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;packer build . &amp;amp;&amp;amp; sleep 30&quot;&lt;/span&gt;&lt;/span&gt;
    environment &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; local&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;packer_cfg
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  provisioner &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local-exec&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; destroy
    command &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${path.module}/scripts/delete_template.py&quot;&lt;/span&gt;&lt;/span&gt;
    interpreter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;python&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    working_dir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;environment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; merge&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;yamldecode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;triggers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;packer_cfg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    triggers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    packer_cfg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; yamlencode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;local&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;packer_cfg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  depends_on &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    local_file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;data
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On redéfinit un master K3S par-dessus notre template (var.tamplate_vm_name), on remarque qu&apos;on doit préciser une dépendance pour que les tâches s&apos;exécutent dans le bon ordre. A noter aussi un script sh qui vérifiera que le déploiement cloud-init est bien fini sur le serveur :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ruby line-numbers&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;resource &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;proxmox_vm_qemu&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;proxmox_vm_master&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  count       &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_k3s_masters
  name        &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;k3s-master-${count.index}&quot;&lt;/span&gt;&lt;/span&gt;
  target_node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pm_node_name
  clone       &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;template_vm_name
  os_type     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cloud-init&quot;&lt;/span&gt;&lt;/span&gt;
  agent       &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  memory      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_k3s_masters_mem
  cores       &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_k3s_masters_cpu

  ipconfig0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ip=${var.master_ips[count.index]}/${var.networkrange},gw=${var.gateway}&quot;&lt;/span&gt;&lt;/span&gt;

  lifecycle &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ignore_changes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      ciuser&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      sshkeys&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      disk&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      desc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      network
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  connection &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ssh&quot;&lt;/span&gt;&lt;/span&gt;
    user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;username
    password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_password
    host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; var&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;worker_ips&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  provisioner &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    source      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${path.module}/scripts/wait-cloud-init.sh&quot;&lt;/span&gt;&lt;/span&gt;
    destination &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/tmp/wait-cloud-init.sh&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  provisioner &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;remote-exec&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    inline &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;chmod +x /tmp/wait-cloud-init.sh&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/tmp/wait-cloud-init.sh&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  depends_on &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    null_resource&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;packer_build
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On fera la même tâche pour les workers&lt;/p&gt;
&lt;p&gt;Et ici on définit nos tâches de customisation de conf, c&apos;est à dire :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Générer des fichiers de configuration pour la future exécution d&apos;ansible&lt;/li&gt;
&lt;li&gt;Générer le user-data nécessaire à l&apos;autoinstall de packer (on modifie essentiellement le user/password)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ruby line-numbers&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;data &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;template_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cloud-init-user-data&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    template &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${file(&quot;&lt;/span&gt;&lt;/span&gt;$&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;templates&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;user&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tpl&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;)}&quot;&lt;/span&gt;&lt;/span&gt;
    vars &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;SUDO_PASSWORD_HASH&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${var.user_password_hash}&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;SUDO_USERNAME&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${var.username}&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;SSH_PUBLIC_KEY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${var.ssh_pub_key}&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
resource &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user-data&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${data.template_file.cloud-init-user-data.rendered}&quot;&lt;/span&gt;&lt;/span&gt;
    filename &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${local.template_folder}/http/user-data&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

data &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;template_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;k8s&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  template &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./templates/k8s.tpl&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  vars &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    k3s_master_ip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${join(&quot;&lt;/span&gt;&lt;/span&gt;\n&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;, [for instance in proxmox_vm_qemu.proxmox_vm_master : join(&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;, [instance.default_ipv4_address, &quot;&lt;/span&gt;&lt;/span&gt; ansible_ssh_private_key_file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;, var.pvt_key])])}&quot;&lt;/span&gt;&lt;/span&gt;
    k3s_node_ip   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${join(&quot;&lt;/span&gt;&lt;/span&gt;\n&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;, [for instance in proxmox_vm_qemu.proxmox_vm_workers : join(&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;, [instance.default_ipv4_address, &quot;&lt;/span&gt;&lt;/span&gt; ansible_ssh_private_key_file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;, var.pvt_key])])}&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

resource &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;k8s_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  content  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;template_file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;k8s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rendered
  filename &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${path.module}/ansible/hosts&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

data &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;template_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;groups_vars_ansible&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    template &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${file(&quot;&lt;/span&gt;&lt;/span&gt;$&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;templates&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;all&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tpl&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;)}&quot;&lt;/span&gt;&lt;/span&gt;
    vars &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;ANSIBLE_USER&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${var.username}&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;K3S_VERSION&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${var.k3s_version}&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

resource &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local_file&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;groups_vars_ansible&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${data.template_file.groups_vars_ansible.rendered}&quot;&lt;/span&gt;&lt;/span&gt;
    filename &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;${path.module}/ansible/group_vars/all.yml&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Et enfin le job ansible :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-ruby line-numbers&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;resource &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;null_resource&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ansible-playbook&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  provisioner &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local-exec&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    command &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ansible-playbook -i ${var.inventory_file}  --private-key ${var.ssh_key_file} site.yml&quot;&lt;/span&gt;&lt;/span&gt;
    working_dir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;..&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  depends_on &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    proxmox_vm_qemu&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proxmox_vm_workers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    proxmox_vm_qemu&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proxmox_vm_master&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    local_file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;k8s_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    local_file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;var_file
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;ansible&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#ansible&quot; aria-label=&quot;ansible permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Ansible&lt;/h1&gt;
&lt;p&gt;Le cluster K3S est déployer via ansible. En voici l&apos;arborescence :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ansible/
├── ansible.cfg
├── group_vars
│   └── all.yml
├── playbook.yml
└── roles
    ├── download
    │   └── tasks
    │       └── main.yml
    ├── k3s
    │   ├── master
    │   │   ├── tasks
    │   │   │   └── main.yml
    │   │   └── templates
    │   │       ├── k3s.service.j2
    │   │       └── k3s.service.j2.withoutterafic
    │   └── node
    │       ├── tasks
    │       │   └── main.yml
    │       └── templates
    │           └── k3s.service.j2
    ├── postconfig
    │   └── localhost
    │       └── tasks
    │           └── main.yml
    ├── prereq
    │   ├── defaults
    │   │   └── main.yml
    │   ├── tasks
    │   │   └── main.yml
    │   └── templates
    │       └── resolv.conf.j2
    ├── raspberrypi
    │   ├── handlers
    │   │   └── main.yml
    │   └── tasks
    │       ├── main.yml
    │       └── prereq
    │           ├── CentOS.yml
    │           ├── Raspbian.yml
    │           ├── Ubuntu.yml
    │           └── default.yml&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Voici les différents roles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;download&lt;/code&gt; : Télécharge la release de k3s&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;k3s&lt;/code&gt; : La configuration de k3s pour le master et les nodes (rien de bien compliqué)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;postconfig&lt;/code&gt; : On configure kubeconfig et installe helm en local sur le server/workstation exécutant le job ansible&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;prereq&lt;/code&gt; : On installe les prérequis K3S (netfilter, ip forwarding etc...)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;raspberrypi&lt;/code&gt; : Un job spécifique si on est sous Raspberry PI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A noter :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le fichier de group vars all.yml est généré via Terraform à partir de variables&lt;/li&gt;
&lt;li&gt;Le fichier ansible.cfg peut être configurer à votre convenance&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;On a donc créé un cluster K3s de 0 sans aucune interaction directe ou manuelle avec Proxmox, pas mal non ? En plus de cela tous est dynamique et flexible, il suffit de changer les conf 😉&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 193px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f2380d33d87d2b65cfee893b785bb6fb/aadfe/final_promox.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 76.6839378238342%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACoUlEQVQoz3VSbW/SYBTlX/vBLDOa+MVopnExcXO6mC0z0w9uTgaMlwItdGPr6BsUWkpfaRkFWtpC357HwDajZp7c3NwPz7nn5pwnBSEo5XN7+1+GI+uihiEllKQolqTq2HmjcXVzY0EIAQDwIaQgBDTZrFaxMAgNSea4jqwomixriq5quuf5SzJ8GKnbrXPP/bD9nhqIcRyPhqY5MGVZNTRdVZSZN/+f+JIMIBzqyuPnj9bpLWmg41i1XCzn8shlvY6j6I3tQgiT1TMA4F1fDanbHQCAJI5iED10HbgrkNzP98qM4TGDZbXMOa0555xBig6lz0jVoXWXGXisOedGYXcc85OEs6KOFbMDjzF8xvBSha5d6Np5blqR5jvH2JOdTy/rZ3s5+sX20UGBePut9Oag8DlPvDvMvdrLbOxnt75XNg8LH0+biOilMNHBRAft2bg6/4G21jZf7/LnaNfOUxrSNk+JfvZaKbbMLNE7xjsZon9GKnlKzTTVWn+WCqIkiJJFGAMIBbFfubhoioIk6XX8QhB6bIenWrw2MHhJ43tik2I10+oI/dF4GoN7w5IkgRAKDLO+sfZ1VPAmHk2RmtTrdLsCL0hSnybJbrtNNK5kRTUNw7JGq6hW9iWrGMcTSxRFazR1bEfXNHu6xHg8jeMojpNFsHBdNwgCwxwGQQDh38pUo/F089mufGLIZgVBOIau4TiK4hTVLJUQrFJJn6Svr+kaWjOHJvwzZwih60zrl7gd+1EQ+r7vum4UJ0my/CBgGTIMwzAIgjAMF4vgX7I1HrE0y3cErIpmTo5+HqcZtoNWyhhSzJ4iVwTJUES5iOAYns7lfc/7TV5213PFntDmON+fz1zX833HtieTycQaO0sfHHs6dd2Z789t246i6BdNSiPdUxaiiwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;final promox&quot;
        title=&quot;final promox&quot;
        src=&quot;/static/f2380d33d87d2b65cfee893b785bb6fb/aadfe/final_promox.png&quot;
        srcset=&quot;/static/f2380d33d87d2b65cfee893b785bb6fb/aadfe/final_promox.png 193w&quot;
        sizes=&quot;(max-width: 193px) 100vw, 193px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Vous pouvez reprendre ce &lt;a href=&quot;https://github.com/ramuskay/k3s-proxmox-terraform-ansible-packer&quot;&gt;projet&lt;/a&gt; (qui lui-même est forké). Par rapport à son utilisation tout est expliqué dans le &lt;a href=&quot;https://github.com/ramuskay/k3s-proxmox-terraform-ansible-packer/blob/main/terraform/README.md&quot;&gt;README&lt;/a&gt;  et consiste principalement à changer des variables Terraform.&lt;/p&gt;
&lt;p&gt;Malgré tous cela il y a pas mal d&apos;axes d&apos;améliorations et problèmes inhérents à la solution choisie :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On pourrait mettre les variables sensibles dans Vault (Outil Hashicorp) et un git qui à chaque push redéploit une image packer.&lt;/li&gt;
&lt;li&gt;Il faudrait aussi créer les utilisateurs adaptés (Terraform &amp;#x26; Packer) avec les bons droits, voir ressource &lt;a href=&quot;https://registry.terraform.io/providers/Telmate/proxmox/latest/docs&quot;&gt;Terraform&lt;/a&gt; par exemple.&lt;/li&gt;
&lt;li&gt;Il faudrait que le job packer se termine au bon moment pour que le job Terraform ne se lance pas trop tôt (j&apos;ai un sleep 30 pour l&apos;instant)&lt;/li&gt;
&lt;li&gt;Pas de provider packer natif donc on doit &quot;tricher&quot; pour supprimer le template&lt;/li&gt;
&lt;li&gt;Terraform considère à un deuxième run que rien a changé et ne relance pas le job ansible (on peut tout de même le lancer à la main)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bref il y a plein d&apos;autres moyens de faire et d&apos;améliorer ce pipeline, les outils HashiCorp sont quand même super pour cela !&lt;/p&gt;
&lt;h1 id=&quot;sources&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#sources&quot; aria-label=&quot;sources permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Sources&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.aerialls.eu/posts/ubuntu-server-2004-image-packer-subiquity-for-proxmox/&quot;&gt;https://www.aerialls.eu/posts/ubuntu-server-2004-image-packer-subiquity-for-proxmox/&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://tlhakhan.medium.com/ubuntu-server-20-04-autoinstall-2e5f772b655a&quot;&gt;https://tlhakhan.medium.com/ubuntu-server-20-04-autoinstall-2e5f772b655a&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://stackoverflow.com/questions/72567455/running-cloud-init-twice-via-packer-terraform-on-vmware-ubuntu-22-04-guest&quot;&gt;https://stackoverflow.com/questions/72567455/running-cloud-init-twice-via-packer-terraform-on-vmware-ubuntu-22-04-guest&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://salmonsec.com/blogs/home_lab_3#6-init-kubeadm-images-sh&quot;&gt;https://salmonsec.com/blogs/home_lab_3#6-init-kubeadm-images-sh&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://github.com/blz-ea/proxmox-packer&quot;&gt;https://github.com/blz-ea/proxmox-packer&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://medium.com/@ssnetanel/build-a-kubernetes-cluster-using-k3s-on-proxmox-via-ansible-and-terraform-c97c7974d4a5&quot;&gt;https://medium.com/@ssnetanel/build-a-kubernetes-cluster-using-k3s-on-proxmox-via-ansible-and-terraform-c97c7974d4a5&lt;/a&gt;&lt;/p&gt;</content:encoded><author>Beerus Inc.</author></item><item><title><![CDATA[Créer mon propre blog !]]></title><description><![CDATA[Je cherchais une bonne solution pour monter mon propre blog. Au début j'ai forcément réfléchis à des CMS classique tel que : Wordpress Drupal Grav etc... Mais je désirais aussi…]]></description><link>https://blog.beerus.fr/creation-du-blog</link><guid isPermaLink="false">https://blog.beerus.fr/creation-du-blog</guid><category><![CDATA[gatsby]]></category><category><![CDATA[jamstack]]></category><category><![CDATA[blog]]></category><pubDate>Thu, 14 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Je cherchais une bonne solution pour monter mon propre blog. Au début j&apos;ai forcément réfléchis à des CMS classique tel que :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wordpress&lt;/li&gt;
&lt;li&gt;Drupal&lt;/li&gt;
&lt;li&gt;Grav etc...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mais je désirais aussi avoir quelque chose de simple si possible et facile d&apos;utilisation car contenu blogging (pas de difficulté particulière). Un CMS tel que wordpress nécessite une base de donnée que j&apos;aimerai éviter au maximum mon site n&apos;hébergeant que des pages statiques. Si on peut éviter le PHP aussi c&apos;est pas mal :) (toujours source de faille de sécu entre autres choses).&lt;/p&gt;
&lt;p&gt;C&apos;est là que j&apos;ai découvert JAMStack (JavaScript, APIs, and (HTML) Markup). Il build le site en amont et le met à disposition sur un CDN (ou n&apos;importe quel hoster) et en fait donc un site composé de pages statique ! Cela correspond totalement à mon besoin, on ajoute à ça quelques feature cool :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pas besoin de database&lt;/li&gt;
&lt;li&gt;Surface d&apos;attaque bien moins étendue, sécurité +++&lt;/li&gt;
&lt;li&gt;Meilleur référencement&lt;/li&gt;
&lt;li&gt;S’intègre super bien dans une pipeline CI/CD ou n&apos;importe quel process d&apos;automatisation (🤤)&lt;/li&gt;
&lt;li&gt;Apparemment bien plus rapide qu&apos;un CMS traditionnel (vu que c&apos;est des pages statiques je veux bien le croire)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plus d&apos;infos ici : &lt;a href=&quot;https://jamstack.org/&quot;&gt;https://jamstack.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le truc c&apos;est que JAMStack n&apos;embarque aucune techno par défaut c&apos;est au développeur de choisir comment l&apos;implémenter. Je cherchais vers quel générateur JAMStack j&apos;allais choisir, il en existe plusieurs sur le marché :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;Jekyll&lt;/li&gt;
&lt;li&gt;Gastby&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et je suis tombé sur le post de ce &lt;a href=&quot;https://calvin.me/now-powered-by-gatsby&quot;&gt;blog&lt;/a&gt; qui explique pourquoi et comment il est passé de Jekyll à Gatsby et son cas d&apos;usage correspond totalement au mien (et j&apos;adore le design de son blog !)&lt;/p&gt;
&lt;p&gt;J&apos;ai donc choisi les paramètres suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Redaction du code en local sur VS-Studio code (j&apos;ai les plugins preview markdown etc...)&lt;/li&gt;
&lt;li&gt;Je push une fois fini sur un de mes projets github&lt;/li&gt;
&lt;li&gt;Le push trigger un build GitHub action (workflow dans le projets) qui héberge mon blog sur GitHub Pages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dd1a8069019a549dbdb0c4805dfb3caf/ac7a9/gh-gatsby.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.33802816901409%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB2ElEQVQoz2P4DwN///79AwZ///799w8k8v3Lrzy7eSkG09NNZqabzko3nglCprPSjGdCEANE5z+Ichj49/cfWPNPmOZZ8VpTUwxnpBjOiNeemmaCpBmic/u2rcGBfsGBftu3bYUYAdVsOCNJb/qkvG1b55zdOvdcf9bWRJ2p6SYg+xn+/PkD1rklPDSovq66vq46PDRo29Yt//////Lxe4HDglj1yb0Zmy8eevDg2qs7F188uvlmSsH2OI3JGaazGP7+/fv////U5MS5c2ZBLJw/b05qcuL///+/fvqR7zA/TmPy9vnnj2+59ef3388ffrx6/PHA6qvxmlMQmvNystrbWiCaG+prsjPTwJq/FzjMj1GdtH3euU0zzuxafPHNs0/b5p9fP+VkgvbUdLjms2fPBPn7XLt6dfeunTKSomfPnIZozrefH6c5pSF89cE1V3cvvnh8y83z++43hK0Cedt0FiLAzp8/++Tx49u3bp06eQI5wFINZyTqTqsNWrFm4vE1E45X+y9P1IUFGNaogjgHojnZYHq66axEnWlxGpPjNCYn6k6D6ERohmv49+/f379//qMmkjSTmekms0DpxHQWXCeKZpREAtNc5Lwww3RWtuWcLAssCAAlTMWd+RmHeQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;gh gatsby&quot;
        title=&quot;gh gatsby&quot;
        src=&quot;/static/dd1a8069019a549dbdb0c4805dfb3caf/d6170/gh-gatsby.png&quot;
        srcset=&quot;/static/dd1a8069019a549dbdb0c4805dfb3caf/53f68/gh-gatsby.png 213w,
/static/dd1a8069019a549dbdb0c4805dfb3caf/df70d/gh-gatsby.png 425w,
/static/dd1a8069019a549dbdb0c4805dfb3caf/d6170/gh-gatsby.png 850w,
/static/dd1a8069019a549dbdb0c4805dfb3caf/12c14/gh-gatsby.png 1275w,
/static/dd1a8069019a549dbdb0c4805dfb3caf/de891/gh-gatsby.png 1700w,
/static/dd1a8069019a549dbdb0c4805dfb3caf/ac7a9/gh-gatsby.png 1920w&quot;
        sizes=&quot;(max-width: 850px) 100vw, 850px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Plusieurs avantages :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mon blog est centralisé et versionné (une ancienne version de ce post décrivait l&apos;ancienne façon d&apos;héberger via GatsbyCloud héhé)&lt;/li&gt;
&lt;li&gt;Les utilisateurs peuvent collaborer sur les articles en soumettant un PR (dans les faits un simple edit du post sur GitHub)&lt;/li&gt;
&lt;li&gt;J&apos;avais hésité à l&apos;héberger sur l&apos;infra maison mais vu que tout est déjà publique aucun problème à le faire héberger par un tiers&lt;/li&gt;
&lt;li&gt;Tout passe par un seul hebergeur --&gt; Github&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et quelques inconvénients:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Je repose sur ce tiers pour le build et l&apos;exposition de mon blog (free version 25 build/jour)&lt;/li&gt;
&lt;li&gt;Pas facile d&apos;utilisation (même si sur ce cas là j&apos;ai forké le projet de &lt;a href=&quot;https://github.com/calvinbui/calvin.me&quot;&gt;calvin&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;</content:encoded><author>Beerus Inc.</author></item></channel></rss>