<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>AWS on The Cloud Optimist</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/tags/aws/</link>
        <description>Recent content in AWS on The Cloud Optimist</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>fr-FR</language>
        <lastBuildDate>Tue, 17 Feb 2026 07:30:00 +0100</lastBuildDate><atom:link href="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/tags/aws/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Le jour où j&#39;ai accidentellement supprimé une API, et ce que cela m&#39;a appris sur le DevOps</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2026/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/</link>
        <pubDate>Tue, 17 Feb 2026 07:30:00 +0100</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2026/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2026/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/deleted_api.png" alt="Featured image of post Le jour où j&#39;ai accidentellement supprimé une API, et ce que cela m&#39;a appris sur le DevOps" /&gt;&lt;p&gt;La journée du 4 avril 2024 avait bien commencé. Un petit café en main, un VS Code en plein ébullition, et de la douce musique électro dans les oreilles, tant de facteurs positifs qui ne pouvaient présager de la catastrophe à venir.&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, j&amp;rsquo;aimerai vous raconter comment une journée en apparence tranquille est devenue un moment marquant de ma carrière de DevOps !&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/calm_before_storm.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Le calme avant la tempête&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;incident&#34;&gt;&lt;a href=&#34;#incident&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Incident
&lt;/h1&gt;&lt;h2 id=&#34;le-contexte&#34;&gt;&lt;a href=&#34;#le-contexte&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le contexte
&lt;/h2&gt;&lt;p&gt;Je travaillais alors dans une équipe avec pour but de mettre à disposition une API Gateway globale sur AWS, avec plusieurs endpoints managés par différentes équipes. Concrètement, la mise en place de cette API Gateway était l&amp;rsquo;étape initiale du projet. Cela comprenait un record DNS qui pointait vers cette API, l&amp;rsquo;API Gateway elle-même, ainsi qu&amp;rsquo;un Cognito Authorizer configuré avec plusieurs clients.&lt;/p&gt;
&lt;p&gt;Une fois cette API prête, des équipes externes pouvaient alors déployer leurs propres endpoints sur cette API. Pour cela, une pipeline CI/CD était mise en place, et via CloudFormation, les endpoints se rattachaient directement à l&amp;rsquo;API déjà créée.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Je simplifie au maximum, si des détails techniques vous intéressent, n&amp;rsquo;hésitez pas à me contacter !&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;De mon côté, en plus d&amp;rsquo;être responsable de l&amp;rsquo;infrastrcture globale de l&amp;rsquo;API, il m&amp;rsquo;arrivait de travailler ou de troubleshooter certains services.&lt;/p&gt;
&lt;h2 id=&#34;le-début-du-drame&#34;&gt;&lt;a href=&#34;#le-d%c3%a9but-du-drame&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le début du drame
&lt;/h2&gt;&lt;p&gt;Si vous avez déjà travaillé avec CloudFormation, vous êtes peut-être familier avec le terme &lt;code&gt;UPDATE_ROLLBACK_FAILED&lt;/code&gt;. C&amp;rsquo;est ce qui arrive lorsque vous essayez de mettre à jour une stack CloudFormation, mais que celle-ci a rencontré un problème. Elle essaiera donc de faire un rollback. Mais si ce rollback n&amp;rsquo;aboutit pas, votre stack sera alors en &lt;code&gt;UPDATE_ROLLBACK_FAILED&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et ce &lt;code&gt;UPDATE_ROLLBACK_FAILED&lt;/code&gt; est bien embêtant, car vous ne pouvez plus relancer de déploiements tant que vous n&amp;rsquo;avez pas résolu le problème.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est exactement ce qui s&amp;rsquo;est passé ce fameux 4 avril 2024. Un de nos services s&amp;rsquo;est retrouvé dans cet état, et j&amp;rsquo;ai commencé à investiguer le pourquoi du comment.&lt;/p&gt;
&lt;p&gt;Après quelques minutes, j&amp;rsquo;ai constaté que le problème venait de la ressource API elle-même. Sans trop réfléchir, et dans une optique de débloquer le problème rapidement, je me suis rendu directement sur la console AWS, sur le service API Gateway. J&amp;rsquo;ai cherché la ressource en question, et me suis empressé de la supprimer.&lt;/p&gt;
&lt;p&gt;À ce moment précis, quelque chose de très étrange s&amp;rsquo;est produit. Un comportement inattendu qui m&amp;rsquo;a glacé le sang. Au lieu de me retrouver sur la même page, AWS m&amp;rsquo;a renvoyé sur la page principale du service API Gateway. Cette même page qui liste vos APIs disponibles, et qui affichait maintenant le nombre &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai ainsi réalisé que je n&amp;rsquo;avais pas supprimé la ressource API, mais bien l&amp;rsquo;API Gateway dans sa totalité.&lt;/p&gt;
&lt;h2 id=&#34;les-détails-dun-échec&#34;&gt;&lt;a href=&#34;#les-d%c3%a9tails-dun-%c3%a9chec&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Les détails d&amp;rsquo;un échec
&lt;/h2&gt;&lt;p&gt;Jamais je n&amp;rsquo;aurais pensé commettre une telle bêtise. Et j&amp;rsquo;imagine que vous lisant ces lignes, vous vous dites la même chose.&lt;/p&gt;
&lt;p&gt;Car pour se tromper, &lt;strong&gt;il fallait le faire !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Laissez-moi vous faire une reconstitution de la scène du crime. Voici ce que j&amp;rsquo;ai vu au moment où j&amp;rsquo;ai pris la décision de supprimer une ressource de l&amp;rsquo;API Gateway.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/api_gateway_view.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Vue de la ressource API Gateway&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Toute ressemblance avec une situation réelle est totalement fortuite&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Dans ma situation, sur quel bouton auriez-vous cliqué ? Facile ! Le bouton &lt;em&gt;Delete&lt;/em&gt; juste à droite de la ressource !&lt;/p&gt;
&lt;p&gt;Pour ma part (et je ne sais toujours pas ce qui m&amp;rsquo;a poussé à faire cela), j&amp;rsquo;ai préféré cliquer sur le bouton &lt;em&gt;API actions&lt;/em&gt;. Après tout, je voulais en effet faire une action !&lt;/p&gt;
&lt;p&gt;Et que se passe-t-il quand on clique sur ce bouton ?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/api_actions.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Menu déroulant du bouton API Actions&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Oula ! De suite, on voit que ce n&amp;rsquo;est pas du tout ce qu&amp;rsquo;on veut faire. Mais pensez-vous que cela m&amp;rsquo;a découragé ? Absolument pas ! J&amp;rsquo;étais venu pour supprimer une ressource, et quand j&amp;rsquo;ai vu le mot &lt;em&gt;Delete&lt;/em&gt;, je n&amp;rsquo;ai pas réfléchi plus longtemps ! J&amp;rsquo;aurais dû, car ainsi, j&amp;rsquo;aurais sûrement vu le mot &lt;em&gt;API&lt;/em&gt; juste à côté.&lt;/p&gt;
&lt;p&gt;Heureusement, nos amis de chez AWS ont pensé à tout ! Lorsque vous cliquez sur &lt;em&gt;Delete API&lt;/em&gt;, on va tout de même vous demander si vous êtes bel et bien certain de vouloir supprimer cette API. Un beau message s&amp;rsquo;affiche, vous indiquant le nom de l&amp;rsquo;API en question, et vous demandant de taper le mot &lt;em&gt;confirm&lt;/em&gt; pour valider cette opération.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/delete_api_dialog.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Demande de confirmation de suppression de l’API&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Tout ça, c&amp;rsquo;est bien beau, mais les ingénieurs d&amp;rsquo;AWS ont sous-estimé mon impatience. À ce moment-là, cette demande de confirmation n&amp;rsquo;était pas une mise en garde, mais un obstacle à mon but de supprimer ma ressource. Ni une ni deux, j&amp;rsquo;ai entré le mot &lt;em&gt;confirm&lt;/em&gt;, et validé l&amp;rsquo;opération.&lt;/p&gt;
&lt;p&gt;Voici donc la dernière chose que j&amp;rsquo;ai vue avant de finalement réaliser l&amp;rsquo;erreur que j&amp;rsquo;avais commise.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/the-day-i-accidentally-deleted-an-api-and-what-it-taught-me-about-devops/successfully_deleted_api.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;L’API a été supprimée avec succès&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Une vision d&amp;rsquo;horreur&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Je voulais absolument vous retracer ce petit parcours pour vous faire comprendre une chose : vous aurez beau mettre en place toutes les sécurités possibles, &lt;strong&gt;vous ne pourrez jamais rien faire contre un individu impatient&lt;/strong&gt;, car ce dernier ne saura pas lire vos avertissements.&lt;/p&gt;
&lt;p&gt;Alors, la prochaine fois que vous devrez faire une action somme toute inoffensive, prenez bien le temps de lire et de vous assurer que vous êtes bel et bien sur le bon chemin.&lt;/p&gt;
&lt;p&gt;Cela étant dit, passons maintenant à une étape cruciale : la résolution de cet incident !&lt;/p&gt;
&lt;h1 id=&#34;résolution&#34;&gt;&lt;a href=&#34;#r%c3%a9solution&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Résolution
&lt;/h1&gt;&lt;h2 id=&#34;le-déclic&#34;&gt;&lt;a href=&#34;#le-d%c3%a9clic&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le déclic
&lt;/h2&gt;&lt;p&gt;Revenons donc sur le moment du drame. Après avoir réalisé ce qui était arrivé, j&amp;rsquo;ai eu comme un électrochoc, un éclair de génie (aucune poudre blanche n&amp;rsquo;ayant pourtant été consommée). Je savais maintenant ce que je devais faire : résoudre l&amp;rsquo;incident, mais surtout, documenter les actions que j&amp;rsquo;allais entreprendre.&lt;/p&gt;
&lt;p&gt;Car quelques semaines plus tôt, je m&amp;rsquo;étais intéressé à &lt;a class=&#34;link&#34; href=&#34;https://about.gitlab.com/blog/postmortem-of-database-outage-of-january-31/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;l&amp;rsquo;incident GitLab de 2017&lt;/a&gt;, celui ayant interrompu le service pendant plusieurs heures, et résultant d&amp;rsquo;une perte de données pour certains utilisateurs. J&amp;rsquo;ai ainsi découvert le terme de &lt;strong&gt;Post-Morten&lt;/strong&gt;, et leur intérêt dans ce genre de situation. Mais je garde ça pour la prochaine section de cet article.&lt;/p&gt;
&lt;p&gt;En attendant, si vous êtes intéressés par ces sujets-là, je vous conseille la très bonne &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/@kevinfaang/videos&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;chaîne Youtube de Kevin Fang&lt;/a&gt; qui je le cite : &amp;ldquo;lit des postmortems et en fait des vidéos de piètre qualité&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;rollback-impact-et-communication&#34;&gt;&lt;a href=&#34;#rollback-impact-et-communication&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Rollback, impact, et communication
&lt;/h2&gt;&lt;p&gt;La première chose que je me suis dite, c&amp;rsquo;est qu&amp;rsquo;il était peut-être possible de faire une sorte de rollback directement depuis AWS, et d&amp;rsquo;ainsi réduire au maximum l&amp;rsquo;impact sur les utilisateurs. Si j&amp;rsquo;avais correctement lu le message d&amp;rsquo;avertissement plus haut, j&amp;rsquo;aurais tout de suite compris que cela était impossible (mais si je l&amp;rsquo;avais lu, je n&amp;rsquo;aurais de toute façon pas été dans cette situation).&lt;/p&gt;
&lt;p&gt;N&amp;rsquo;ayant aucun moyen rapide et simple de revenir en arrière, j&amp;rsquo;étais maintenant confiant que j&amp;rsquo;étais face à un véritable incident ayant un impact global. J&amp;rsquo;ai donc dans un premier temps pris soin de comprendre tous les impacts que cette suppression d&amp;rsquo;API allait avoir. Dans mon cas, non seulement l&amp;rsquo;API n&amp;rsquo;était plus disponible (merci Captain Obvious), mais en plus de cela, aucun nouveau déploiement n&amp;rsquo;était possible jusqu&amp;rsquo;à ce que l&amp;rsquo;API soit de nouveau opérationnelle.&lt;/p&gt;
&lt;p&gt;Finalement, j&amp;rsquo;ai fait en sorte d&amp;rsquo;avertir toute notre équipe interne de la situation. Ainsi, ils étaient au courant de l&amp;rsquo;incident en cours, et que j&amp;rsquo;étais en train de travailler à sa résolution.&lt;/p&gt;
&lt;h2 id=&#34;analyse-et-découverte-de-problèmes&#34;&gt;&lt;a href=&#34;#analyse-et-d%c3%a9couverte-de-probl%c3%a8mes&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Analyse et découverte de problèmes
&lt;/h2&gt;&lt;p&gt;Il était maintenant temps de se retrousser les manches et de trouver un moyen de redéployer cette API Gateway.&lt;/p&gt;
&lt;p&gt;En premier lieu, je me suis rendu dans le service CloudFormation, car j&amp;rsquo;avais souvenir que cette API avait été initialement déployée via ce service. J&amp;rsquo;ai d&amp;rsquo;abord essayé de mettre à jour la stack, en pensant que cela pourrait faire revenir ma chère API comme par magie.&lt;/p&gt;
&lt;p&gt;Évidemment, cela n&amp;rsquo;allait pas être aussi simple. La mise à jour de cette stack était maintenant impossible, car la suppression manuelle de l&amp;rsquo;API avait fait rentrer la stack dans un état &amp;ldquo;hybride&amp;rdquo; dont elle n&amp;rsquo;arrivait pas à se sortir.&lt;/p&gt;
&lt;p&gt;La mise à jour de cette stack étant impossible, la suite logique était de la supprimer afin de la déployer à nouveau proprement. Et c&amp;rsquo;est là que les ennuis ont commencé. Cette fameuse stack CloudFormation produisait plusieurs Outputs. &lt;strong&gt;Deux de ces outputs étaient nécessaires à toutes les stacks &amp;ldquo;enfants&amp;rdquo;&lt;/strong&gt; qui avaient jusqu&amp;rsquo;alors déployé leurs endpoints sur cette API. Ainsi, CloudFormation m&amp;rsquo;interdisait de supprimer ma stack, car elle pourrait impacter toutes les autres.&lt;/p&gt;
&lt;p&gt;Après plusieurs minutes de réflexion pour essayer de trouver d&amp;rsquo;autres alternatives, cette forte interdépendance m&amp;rsquo;amena à prendre une décision difficile : supprimer toutes les stacks &amp;ldquo;enfants&amp;rdquo; de CloudFormation, pour un total de 81 stacks.&lt;/p&gt;
&lt;p&gt;Pour couronner le tout, ces stacks &amp;ldquo;enfants&amp;rdquo; n&amp;rsquo;avaient pas de tags identifiables qui auraient pu nous permettre d&amp;rsquo;automatiser cette suppression. Heureusement, la plupart d&amp;rsquo;entre elles avaient un nom avec un préfixe reconnaissable, ce qui m&amp;rsquo;a permis de faire un bon coup de ménage sur la plupart d&amp;rsquo;entre elles.&lt;/p&gt;
&lt;p&gt;Je vous ai parlé &lt;strong&gt;d&amp;rsquo;interdépendances&lt;/strong&gt; ? Parce que ce n&amp;rsquo;est pas fini ! Certaines stacks avaient déployé des buckets S3. Et devinez quoi ? CloudFormation ne voudra pas supprimer votre stack, si votre bucket S3 n&amp;rsquo;est pas vide ! Et bien sûr, 14 stacks se sont retrouvées dans l&amp;rsquo;état &lt;code&gt;DELETE_FAILED&lt;/code&gt; à cause de cela. Heureusement, le problème se résout assez facilement : après avoir fait un backup de chaque bucket, il suffit de les vider et de relancer la suppression de la stack.&lt;/p&gt;
&lt;h2 id=&#34;déploiement-de-lapi--le-bout-du-tunnel-&#34;&gt;&lt;a href=&#34;#d%c3%a9ploiement-de-lapi--le-bout-du-tunnel-&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Déploiement de l&amp;rsquo;API : Le bout du tunnel ?
&lt;/h2&gt;&lt;p&gt;Étant venu à bout de toutes ces interdépendances, il était maintenant temps de supprimer la stack CloudFormation de l&amp;rsquo;API Gateway, et de la déployer à nouveau.&lt;/p&gt;
&lt;p&gt;La suppression se passa sans plus de problème (Dieu merci), mais évidemment, cela ne fût pas le cas pour sa création.&lt;/p&gt;
&lt;p&gt;Déjà, parlons de la stack elle-même. Un fichier YML existait dans un repo GitHub, mais &lt;strong&gt;celui-ci n&amp;rsquo;avait pas été mis à jour depuis des lustres&lt;/strong&gt;, et je savais que je ferais mieux d&amp;rsquo;utiliser la définition de la stack présente dans CloudFormation (et oui, je l&amp;rsquo;ai quand même gardée, pas fou le gars).&lt;/p&gt;
&lt;p&gt;Cette stack ne déployait pas uniquement l&amp;rsquo;API Gateway, mais plusieurs ressources AWS (je ne rentrerai pas dans les détails du pourquoi nous avions besoin de ces ressources dans cet article), dont des Lambdas. Ces dernières se basaient encore sur Python 3.7, version avec laquelle &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-deprecated&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;il était impossible de se servir pour créer de nouvelles Lambdas&lt;/a&gt;. Heureusement, un petit upgrade en Python 3.12 sera suffisant pour qu&amp;rsquo;AWS nous laisse tranquille.&lt;/p&gt;
&lt;p&gt;Et, à ma grande surprise, la stack se déployait maintenant sans souci !&lt;/p&gt;
&lt;p&gt;Mais je vous la fait courte, il restait encore du pain sur la planche ! En effet, il manquait à la stack CloudFormation plusieurs ressources critiques à la bonne exécution de notre API. Des ressources qui avaient été créées à la main dans AWS directement, faisant fi de toute bonne pratique d&amp;rsquo;Infrastructure as Code (&lt;em&gt;pleure en Terraform&lt;/em&gt;). Dans un souci de rétablissement du service le plus rapidement possible (on est DevOps, ou on ne l&amp;rsquo;est pas !), ces ressources seront donc créées une nouvelle fois à la main.&lt;/p&gt;
&lt;p&gt;Pour finir, plusieurs composants clés faisaient référence à l&amp;rsquo;ARN de l&amp;rsquo;ancienne API en dur. Il fallait ainsi faire tout un travail d&amp;rsquo;archéologie pour trouver tous les endroits où une mise à jour vers la nouvelle API s&amp;rsquo;imposait.&lt;/p&gt;
&lt;p&gt;Finalement, après plusieurs heures de troubleshooting, l&amp;rsquo;API était de nouveau opérationnelle, et les développeurs pouvaient à nouveau déployer leurs projets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cet incident aura démarré le 4 avril 2024 à 15h24 et se sera conclu le 5 avril 2024 à 08h46.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;post-mortem-et-lessons-learned&#34;&gt;&lt;a href=&#34;#post-mortem-et-lessons-learned&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Post-Mortem et Lessons Learned
&lt;/h1&gt;&lt;p&gt;Pendant cet incident, j&amp;rsquo;ai réalisé une prise de note intensive sur les actions menées. J&amp;rsquo;avais déjà entendu parler du principe de &lt;strong&gt;Post-Mortem&lt;/strong&gt;, et je pensais que cet incident serait le parfait candidat.&lt;/p&gt;
&lt;p&gt;Si vous ignorez le principe d&amp;rsquo;un Post-Mortem, il agit comme un document retraçant les étapes de résolution d&amp;rsquo;un incident, couvrant les impacts, et la root cause, mais surtout — et à mon sens le plus intéressant — comporte une section appellée &lt;strong&gt;Lessons Learned&lt;/strong&gt;. Cette section, si vous la prenez au sérieux, sera votre meilleure alliée pour construire une architecture plus robuste et plus durable.&lt;/p&gt;
&lt;p&gt;Concrètement, vous allez noter dans cette section trois points clés : ce qui s&amp;rsquo;est bien passé, ce qui s&amp;rsquo;est mal passé, et là où vous avez eu de la chance. Et surtout, &lt;strong&gt;soyez honnêtes&lt;/strong&gt; ! Même si certains points vous paraissent bêtes, ou vous font passer pour un incompétent (et je vous dis ça alors que j&amp;rsquo;ai manuellement supprimé une API, donc prenez-le avec légèreté), le but n&amp;rsquo;est pas de pointer du doigt (ce qu&amp;rsquo;on appelle aussi la blameless culture), mais de comprendre les failles dans notre système, afin de les améliorer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;« The cost of failure is education. » — Devin Carraway (&lt;a class=&#34;link&#34; href=&#34;https://sre.google/sre-book/postmortem-culture/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cela vous paraît peut-être encore un peu flou, alors laissez-moi vous montrer mes lessons learned de cet incident.&lt;/p&gt;
&lt;h2 id=&#34;what-went-well&#34;&gt;&lt;a href=&#34;#what-went-well&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;What went well
&lt;/h2&gt;&lt;p&gt;Pendant cet incident, &lt;strong&gt;deux choses se sont bien passées&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;abord, la résolution s&amp;rsquo;est faite par &lt;strong&gt;un membre de l&amp;rsquo;équipe qui connaissait en profondeur cette architecture&lt;/strong&gt;, ce qui a permis de comprendre rapidement ce qui devait être remis en place pour restaurer le service.&lt;/p&gt;
&lt;p&gt;Enfin, il y a eu &lt;strong&gt;une bonne communication tout au long de cet incident&lt;/strong&gt;. Lorsque le problème s&amp;rsquo;est présenté, il n&amp;rsquo;a pas essayé d&amp;rsquo;être dissimulé, et des mises à jour fréquentes ont été annoncées pour avertir de l&amp;rsquo;avancement de sa résolution. C&amp;rsquo;est un point très important, car non seulement vous donnez de la visibilité sur vos actions, mais par la communication, vous pouvez aussi acquérir des informations utiles à la résolution de votre incident (un collègue pourra par exemple vous pointer vers une documentation dont vous n&amp;rsquo;avez pas connaissance, ou vous donner un coup de main si nécessaire).&lt;/p&gt;
&lt;h2 id=&#34;what-went-wrong&#34;&gt;&lt;a href=&#34;#what-went-wrong&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;What went wrong
&lt;/h2&gt;&lt;p&gt;Ici, c&amp;rsquo;est la partie qui fait mal. Comme je vous l&amp;rsquo;ai dit, il faut ravaler sa fierté, et mettre en lumière tout ce qui aurait pu être mieux exécuté.&lt;/p&gt;
&lt;p&gt;Pour cet incident, &lt;strong&gt;quatre choses ne se sont pas bien passées&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour commencer, &lt;strong&gt;l&amp;rsquo;infrastrucutre de cette API n&amp;rsquo;était non seulement pas consolidée dans un seul et même fichier&lt;/strong&gt; (ou dossier), mais était en plus disséminée dans plusieurs repos GitHub. Il était ainsi très compliqué d&amp;rsquo;avoir une vue d&amp;rsquo;ensemble de ce qui était nécessaire au bon fonctionnement de cette API.&lt;/p&gt;
&lt;p&gt;Ensuite, un gros problème résidait dans ce qu&amp;rsquo;on appelle le &lt;strong&gt;drift&lt;/strong&gt;. Ce sont toutes les différences que vous avez entre votre infrastructure réelle, et votre infrastructure telle qu&amp;rsquo;elle est définie dans votre code. Idéalement, aucune modification manuelle ne doit avoit lieu, et tout doit passer par votre fichier d&amp;rsquo;Infrastructure as Code. Si cela avait était le cas, un simple redéploiement aurait permi une remise en service instantanée.&lt;/p&gt;
&lt;p&gt;Un autre problème résidait dans &lt;strong&gt;la forte interdépendance de toutes les ressources&lt;/strong&gt;. Beaucoup par exemple se basaient sur un output de la stack CloudFormation. Si vous enlevez cette stack, vous enlevez ainsi la possibilité de déployer la suite de votre infrastructure.&lt;/p&gt;
&lt;p&gt;Enfin, l&amp;rsquo;identification des ressources liées à notre infrastructure était difficile. &lt;strong&gt;Notre stack déployait les ressources sans aucun tag associé&lt;/strong&gt;, ce qui rendait compliqué la recherche de toutes les ressources nécessaires à notre API.&lt;/p&gt;
&lt;h2 id=&#34;where-we-got-lucky&#34;&gt;&lt;a href=&#34;#where-we-got-lucky&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Where we got lucky
&lt;/h2&gt;&lt;p&gt;Cette partie peut ressembler à du positif, mais il n&amp;rsquo;en est rien ! Car vous allez ici parler des élément qui se sont bien passés, mais UNIQUEMENT car vous avez eu de la chance. Comprenez qu&amp;rsquo;à tout moment, cela aurait pû être un autre point à mettre dans la catégorie &amp;ldquo;What went wrong&amp;rdquo;. Donc soyez heureux pour cette fois, mais ne baissez pas votre garde pour autant !&lt;/p&gt;
&lt;p&gt;Pour cet incident, &lt;strong&gt;trois choses se sont bien passées par chance&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, l&amp;rsquo;incident a été &lt;strong&gt;immédiatement identifié&lt;/strong&gt; (c&amp;rsquo;est au moins l&amp;rsquo;avantage quand on fait une boulette pareille). Mais cela aurait pû être bien pire ! Car si cette API avait été supprimée par tout autre moyen (un script d&amp;rsquo;automatisation par exemple), nous n&amp;rsquo;avions aucun monitoring en place capable de nous prévenir d&amp;rsquo;une telle chose.&lt;/p&gt;
&lt;p&gt;Ensuite, il se trouve que la personne qui a supprimé cette API avait une excellente connaissance du projet et de l&amp;rsquo;infrastructure (je parle de moi oui, il faut bien s&amp;rsquo;envoyer quelques fleurs). Cela a permis de très vite enchaîner sur la résolution de l&amp;rsquo;incident, mais cela aurait pu se passer autrement.&lt;/p&gt;
&lt;p&gt;Enfin, cette API était en fait &lt;strong&gt;notre API de dev&lt;/strong&gt;. L&amp;rsquo;API de prod, elle, allait très bien (détail que j&amp;rsquo;ai volontairement gardé pour la fin, il paraît que c&amp;rsquo;est du storytelling). Alors certes, l&amp;rsquo;impact fût minime, mais l&amp;rsquo;incident aurait tout de même pû arriver en production, avec les mêmes problématiques de remise en service. Et cela aurait pû coûter bien plus cher.&lt;/p&gt;
&lt;h2 id=&#34;préparer-le-futur&#34;&gt;&lt;a href=&#34;#pr%c3%a9parer-le-futur&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Préparer le futur
&lt;/h2&gt;&lt;p&gt;Maintenant que vous avez pu lister les problèmes rencontrés lors de la résolution de cet incident, en tant que bon DevOps, vous vous devez d&amp;rsquo;en tirer les leçons. Notez bien tout ce qui pourrait être amélioré, mais surtout, fixez-vous un plan ! Sinon, ce ne seront que de vastes phrases sans utilité.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;« Tout objectif sans plan n&amp;rsquo;est qu&amp;rsquo;un souhait. » — Antoine de Saint-Exupéry&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dans mon cas, les trois leçons clés ont été les suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Consolidation de l&amp;rsquo;Infrastructure as Code :&lt;/strong&gt; tout doit pouvoir être déployé en un clin d&amp;rsquo;oeil. C&amp;rsquo;est un chantier que je serai amené à compléter dans les mois qui suivirent (mais cette histoire, c&amp;rsquo;est pour une prochaine fois).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amélioration du monitoring et de l&amp;rsquo;alerting :&lt;/strong&gt; si cet incident devait de nouveau arriver, il nous faut être averti rapidement afin de réagir en vitesse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documentation plus claire et cohérente :&lt;/strong&gt; n&amp;rsquo;importe quel membre de l&amp;rsquo;équipe doit pouvoir faire face à un tel incident, et cela commence par une documentation fiable et compréhensible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Toutes ces leçons seront ensuite trackées en tant qu&amp;rsquo;issues GitHub, et je m&amp;rsquo;appliquerai à les compléter dans les mois qui suivirent (mais cette histoire, c&amp;rsquo;est pour une prochaine fois).&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion
&lt;/h1&gt;&lt;p&gt;Vous l&amp;rsquo;aurez compris, un accident ça arrive. L&amp;rsquo;essentiel est qu&amp;rsquo;il soit bénéfique pour vous, et l&amp;rsquo;ensemble de votre organisation. Servez-vous en comme d&amp;rsquo;une opportunité d&amp;rsquo;apprendre et de consolider des failles qui n&amp;rsquo;était jusqu&amp;rsquo;alors pas détectées (certaines entreprises s&amp;rsquo;amusent d&amp;rsquo;ailleurs même à &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Chaos_engineering&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;volontairement créer ce chaos&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Merci de m&amp;rsquo;avoir lu jusqu&amp;rsquo;au bout ! Je vous laisse ici, car j&amp;rsquo;ai d&amp;rsquo;autres infrastructures à supprimer !&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Comment migrer son State de Terraform Cloud vers AWS S3 ?</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/moving-away-from-terraform-cloud/</link>
        <pubDate>Wed, 17 Dec 2025 07:30:00 +0200</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/moving-away-from-terraform-cloud/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/moving-away-from-terraform-cloud/terraform.png" alt="Featured image of post Comment migrer son State de Terraform Cloud vers AWS S3 ?" /&gt;&lt;h1 id=&#34;introduction&#34;&gt;&lt;a href=&#34;#introduction&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Introduction
&lt;/h1&gt;&lt;p&gt;Quand j&amp;rsquo;ai commencé à utiliser Terraform (notamment pour &lt;a class=&#34;link&#34; href=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-i-automated-my-blog-to-the-cloud/&#34; &gt;le déploiement de mon blog&lt;/a&gt;), je me suis tourné vers l&amp;rsquo;utilisation de &lt;strong&gt;Terraform Cloud&lt;/strong&gt; (ce nom a ensuite été modifié en HCP Terraform).&lt;/p&gt;
&lt;h1 id=&#34;terraform-et-le-state&#34;&gt;&lt;a href=&#34;#terraform-et-le-state&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Terraform et le State
&lt;/h1&gt;&lt;p&gt;Si vous connaissez un peu Terraform, vous êtes sûrement familier avec le terme &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/state&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;em&gt;State&lt;/em&gt;&lt;/a&gt;, qui correspond en fait à l&amp;rsquo;état actuel de votre infrastructure, et qui permet à Terraform de savoir quelles modifications seront à prévoir si vous venez à modifier vos fichiers Terraform. Ce &lt;em&gt;State&lt;/em&gt; est représenté par un fichier : &lt;strong&gt;terraform.tfstate&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Par défaut, Terraform stocke ce fichier en local sur votre machine, mais recommande d&amp;rsquo;utiliser un &lt;em&gt;backend storage&lt;/em&gt; (comprenez : &amp;ldquo;stockez ce fichier ailleurs bon sang !&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Évidemment, Terraform vous propose en premier la solution HashiCorp : Terraform Cloud. En créant un compte, vous pourrez gratuitement utiliser leur backend pour stocker vos fichiers de state. C&amp;rsquo;est tout naturellement ce que j&amp;rsquo;ai fait il y a quelques années.&lt;/p&gt;
&lt;h1 id=&#34;la-fin-de-terraform-cloud&#34;&gt;&lt;a href=&#34;#la-fin-de-terraform-cloud&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;La fin de Terraform Cloud
&lt;/h1&gt;&lt;p&gt;Jusqu&amp;rsquo;à cette semaine, où j&amp;rsquo;ai reçu ce mail d&amp;rsquo;HashiCorp.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/moving-away-from-terraform-cloud/terraform-mail-free-plan-expiration.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Mail de Terraform annonçant la fin du plan Free de Terraform Cloud&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Aïe ! Il fallait s&amp;rsquo;en douter, toutes les bonnes choses ont une fin ! L&amp;rsquo;option gratuite de l&amp;rsquo;époque n&amp;rsquo;existera bientôt plus, et il me faut donc faire un choix : mettre à jour mon &amp;ldquo;plan&amp;rdquo; HashiCorp, ou aller stocker mes states ailleurs.&lt;/p&gt;
&lt;p&gt;En regardant de plus près &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/cloud-docs/overview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;leurs offres actuelles&lt;/a&gt;, HashiCorp propose encore une version gratuite, bien que limitée dans le nombre de ressources pouvant être déployées (500 aujourd&amp;rsquo;hui). C&amp;rsquo;est une offre assez généreuse, mais ne sachant pas comment celle-ci pourra évoluer, je prends la décision de déménager mes States une bonne fois pour toutes.&lt;/p&gt;
&lt;p&gt;Adieu, Terraform Cloud !&lt;/p&gt;
&lt;h1 id=&#34;une-alternative-pour-stocker-vos-states&#34;&gt;&lt;a href=&#34;#une-alternative-pour-stocker-vos-states&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Une alternative pour stocker vos states
&lt;/h1&gt;&lt;p&gt;Heureusement pour moi, il existe bien des moyens pour stocker son state Terraform, et ce grâce au &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/state/remote&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Remote State&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour faire simple, il suffit de dire à Terraform où sera stocké votre fichier de state. On utilise pour cela &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/backend&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;le block &lt;code&gt;backend&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il en existe une bonne poignée, mais possédant un compte AWS sur lequel je déploie toutes mes ressources, je me dirige tout naturellement vers le backend S3.&lt;/p&gt;
&lt;p&gt;Voici par exemple comment configurer un backend S3 avec Terraform.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;terraform&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;bucket&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;mybucket&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;path/to/my/key/terraform.tfstate&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;region&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;eu-west-1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Maintenant qu&amp;rsquo;une alternative a été trouvée, il est temps de passer à la migration !&lt;/p&gt;
&lt;h1 id=&#34;migration-du-state-vers-s3&#34;&gt;&lt;a href=&#34;#migration-du-state-vers-s3&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Migration du state vers S3
&lt;/h1&gt;&lt;p&gt;Je vais prendre en exemple la migration du state dont je me sers pour déployer ce blog.&lt;/p&gt;
&lt;p&gt;Actuellement, si on regarde &lt;a class=&#34;link&#34; href=&#34;https://github.com/antoinedelia/cloud-optimist/blob/4f8f95c177c490e3383c8b554e8d8ca4b3df249b/.github/workflows/main.yml#L28-L33&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;mon workflow GitHub Actions de déploiement&lt;/a&gt;, on voit que je m&amp;rsquo;authentifie avec un token à mon compte Terraform Cloud. Cette partie-là n&amp;rsquo;aura plus de raison d&amp;rsquo;exister (du  moins pour les credentials, il faudra toujours initialiser la CLI Terraform).&lt;/p&gt;
&lt;p&gt;Ensuite, il va falloir créer un bucket S3 qui contiendra les futurs fichiers de state.&lt;/p&gt;
&lt;p&gt;Enfin, il faudra rajouter un block &lt;code&gt;backend&lt;/code&gt; à mon projet afin d&amp;rsquo;indiquer à Terraform de ne plus utiliser Terraform Cloud, mais bien S3 lorsqu&amp;rsquo;il viendra utiliser le state.&lt;/p&gt;
&lt;p&gt;Attention, nous n&amp;rsquo;avons pas encore fini ! Car si je laisse ce bucket vide, la prochaine fois que j&amp;rsquo;essaierai de déployer mon blog, Terraform viendra se baser sur un state&amp;hellip; inexistant ! Et pensera donc qu&amp;rsquo;aucune ressource n&amp;rsquo;a encore été déployée sur mon compte AWS. Terraform essaiera ainsi de recréer des ressources déjà existantes.&lt;/p&gt;
&lt;p&gt;La dernière étape sera donc de récupérer le fichier de state de mon projet de blog, et de le déplacer dans mon bucket S3.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/moving-away-from-terraform-cloud/downloading_terraform_state.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Téléchargement du Terraform State dans Terraform Cloud&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Je dois ensuite m&amp;rsquo;assurer que les informations que j&amp;rsquo;ai fournies dans le block &lt;code&gt;backend&lt;/code&gt; correspondent bien à la réalité.&lt;/p&gt;
&lt;p&gt;Une fois tout cela prêt, il est temps de tester et de déployer tout ça !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai volontairement omis quelques étapes de cette migration (des variables de workspace à migrer, l&amp;rsquo;utilisation de GitHub Secrets pour le nom du bucket S3, l&amp;rsquo;ajout des credentials AWS dans la GitHub Actions, &amp;hellip;) pour rendre cet article plus concis. Si vous voulez en voir plus, rendez-vous dans la &lt;a class=&#34;link&#34; href=&#34;https://github.com/antoinedelia/cloud-optimist/pull/116&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Pull Request que j&amp;rsquo;ai ouverte&lt;/a&gt; pour réaliser cette migration.&lt;/p&gt;
&lt;p&gt;Si tout s&amp;rsquo;est passé comme prévu, vous devriez voir apparaitre la phrase &lt;code&gt;No changes. Your infrastructure matches the configuration.&lt;/code&gt; lors de votre &lt;code&gt;terraform plan&lt;/code&gt; !&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion
&lt;/h1&gt;&lt;p&gt;Il est toujours pénible de devoir réaliser des migrations sur des infrastructures qui sont déjà en place. Mais avec un peu de temps, et avec une bonne volonté, c&amp;rsquo;est le genre de tâche qui ne prend au final que quelques heures.&lt;/p&gt;
&lt;p&gt;Alors, n&amp;rsquo;attendez pas le dernier moment, et lancez-vous !&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Comment et pourquoi configurer AWS IAM Identity Center sur votre compte AWS</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-and-why-to-set-up-aws-iam-identity-center-on-your-aws-account/</link>
        <pubDate>Wed, 19 Nov 2025 07:30:00 +0200</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-and-why-to-set-up-aws-iam-identity-center-on-your-aws-account/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-and-why-to-set-up-aws-iam-identity-center-on-your-aws-account/iam-identity-center.jpg" alt="Featured image of post Comment et pourquoi configurer AWS IAM Identity Center sur votre compte AWS" /&gt;&lt;h1 id=&#34;introduction&#34;&gt;&lt;a href=&#34;#introduction&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Introduction
&lt;/h1&gt;&lt;p&gt;Si vous jonglez avec plusieurs comptes AWS, ou même un seul compte avec différents utilisateurs, vous savez à quel point la gestion des accès peut devenir un véritable casse-tête. Créer des utilisateurs IAM individuels dans chaque compte, gérer leurs permissions, s&amp;rsquo;assurer que tout le monde utilise le MFA&amp;hellip; Ouf, rien que d&amp;rsquo;y penser, ça peut donner des sueurs froides ! Et si je vous disais qu&amp;rsquo;il existe une solution élégante, centralisée et bien plus sécurisée pour gérer tout ça ? Mesdames et Messieurs, laissez-moi vous présenter &lt;strong&gt;IAM Identity Center&lt;/strong&gt; !&lt;/p&gt;
&lt;p&gt;Depuis que j&amp;rsquo;ai découvert et mis en place IAM Identity Center (que certains connaissent peut-être sous son ancien nom, AWS Single Sign-On ou AWS SSO), ma vie d&amp;rsquo;administrateur Cloud a radicalement changé. C&amp;rsquo;est le genre d&amp;rsquo;outil qui, une fois adopté, vous fait vous demander comment vous avez pu vivre sans.&lt;/p&gt;
&lt;p&gt;Alors, qu&amp;rsquo;est-ce que c&amp;rsquo;est exactement, et pourquoi est-ce si génial ? C&amp;rsquo;est ce qu&amp;rsquo;on va voir ensemble.&lt;/p&gt;
&lt;h1 id=&#34;iam-identity-center--késako-&#34;&gt;&lt;a href=&#34;#iam-identity-center--k%c3%a9sako-&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;IAM Identity Center : Késako ?
&lt;/h1&gt;&lt;p&gt;En termes simples, IAM Identity Center est un service AWS qui vous permet de gérer de manière centralisée l&amp;rsquo;accès à tous vos comptes AWS et à vos applications Cloud. Que vous ayez une poignée de comptes ou une organisation AWS tentaculaire avec des dizaines, voire des centaines de comptes, IAM Identity Center est là pour vous simplifier la tâche.&lt;/p&gt;
&lt;p&gt;Il vous offre un point d&amp;rsquo;entrée unique (un portail d&amp;rsquo;accès web) pour vos utilisateurs, leur permettant d&amp;rsquo;accéder aux rôles et aux comptes auxquels ils ont droit, le tout avec une seule authentification.&lt;/p&gt;
&lt;h1 id=&#34;les-avantages-diam-identity-center&#34;&gt;&lt;a href=&#34;#les-avantages-diam-identity-center&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Les avantages d&amp;rsquo;IAM Identity Center
&lt;/h1&gt;&lt;p&gt;Si je suis aussi enthousiaste, c&amp;rsquo;est parce que les bénéfices sont nombreux et significatifs. Pour vous citer les plus importants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Single Sign-On (SSO) :&lt;/strong&gt; Vos utilisateurs se connectent une seule fois via le portail AWS (ou via votre fournisseur d&amp;rsquo;identité existant si vous en avez un) et accèdent ensuite à tous les comptes et rôles qui leur sont assignés, sans avoir à se ré-authentifier pour chaque compte.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gestion Centralisée :&lt;/strong&gt; Vous gérez tous vos utilisateurs, groupes et leurs permissions (via des &lt;em&gt;Permission Sets&lt;/em&gt;) depuis un seul endroit, même s&amp;rsquo;ils doivent accéder à des dizaines de comptes AWS différents.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identifiants Temporaires :&lt;/strong&gt; C&amp;rsquo;est l&amp;rsquo;un des points les plus importants ! Lorsque les utilisateurs accèdent à un compte via IAM Identity Center, ils obtiennent des identifiants temporaires à durée de vie limitée. Adieu les &lt;em&gt;Access Keys&lt;/em&gt; IAM qui traînent et qui représentent un risque de sécurité majeur.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MFA (Multi-Factor Authentication) :&lt;/strong&gt; Vous pouvez (et devriez !) imposer l&amp;rsquo;utilisation du MFA directement au niveau de la connexion à IAM Identity Center.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si j&amp;rsquo;ai piqué votre curiosité et que vous souhaitez en savoir plus, je vous laisse consulter la &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;documentation AWS sur IAM Identity Center&lt;/a&gt;. Pour ceux qui sont déjà convaincus, continuons ensemble !&lt;/p&gt;
&lt;h1 id=&#34;se-lancer-avec-iam-identity-center&#34;&gt;&lt;a href=&#34;#se-lancer-avec-iam-identity-center&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Se Lancer avec IAM Identity Center
&lt;/h1&gt;&lt;p&gt;Mettre en place IAM Identity Center est étonnamment simple, surtout si vous utilisez l&amp;rsquo;annuaire intégré d&amp;rsquo;Identity Center comme source d&amp;rsquo;identité. Voici les étapes clés pour démarrer :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Configuration initiale :&lt;/strong&gt; Rendez-vous dans la console AWS, et cherchez &lt;em&gt;IAM Identity Center&lt;/em&gt;. Attention, choisissez bien votre région AWS pour héberger IAM Identity Center dès le départ, car il est actuellement complexe de changer la région d&amp;rsquo;IAM Identity Center une fois configuré. La configuration initiale est souvent guidée et rapide. Vous choisirez votre source d&amp;rsquo;identité (l&amp;rsquo;annuaire Identity Center, AWS Managed Microsoft AD, ou un fournisseur externe).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Création de groupes et d&amp;rsquo;utilisateurs :&lt;/strong&gt; Définissez des groupes pertinents pour votre organisation (ex: Developers, Administrators, &amp;hellip;). Créez ensuite vos utilisateurs et assignez-les à ces groupes. Si vous utilisez un IdP externe, cette étape consistera plutôt à synchroniser vos utilisateurs et groupes existants.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Création des &lt;em&gt;Permission Sets&lt;/em&gt; :&lt;/strong&gt; Un &lt;em&gt;Permission Set&lt;/em&gt; est un ensemble de permissions (similaire à une policy IAM) que vous allez pouvoir réutiliser. Vous pouvez partir de policies managées par AWS (ex: &lt;em&gt;AdministratorAccess&lt;/em&gt; ou &lt;em&gt;ReadOnlyAccess&lt;/em&gt;) ou créer les vôtres.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assignation des accès :&lt;/strong&gt; C&amp;rsquo;est ici que la magie opère. Vous assignez un groupe (ou un utilisateur) à un ou plusieurs comptes AWS, en leur donnant le droit d&amp;rsquo;utiliser un &lt;em&gt;Permission Set&lt;/em&gt; spécifique sur ces comptes. Par exemple, le groupe Developers peut avoir le &lt;em&gt;Permission Set&lt;/em&gt; &lt;code&gt;PowerUserAccess&lt;/code&gt; sur les comptes AWS de développement.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Imposer le MFA :&lt;/strong&gt; Dans les paramètres d&amp;rsquo;IAM Identity Center, configurez le MFA pour qu&amp;rsquo;il soit obligatoire pour tous vos utilisateurs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Partager l&amp;rsquo;URL d&amp;rsquo;accès AWS :&lt;/strong&gt; Chaque configuration IAM Identity Center a une URL unique pour le portail d&amp;rsquo;accès (ex: &lt;code&gt;d-xxxxxxxxxx.awsapps.com/start&lt;/code&gt;). C&amp;rsquo;est cette URL que vos utilisateurs mettront en favori pour se connecter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-and-why-to-set-up-aws-iam-identity-center-on-your-aws-account/aws-iam-identity-center-dashboard.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;AWS IAM Identity Center Dashboard&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Une fois connectés au portail, les utilisateurs verront la liste des comptes AWS et des rôles (définis par les &lt;em&gt;Permission Sets&lt;/em&gt;) auxquels ils ont accès. Un clic, et ils sont dans la console du compte AWS choisi avec les bonnes permissions !&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-and-why-to-set-up-aws-iam-identity-center-on-your-aws-account/aws-iam-identity-center-access-portal.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;AWS IAM Identity Center Access Portal&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Ils peuvent aussi obtenir des identifiants temporaires pour la CLI. Mais d&amp;rsquo;ailleurs, comment faire pour se connecter à un compte AWS en CLI via IAM Identity Center ? Voyons ça ensemble !&lt;/p&gt;
&lt;h1 id=&#34;configurer-les-accès-cli&#34;&gt;&lt;a href=&#34;#configurer-les-acc%c3%a8s-cli&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Configurer les accès CLI
&lt;/h1&gt;&lt;p&gt;La &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;documentation d&amp;rsquo;AWS pour configurer l&amp;rsquo;authentification CLI avec IAM Identity Center&lt;/a&gt; est assez claire, mais je vais tout de même vous décrire les étapes. Je pars du principe que vous avez déjà installé votre &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/cli/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS CLI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;La commande pour initier la configuration est la suivante :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws configure sso
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ensuite, vous allez devoir rentrer quelques informations propres à votre IAM Identity Center. Le plus important étant le &lt;em&gt;SSO start URL&lt;/em&gt; (que vous pouvez trouver dans IAM Identity Center sous le nom de &lt;em&gt;AWS access portal URL&lt;/em&gt;, URL qui finit par &lt;code&gt;/start&lt;/code&gt;). Il faut ensuite rentrer la région dans laquelle se trouve votre configuration, quant au &lt;em&gt;SSO registration scopes&lt;/em&gt;, vous pouvez laisser la valeur par défaut.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSO session name &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Recommended&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSO start URL &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;None&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: https://xxxxxxxxxxxx.awsapps.com/start
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSO region &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;None&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: eu-west-1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSO registration scopes &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;sso:account:access&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si tout se passe bien, une fenêtre devrait s&amp;rsquo;ouvrir dans votre navigateur pour valider votre identité. Une fois cela fait, retournez dans votre terminal.&lt;/p&gt;
&lt;p&gt;Dans mon cas, je ne possède qu&amp;rsquo;un seul compte AWS, et IAM Identity Center me le sélectionne par défaut. Mais vous aurez peut-être le choix dans le compte AWS à sélectionner. Idem pour le role.&lt;/p&gt;
&lt;p&gt;Enfin, choisissez un nom de profil à utiliser pour vos futurs appels API. Je vous conseille d&amp;rsquo;utiliser &lt;code&gt;default&lt;/code&gt;, ce qui vous permettra de ne pas avoir à rajouter &lt;code&gt;--profile my-aws-profile&lt;/code&gt; à la fin de chacune de vos commandes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The only AWS account available to you is: xxxxxxxxxxxx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Using the account ID xxxxxxxxxxxx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The only role available to you is: AdministratorAccess
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Using the role name &lt;span class=&#34;s2&#34;&gt;&amp;#34;AdministratorAccess&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Default client Region &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;None&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: eu-west-1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CLI default output format &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;json &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; not specified&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;None&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Profile name &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;AdministratorAccess-xxxxxxxxxxxx&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The AWS CLI is now configured to use the default profile.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Run the following &lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt; to verify your configuration:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws sts get-caller-identity
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Et voilà, le tour est joué !&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion
&lt;/h1&gt;&lt;p&gt;Vous l&amp;rsquo;aurez compris, je suis un grand fan d&amp;rsquo;AWS IAM Identity Center. Il apporte une couche de sécurité indispensable tout en simplifiant considérablement la gestion des accès, que ce soit pour les administrateurs ou pour les utilisateurs.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est un véritable pilier pour une infrastructure AWS bien gérée et sécurisée. Si vous ne l&amp;rsquo;utilisez pas encore, je vous encourage vivement à explorer sa mise en place. C&amp;rsquo;est un investissement en temps minime pour des gains en sécurité et en efficacité énormes.&lt;/p&gt;
&lt;p&gt;Votre infrastructure (et vos équipes de sécurité) vous diront merci !&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Sur la piste de la ressource perdue - Mon enquête avec Athena et CloudTrail</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/on-the-trail-of-the-lost-resource-my-investigation-with-athena-and-cloudtrail/</link>
        <pubDate>Wed, 09 Jul 2025 12:30:00 +0200</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/on-the-trail-of-the-lost-resource-my-investigation-with-athena-and-cloudtrail/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/on-the-trail-of-the-lost-resource-my-investigation-with-athena-and-cloudtrail/aws_lost_resource.jpeg" alt="Featured image of post Sur la piste de la ressource perdue - Mon enquête avec Athena et CloudTrail" /&gt;&lt;h1 id=&#34;introduction&#34;&gt;&lt;a href=&#34;#introduction&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Introduction
&lt;/h1&gt;&lt;p&gt;Récemment, j&amp;rsquo;ai dû jouer les détectives sur notre compte AWS.&lt;/p&gt;
&lt;p&gt;Une ressource était là (un Cognito User Pool), bien présente, mais personne ne se souvenait de son origine. Et évidemment, pas de tags pour nous aider (si seulement ils avaient lu &lt;a class=&#34;link&#34; href=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/why-tagging-your-aws-resources-is-a-must/&#34; &gt;mon article sur le tagging des ressources AWS&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Ma mission, si je l&amp;rsquo;acceptais : découvrir qui l&amp;rsquo;avait créée. Le problème ? L&amp;rsquo;événement datait d&amp;rsquo;il y a environ quatre mois.&lt;/p&gt;
&lt;p&gt;Mon premier réflexe a été de me tourner vers AWS CloudTrail. Et là, premier mur : &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html#event-history-limitations&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;l&amp;rsquo;historique des événements n&amp;rsquo;est consultable que sur les 90 derniers jours&lt;/a&gt;. Raté !&lt;/p&gt;
&lt;p&gt;Heureusement, je savais que nos logs CloudTrail étaient archivés dans un bucket S3. Mon premier réflexe : télécharger manuellement les archives du bon mois, décompresser des dizaines de fichiers JSON, et lancer un &lt;kbd&gt;Ctrl+F&lt;/kbd&gt; en priant très fort. Autant vous dire que ce n&amp;rsquo;est ni efficace, ni agréable, ni rapide.&lt;/p&gt;
&lt;p&gt;Je me suis donc demandé s&amp;rsquo;il n&amp;rsquo;y avait pas un moyen plus simple de chercher dans cet amas de logs, et j&amp;rsquo;ai finalement trouvé la solution parfaite : &lt;strong&gt;AWS Athena&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id=&#34;interroger-vos-logs-s3-avec-athena&#34;&gt;&lt;a href=&#34;#interroger-vos-logs-s3-avec-athena&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Interroger vos logs S3 avec Athena
&lt;/h1&gt;&lt;p&gt;Pour ceux qui ne connaissent pas, &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/athena/latest/ug/what-is.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Athena&lt;/a&gt; est un service de requête interactif qui facilite l&amp;rsquo;analyse de données directement dans Amazon S3 en utilisant du SQL standard. En gros, vous pouvez faire des requêtes sur des fichiers (JSON, CSV, &amp;hellip;) comme s&amp;rsquo;il s&amp;rsquo;agissait d&amp;rsquo;une base de données traditionnelle. Plus besoin de télécharger quoi que ce soit !&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;idée est donc de &amp;ldquo;mapper&amp;rdquo; nos logs CloudTrail stockés dans S3 à une table dans Athena. Pour cela, on utilise une seule requête &lt;code&gt;CREATE EXTERNAL TABLE&lt;/code&gt;. En suivant &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/athena/latest/ug/create-cloudtrail-table-partition-projection.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;la documentation d&amp;rsquo;AWS sur le sujet&lt;/a&gt;, j&amp;rsquo;ai lancé la requête suivante dans la console Athena.&lt;/p&gt;
&lt;p&gt;Cette requête crée une table et utilise une fonctionnalité très pratique appelée &amp;ldquo;partition projection&amp;rdquo;. Cela permet à Athena de déduire l&amp;rsquo;emplacement des logs en fonction de la date, sans avoir à gérer manuellement les partitions. C&amp;rsquo;est d&amp;rsquo;autant plus pratique quand la structure est bien standardisée comme c&amp;rsquo;est le cas avec AWS CloudTrail.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXTERNAL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cloudtrail_logs_pp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventversion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;useridentity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRUCT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventtime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventsource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;awsregion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestparameters&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;responseelements&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;additionaleventdata&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;ARRAY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRUCT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;accountid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventtype&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventcategory&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;PARTITIONED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ROW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FORMAT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SERDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.apache.hive.hcatalog.data.JsonSerDe&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;STORED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INPUTFORMAT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;com.amazon.emr.cloudtrail.CloudTrailInputFormat&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;OUTPUTFORMAT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;LOCATION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;s3://BUCKET-NAME/AWSLogs/ACCOUNT-ID/CloudTrail/REGION&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Remplacez par le chemin de votre bucket S3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;TBLPROPERTIES&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;projection.enabled&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;projection.timestamp.format&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;yyyy/MM/dd&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;projection.timestamp.interval&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;projection.timestamp.interval.unit&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;DAYS&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;projection.timestamp.range&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;2024/01/01,NOW&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Remplacez par la date de début
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;projection.timestamp.type&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;storage.location.template&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;s3://BUCKET-NAME/AWSLogs/ACCOUNT-ID/CloudTrail/REGION/${timestamp}&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Remplacez par le chemin de votre bucket S3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Attention :&lt;/strong&gt; N&amp;rsquo;oubliez pas de remplacer les URLs &lt;code&gt;s3://...&lt;/code&gt; par le chemin exact de votre bucket S3 où sont stockés vos logs CloudTrail, et d&amp;rsquo;ajuster la propriété &lt;code&gt;projection.timestamp.range&lt;/code&gt; à la période qui vous intéresse.&lt;/p&gt;
&lt;h1 id=&#34;lheure-de-lenquête--trouver-linformation&#34;&gt;&lt;a href=&#34;#lheure-de-lenqu%c3%aate--trouver-linformation&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;L&amp;rsquo;Heure de l&amp;rsquo;Enquête : Trouver l&amp;rsquo;Information
&lt;/h1&gt;&lt;p&gt;Une fois la table créée (ce qui ne prend que quelques secondes), le plus dur est fait ! Mon enquête pouvait enfin commencer.&lt;/p&gt;
&lt;p&gt;Je cherchais à savoir qui avait créé un &lt;code&gt;UserPoolClient&lt;/code&gt; pour Cognito à une date précise. Ma requête SQL ressemblait donc à ça :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userIdentity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cloudtrail_logs_pp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;2025/02/25&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eventName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;CreateUserPoolClient&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;En quelques secondes, Athena a scanné les logs du jour demandé et m&amp;rsquo;a retourné le résultat.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/on-the-trail-of-the-lost-resource-my-investigation-with-athena-and-cloudtrail/running_the_athena_query.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Athena query to search CloudTrail logs in S3&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avais l&amp;rsquo;heure exacte, l&amp;rsquo;événement, et surtout, l&amp;rsquo;ARN de l&amp;rsquo;utilisateur qui avait effectué l&amp;rsquo;action. Mission accomplie !&lt;/p&gt;
&lt;h1 id=&#34;le-verdict-et-le-coupable&#34;&gt;&lt;a href=&#34;#le-verdict-et-le-coupable&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le Verdict&amp;hellip; et le Coupable
&lt;/h1&gt;&lt;p&gt;Le plus drôle dans cette histoire ?&lt;/p&gt;
&lt;p&gt;Après avoir mis en place cette solution et retrouvé l&amp;rsquo;information si facilement, j&amp;rsquo;ai découvert que le &amp;ldquo;coupable&amp;rdquo; qui avait créé cette ressource il y a quatre mois&amp;hellip; &lt;strong&gt;c&amp;rsquo;était moi&lt;/strong&gt;. J&amp;rsquo;avais complètement oublié !&lt;/p&gt;
&lt;p&gt;Au-delà de l&amp;rsquo;anecdote, cette expérience m&amp;rsquo;a confirmé une chose : prendre quelques minutes pour configurer Athena sur vos logs CloudTrail est un investissement incroyablement rentable. Vous vous offrez une capacité d&amp;rsquo;audit et de recherche sur le long terme qui vous sauvera des heures de recherche manuelle le jour où vous en aurez vraiment besoin. Ne faites pas comme moi, n&amp;rsquo;attendez pas d&amp;rsquo;être coincé pour le mettre en place !&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Pourquoi taguer vos ressources AWS est indispensable ?</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/why-tagging-your-aws-resources-is-a-must/</link>
        <pubDate>Tue, 24 Jun 2025 07:30:00 +0200</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/why-tagging-your-aws-resources-is-a-must/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/why-tagging-your-aws-resources-is-a-must/aws_tagging.jpeg" alt="Featured image of post Pourquoi taguer vos ressources AWS est indispensable ?" /&gt;&lt;h1 id=&#34;introduction&#34;&gt;&lt;a href=&#34;#introduction&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Introduction
&lt;/h1&gt;&lt;p&gt;Plus on déploie de services sur AWS, plus on commence à s&amp;rsquo;y perdre. Au début, on connaît par coeur tous les services qu&amp;rsquo;on utilise, le nombre de Lambdas ou d&amp;rsquo;EC2 qui sont lancées. Mais petit à petit, il est facile de ne plus savoir où donner de la tête, surtout lorsque différents projets s&amp;rsquo;accumulent. Retrouver rapidement quelles ressources appartiennent à quel projet, ou identifier celles qui n&amp;rsquo;ont pas été correctement nettoyées après un PoC, tout cela peut vite devenir un casse-tête. Et c&amp;rsquo;est sans parler de la vision des coûts !&lt;/p&gt;
&lt;p&gt;Heureusement, il existe une pratique simple mais incroyablement puissante : &lt;strong&gt;le tagging&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Dans cet article, j&amp;rsquo;aimerais vous montrer qu&amp;rsquo;une bonne stratégie de tags est &lt;strong&gt;cruciale pour votre organisation, votre gestion des coûts, et pour la sécurité&lt;/strong&gt; de votre compte AWS.&lt;/p&gt;
&lt;p&gt;À vos marques. Prêts ? Taguez !&lt;/p&gt;
&lt;h1 id=&#34;pourquoi-les-tags-sont-ils-utiles-&#34;&gt;&lt;a href=&#34;#pourquoi-les-tags-sont-ils-utiles-&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Pourquoi les tags sont-ils utiles ?
&lt;/h1&gt;&lt;p&gt;Imaginez des étiquettes sur des boîtes de déménagement. Sans elles, impossible de savoir ce qu&amp;rsquo;il y a dedans ou à quelle pièce elles appartiennent. Les tags sur AWS, c&amp;rsquo;est pareil ! Un tag est une &lt;strong&gt;information&lt;/strong&gt; (sous la forme clé-valeur) que vous assignez à vos ressources (instances EC2, buckets S3, bases de données RDS, etc.).&lt;/p&gt;
&lt;p&gt;Une bonne stratégie de tagging vous permet notamment de :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Identifier des ressources orphelines&lt;/strong&gt; : C&amp;rsquo;est le grand classique. Une ressource sans tag &lt;code&gt;Project&lt;/code&gt; ou &lt;code&gt;Owner&lt;/code&gt; ? Il y a de fortes chances qu&amp;rsquo;elle ait été oubliée et qu&amp;rsquo;elle consomme des ressources (et donc de l&amp;rsquo;argent) pour rien. Lister les ressources non taguées (ou mal taguées) est une première étape essentielle pour faire le ménage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ventiler les coûts&lt;/strong&gt; : En taguant vos ressources avec un identifiant de projet, de centre de coût, ou d&amp;rsquo;équipe, vous pouvez ensuite utiliser AWS Cost Explorer pour filtrer vos dépenses et comprendre précisément quels projets consomment le plus. Indispensable pour la refacturation interne ou simplement pour optimiser votre budget.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatiser des actions&lt;/strong&gt; : Les tags peuvent servir de déclencheurs pour des scripts d&amp;rsquo;automatisation (par exemple, sauvegarder toutes les instances EC2 avec le tag &lt;code&gt;Backup=Daily&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gérer les accès et la sécurité&lt;/strong&gt; : Le service &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/iam&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS IAM&lt;/a&gt; peut utiliser les tags pour accorder des permissions granulaires.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Bref, taguer, c&amp;rsquo;est la base d&amp;rsquo;une &lt;strong&gt;bonne gouvernance Cloud&lt;/strong&gt;. Pour plus de détails, je vous invite à consulter le &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/solutions/guidance/tagging-on-aws/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;guide de tagging proposé par AWS&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;On peut fort heureusement associer plusieurs tags à une même ressource. Mais cela pose la question : combien de tags sont nécessaires ?&lt;/p&gt;
&lt;p&gt;Cela va dépendre de votre entreprise et de chaque projet, mais globalement, il y a des tags qui ne font pas de mal, peu importe votre situation :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Project&lt;/strong&gt; : Le nom du projet lié à la ressource. Généralement, le nom du repository GitHub fait l&amp;rsquo;affaire&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Environment&lt;/strong&gt; : L&amp;rsquo;environnement désiré (dev, val, prod, &amp;hellip;). Même si vous avez des comptes AWS cloisonnés, cela vous permettra d&amp;rsquo;identifier si une ressource s&amp;rsquo;est perdue durant un déploiement&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Owner&lt;/strong&gt; : L&amp;rsquo;owner de la ressource. Cela pourrait être une personne, mais plus idéalement une équipe (frontend, backend, security, &amp;hellip;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Selon votre usage, vous aurez sûrement d&amp;rsquo;autres idées de tags, mais avec ceux-ci, ce sera déjà un bon début ! Et dans le doute, n&amp;rsquo;hésitez pas à consulter les &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/tag-editor/latest/userguide/best-practices-and-strats.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;best practices de tagging recommandées par AWS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Voyons maintenant quelques cas concrets de l&amp;rsquo;utilité des tags dans AWS.&lt;/p&gt;
&lt;h2 id=&#34;aws-cost-explorer--suivre-les-coûts-grâce-aux-tags&#34;&gt;&lt;a href=&#34;#aws-cost-explorer--suivre-les-co%c3%bbts-gr%c3%a2ce-aux-tags&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;AWS Cost Explorer : Suivre les coûts grâce aux tags
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;un des avantages les plus concrets du tagging est la &lt;strong&gt;visibilité qu&amp;rsquo;il apporte sur vos dépenses&lt;/strong&gt;. &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/aws-cost-management/aws-cost-explorer/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Cost Explorer&lt;/a&gt; est l&amp;rsquo;outil de prédilection pour cela.&lt;/p&gt;
&lt;p&gt;Une fois vos ressources correctement taguées (par exemple, avec le tag &lt;code&gt;Project&lt;/code&gt;), vous devez activer ces tags pour l&amp;rsquo;allocation des coûts dans la console de gestion de la facturation AWS (Billing and Cost Management -&amp;gt; Cost Organization -&amp;gt; Cost Allocation Tags). Attention, il peut y avoir un délai avant que les tags activés n&amp;rsquo;apparaissent dans Cost Explorer.&lt;/p&gt;
&lt;p&gt;Une fois activés, vous pouvez :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Filtrer par tag&lt;/strong&gt; : Dans Cost Explorer, vous pouvez filtrer vos coûts par la valeur d&amp;rsquo;un tag spécifique.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grouper par tag&lt;/strong&gt; : Vous pouvez également choisir de grouper vos dépenses par tag. Cela vous donnera une vue d&amp;rsquo;ensemble de la répartition des coûts entre les différents projets, environnements, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Créer des budgets basés sur les tags&lt;/strong&gt; : Avec AWS Budgets, vous pouvez définir des seuils d&amp;rsquo;alerte pour les coûts associés à des tags spécifiques, vous aidant à éviter les mauvaises surprises.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/why-tagging-your-aws-resources-is-a-must/cost_explorer_tag_filtering.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Exemple de filtrage par tag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Exemple de filtrage par tag pour mon blog : les coûts sont minimes, suis-je un expert FinOps ?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Cette capacité à disséquer votre facture AWS par tags transforme la gestion des coûts d&amp;rsquo;une corvée obscure en un exercice transparent et contrôlable. C&amp;rsquo;est un must pour toute organisation soucieuse de son budget Cloud. Vous pourrez désormais rajouter &lt;em&gt;FinOps&lt;/em&gt; dans votre bio LinkedIn !&lt;/p&gt;
&lt;h2 id=&#34;aws-resource-explorer--garder-un-œil-sur-les-ressources-déployées&#34;&gt;&lt;a href=&#34;#aws-resource-explorer--garder-un-%c5%93il-sur-les-ressources-d%c3%a9ploy%c3%a9es&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;AWS Resource Explorer : Garder un œil sur les ressources déployées
&lt;/h2&gt;&lt;p&gt;Maintenant que l&amp;rsquo;on est convaincu de l&amp;rsquo;utilité des tags, comment fait-on pour &lt;strong&gt;lister toutes les ressources qui utilisent un tag précis ?&lt;/strong&gt; Nous allons le voir ensemble avec une partie dans la console AWS, et une partie qui se passera dans le terminal (pour tous les geeks qui lisent cet article !).&lt;/p&gt;
&lt;h3 id=&#34;lexploration-visuelle-dans-la-console-aws&#34;&gt;&lt;a href=&#34;#lexploration-visuelle-dans-la-console-aws&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;L&amp;rsquo;exploration visuelle dans la console AWS
&lt;/h3&gt;&lt;p&gt;Si vous n&amp;rsquo;êtes pas encore familier avec &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/resourceexplorer/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Resource Explorer&lt;/a&gt;, c&amp;rsquo;est le moment de le découvrir ! Ce service, relativement récent, vous permet de rechercher et de découvrir vos ressources AWS à travers toutes les régions de votre compte, en utilisant une interface simple, un peu comme un moteur de recherche.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;avantage principal de Resource Explorer est sa capacité à vous donner une vue unifiée. Plus besoin de sauter de région en région. Vous activez l&amp;rsquo;indexation, et ensuite, vous pouvez rechercher vos ressources par nom, ID, et bien sûr&amp;hellip; par tag !&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est un excellent outil pour :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoir une vue d&amp;rsquo;ensemble rapide.&lt;/li&gt;
&lt;li&gt;Explorer visuellement les ressources associées à un tag spécifique.&lt;/li&gt;
&lt;li&gt;Identifier rapidement des ressources sans avoir à coder quoi que ce soit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour l&amp;rsquo;utiliser, activez-le dans les régions souhaitées (ou toutes), laissez-le indexer vos ressources, puis utilisez la barre de recherche avec une syntaxe comme &lt;code&gt;tag.key:Project tag.value:Cloud*&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/why-tagging-your-aws-resources-is-a-must/resource_explorer_search_tags.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Recherche des ressources par tag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Exemple de recherche par tag pour mon blog : seulement trois ressources permettent de gérer ce blog !&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;une-approche-plus-technique-avec-aws-cli&#34;&gt;&lt;a href=&#34;#une-approche-plus-technique-avec-aws-cli&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Une approche plus technique avec AWS CLI
&lt;/h3&gt;&lt;p&gt;Pour ceux qui, comme moi, aiment avoir la main via la ligne de commande, ou qui ont besoin d&amp;rsquo;automatiser ces recherches, l&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/cli/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS CLI&lt;/a&gt; reste une alliée de choix. Plus précisément, c&amp;rsquo;est le service &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;resourcegroupstaggingapi&lt;/a&gt; qui va nous intéresser.&lt;/p&gt;
&lt;p&gt;La commande clé est &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;get-resources&lt;/a&gt;. Voici un exemple typique pour lister les ARN de toutes les ressources ayant le tag Project avec la valeur &amp;ldquo;Cloud Antoine Delia&amp;rdquo; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws resourcegroupstaggingapi get-resources &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --tag-filters &lt;span class=&#34;s2&#34;&gt;&amp;#34;Key=Project,Values=Cloud Antoine Delia&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s2&#34;&gt;&amp;#34;[.ResourceTagMappingList[].ResourceARN]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ce qui nous donne :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;arn:aws:s3:::antoiXXXXXXXXXXXXX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Décortiquons un peu :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;aws resourcegroupstaggingapi get-resources&lt;/code&gt; : C&amp;rsquo;est l&amp;rsquo;appel à l&amp;rsquo;API, jusqu&amp;rsquo;ici, tout va bien.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--tag-filters &amp;quot;Key=Project,Values=Cloud Antoine Delia&amp;quot;&lt;/code&gt; : C&amp;rsquo;est ici qu&amp;rsquo;on spécifie notre filtre. On cherche le tag Project qui a la valeur &amp;ldquo;Cloud Antoine Delia&amp;rdquo;. Vous pouvez ajouter plusieurs filtres.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;| jq &amp;quot;[.ResourceTagMappingList[].ResourceARN]&amp;quot;&lt;/code&gt; : &lt;a class=&#34;link&#34; href=&#34;https://jqlang.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;jq&lt;/a&gt; est un outil formidable pour manipuler du JSON en ligne de commande. Ici, on l&amp;rsquo;utilise pour extraire proprement la liste des ARN des ressources trouvées (vous pouvez vous en passer, mais pourquoi se compliquer la vie ?).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Eh attends une minute ! Dans la console, tu nous montres trois ressources, et là il n&amp;rsquo;y en a plus qu&amp;rsquo;une ! Elle est où l&amp;rsquo;arnaque ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Habilement remarqué ! Il faut savoir que lorsque vous faites votre appel à l&amp;rsquo;API, vous utilisez une &lt;strong&gt;region par défaut&lt;/strong&gt;. Or, si vous avez des ressources dans diverses régions, il faudra le spécifier. Ainsi, si l&amp;rsquo;on ajoute &lt;code&gt;--region us-east-1&lt;/code&gt; juste avant le pipe jq, on obtient bien nos deux ressources manquantes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;arn:aws:acm:us-east-1:6XXXXXXXXXXX0:certificate/f4ca3b13-XXXXXXXXXXXXX&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;arn:aws:cloudfront::6XXXXXXXXXXX0:distribution/ERSXXXXXXXXXX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Outre ce détail qu&amp;rsquo;il ne vous faudra pas oublier, cette commande est extrêmement puissante car vous pouvez l&amp;rsquo;intégrer dans des scripts pour :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Générer des rapports réguliers sur les ressources par projet.&lt;/li&gt;
&lt;li&gt;Détecter automatiquement les ressources qui ne respectent pas votre politique de tagging.&lt;/li&gt;
&lt;li&gt;Combiner avec d&amp;rsquo;autres commandes AWS CLI pour effectuer des actions sur les ressources listées.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par exemple, vous pourriez ainsi lister toutes vos ressources d&amp;rsquo;un certain type (ex: toutes vos instances EC2) et de vérifier celles à qui il manque des tags essentiels.&lt;/p&gt;
&lt;p&gt;Et si vous vous demandez si AWS n&amp;rsquo;offre pas déjà un service pour ça&amp;hellip; C&amp;rsquo;est le cas ! Mais nous en parlerons dans un futur article (pour les curieux, je veux parler d&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/config/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Config&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;aws-iam--sécuriser-lutilisation-de-vos-ressources&#34;&gt;&lt;a href=&#34;#aws-iam--s%c3%a9curiser-lutilisation-de-vos-ressources&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;AWS IAM : Sécuriser l&amp;rsquo;utilisation de vos ressources
&lt;/h2&gt;&lt;p&gt;Vos ressources sont déployées dans AWS, et vous souhaitez maintenant donner à une équipe la permission de gérer tout cela.&lt;/p&gt;
&lt;p&gt;Seulement voilà, dans votre compte AWS, vous avez aussi des ressources critiques qui ne doivent surtout pas être compromises.&lt;/p&gt;
&lt;p&gt;AWS IAM est là pour vous ! À l&amp;rsquo;aide d&amp;rsquo;une simple policy, vous pouvez spécifier que &lt;strong&gt;seules les ressources comportant un certain tag peuvent être modifiées&lt;/strong&gt; par un utilisateur ou un groupe.&lt;/p&gt;
&lt;p&gt;Prenons par exemple le cas suivant : vous aimeriez la possibilité à une équipe de démarrer ou stopper certaines instances EC2, mais de les empêcher d&amp;rsquo;accidentellement stopper une instance EC2 critique !&lt;/p&gt;
&lt;p&gt;Il vous suffit d&amp;rsquo;ajouter la policy suivante à vos utilisateurs :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;Version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2012-10-17&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;Statement&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Sid&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AllowStartStopEC2IfProjectCloud&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Effect&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;ec2:StartInstances&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;ec2:StopInstances&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Resource&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;arn:aws:ec2:*:*:instance/*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Condition&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;StringEquals&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;aws:ResourceTag/Project&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Cloud Antoine Delia&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Sid&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AllowDescribeToSeeInstances&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Effect&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ec2:DescribeInstances&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;Resource&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ainsi, vos utilisateurs seront autonomes dans l&amp;rsquo;utilisation de leurs ressources, sans pour autant avoir la possibilité d&amp;rsquo;impacter d&amp;rsquo;autres ressources.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion
&lt;/h1&gt;&lt;p&gt;Vous l&amp;rsquo;aurez compris, une stratégie de tagging rigoureuse &lt;strong&gt;n&amp;rsquo;est pas une option, c&amp;rsquo;est une nécessité&lt;/strong&gt; pour opérer sereinement sur AWS. Que ce soit sur le plan organisationnel, financier, ou encore dans la gestion de la sécurité, AWS vous donne les moyens de tirer pleinement parti de vos tags.&lt;/p&gt;
&lt;p&gt;Alors, un petit conseil : si ce n&amp;rsquo;est pas déjà fait, &lt;strong&gt;définissez une politique de tagging claire&lt;/strong&gt; dans votre organisation, appliquez-la, et utilisez ces outils pour vérifier régulièrement que tout est en ordre. Vous m&amp;rsquo;en remercierez plus tard !&lt;/p&gt;
</description>
        </item>
        <item>
        <title>AWS Lambda : La phase d&#39;INIT devient payante - faut-il s&#39;alarmer ?</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/aws-lambdas-init-phase-to-be-billed-soon-should-we-be-alarmed/</link>
        <pubDate>Tue, 13 May 2025 07:30:00 +0200</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/aws-lambdas-init-phase-to-be-billed-soon-should-we-be-alarmed/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/aws-lambdas-init-phase-to-be-billed-soon-should-we-be-alarmed/lambda-init-billing.jpeg" alt="Featured image of post AWS Lambda : La phase d&#39;INIT devient payante - faut-il s&#39;alarmer ?" /&gt;&lt;h1 id=&#34;introduction&#34;&gt;&lt;a href=&#34;#introduction&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Introduction
&lt;/h1&gt;&lt;p&gt;Ah, les Lambdas. Probablement le service AWS que j&amp;rsquo;affectionne le plus ! En moins de temps qu&amp;rsquo;il ne faut pour le dire, elles permettent de créer un petit script ou carrément un backend API hosté dans le Cloud, et tout cela à moindre coût avec le &amp;ldquo;pay as you go&amp;rdquo;. Mais cela serait-il trop beau pour être vrai ?&lt;/p&gt;
&lt;p&gt;Il y a quelques jours, &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/blogs/compute/aws-lambda-standardizes-billing-for-init-phase&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS a annoncé une modification dans la manière dont la phase d&amp;rsquo;initialisation des Lambdas est facturée&lt;/a&gt;. &lt;strong&gt;À partir du 1er août 2025&lt;/strong&gt;, cette phase sera systématiquement incluse dans le calcul de la durée facturée, et ce, pour &lt;em&gt;toutes&lt;/em&gt; les Lambdas.&lt;/p&gt;
&lt;p&gt;Si vous n&amp;rsquo;étiez pas au courant, sachez que jusqu&amp;rsquo;à présent, si vous utilisiez des fonctions Lambdas avec un code packagé en ZIP avec des runtimes managés par AWS (comme Python, Node.js, etc.), la durée de cette phase &lt;code&gt;INIT&lt;/code&gt; n&amp;rsquo;était pas facturée. C&amp;rsquo;était un petit &amp;ldquo;cadeau&amp;rdquo; de la part d&amp;rsquo;AWS (plutôt sympa de leur part). Mais toutes les bonnes choses ont une fin, et il faudra maintenant payer ce temps d&amp;rsquo;initialisation de nos Lambdas.&lt;/p&gt;
&lt;p&gt;Alors, cela va-t-il rendre l&amp;rsquo;usage des Lambdas trop cher ? Et comment faire en sorte de réduire au maximum cette partie d&amp;rsquo;initialisation ? Je vous propose aujourd&amp;rsquo;hui de répondre à toutes ces questions !&lt;/p&gt;
&lt;h1 id=&#34;comprendre-le-cycle-de-vie-dune-lambda&#34;&gt;&lt;a href=&#34;#comprendre-le-cycle-de-vie-dune-lambda&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Comprendre le cycle de vie d&amp;rsquo;une Lambda
&lt;/h1&gt;&lt;p&gt;Avant de plonger dans la facturation, c&amp;rsquo;est l&amp;rsquo;occasion de se rappeler du &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cycle de vie d&amp;rsquo;une Lambda&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pour simplifier la lecture, je ne rentrerai pas dans les détails des &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-extensions.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Lambda Extensions&lt;/a&gt; et de &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Lambda SnapStart&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cela se compose de trois phases principales :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;INIT :&lt;/strong&gt; C&amp;rsquo;est l&amp;rsquo;étape du &amp;ldquo;démarrage à froid&amp;rdquo; ou cold start. Quand une nouvelle instance de votre fonction doit être créée pour répondre à une requête, Lambda prépare le terrain. Cette phase dure au maximum 10 secondes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;INVOKE :&lt;/strong&gt; C&amp;rsquo;est là que votre code (le handler de votre fonction) est exécuté pour traiter la requête.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHUTDOWN :&lt;/strong&gt; Quand l&amp;rsquo;environnement d&amp;rsquo;exécution n&amp;rsquo;est plus utilisé pendant un certain temps, la Lambda se &amp;ldquo;shutdown&amp;rdquo; pour libérer les ressources. Si une nouvelle requête arrive, la Lambda devra de nouveau passer par la phase d&amp;rsquo;INIT.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/aws-lambdas-init-phase-to-be-billed-soon-should-we-be-alarmed/lambda_lifecycle.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Lambda Lifecycle&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Pendant la phase &lt;code&gt;INIT&lt;/code&gt;, &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html#runtimes-lifecycle-ib&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;votre Lambda fait plusieurs choses&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Récupère votre code (depuis S3 pour un ZIP, ou ECR pour une image Docker).&lt;/li&gt;
&lt;li&gt;Configure l&amp;rsquo;environnement avec la mémoire allouée, le runtime choisi, etc.&lt;/li&gt;
&lt;li&gt;Démarre le runtime (&lt;code&gt;Runtime INIT&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Exécute le code statique de votre fonction (tout ce qui est en dehors du handler, par exemple l&amp;rsquo;initialisation de variables globales ou de &lt;code&gt;boto3&lt;/code&gt;) (&lt;code&gt;Function INIT&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le point clé à retenir de tout cela, c&amp;rsquo;est que la phase &lt;code&gt;INIT&lt;/code&gt; ne se produit que lors d&amp;rsquo;un démarrage &lt;em&gt;à froid&lt;/em&gt; (ce fameux cold start). Si une requête arrive alors qu&amp;rsquo;un environnement d&amp;rsquo;exécution est déjà &amp;ldquo;chaud&amp;rdquo; (prêt et réutilisé), cette phase est sautée, et on passe directement à l&amp;rsquo;&lt;code&gt;INVOKE&lt;/code&gt;. C&amp;rsquo;est ce qu&amp;rsquo;on appelle un &amp;ldquo;démarrage à chaud&amp;rdquo; (warm start), qui est bien plus rapide.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AWS ne communique pas sur son calcul pour passer une Lambda &amp;ldquo;warm&amp;rdquo; à &amp;ldquo;cold&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;le-changement-de-facturation-en-détail&#34;&gt;&lt;a href=&#34;#le-changement-de-facturation-en-d%c3%a9tail&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le changement de facturation en détail
&lt;/h1&gt;&lt;p&gt;Actuellement, &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/lambda/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;la facturation des Lambdas&lt;/a&gt; repose sur deux éléments :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le nombre de requêtes.&lt;/li&gt;
&lt;li&gt;La durée d&amp;rsquo;exécution de votre code, arrondie à la milliseconde supérieure (le coût de cette durée dépend de la mémoire allouée à la fonction).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jusqu&amp;rsquo;au 1er août 2025, pour ces fonctions en ZIP avec runtime managé, la durée de la phase &lt;code&gt;INIT&lt;/code&gt; n&amp;rsquo;était pas comptée dans la &amp;ldquo;Durée Facturée&amp;rdquo; (&lt;code&gt;Billed Duration&lt;/code&gt;). On pouvait le voir dans les logs CloudWatch :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# Avant le 1er août 2025
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# Notez que la Billed Duration est l&amp;#39;arrondie au supérieur
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# de la Duration sans tenir compte de la Init Duration
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;REPORT RequestId: xxxxx   Duration: 250.06 ms   Billed Duration: 251 ms   Init Duration: 100.77 ms
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# Après le 1er août 2025
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# La Billed Duration est maintenant l&amp;#39;arrondie au supérieur
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# de la Duration + la Init Duration
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;REPORT RequestId: xxxxx   Duration: 250.06 ms   Billed Duration: 351 ms   Init Duration: 100.77 ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Comme vous pouvez le voir, AWS prendra maintenant en compte votre Init Duration en plus de la Duration pour réaliser son calcul de la Billed Duration.&lt;/p&gt;
&lt;h1 id=&#34;quel-impact-sur-la-facture-&#34;&gt;&lt;a href=&#34;#quel-impact-sur-la-facture-&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Quel impact sur la facture ?
&lt;/h1&gt;&lt;p&gt;Alors tout ça, c&amp;rsquo;est bien beau, mais allons-nous tous finir ruiner par ce changement ?&lt;/p&gt;
&lt;p&gt;Prenons un exemple pour y voir plus clair. Imaginons une Lambda en Python configurée avec 1024 Mo de mémoire, déployée dans la région &lt;code&gt;eu-west-1&lt;/code&gt; (Irlande).&lt;/p&gt;
&lt;p&gt;Supposons les points suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La Lambda reçoit 10 millions d&amp;rsquo;invocations par mois.&lt;/li&gt;
&lt;li&gt;Le taux de cold start est de 1% (&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html#cold-start-latency&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;moyenne fournie par AWS&lt;/a&gt;), soit 100&#39;000 démarrages à froid par mois.&lt;/li&gt;
&lt;li&gt;La durée moyenne de l&amp;rsquo;invocation (&lt;code&gt;Duration&lt;/code&gt;) est de 3 secondes.&lt;/li&gt;
&lt;li&gt;La durée moyenne de l&amp;rsquo;initialisation (&lt;code&gt;Init Duration&lt;/code&gt;) est de 1 seconde.&lt;/li&gt;
&lt;li&gt;Coût par requête : $0.20 par million de requêtes.&lt;/li&gt;
&lt;li&gt;Coût de la durée (x86) : $0.0000166667 par GB-seconde.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;
  &lt;summary&gt;Détails des calculs&lt;/summary&gt;
&lt;p&gt;&lt;strong&gt;Calcul du coût AVANT le 1er août 2025 :&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Coût des requêtes :&lt;/strong&gt; 10 millions req * ($0.20 / 1 million req) = &lt;strong&gt;$2.00&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coût de la durée :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Invocations &amp;ldquo;à chaud&amp;rdquo; (9.9 millions) : Durée facturée = 3 secondes.&lt;/li&gt;
&lt;li&gt;Invocations &amp;ldquo;à froid&amp;rdquo; (100 000) : Durée facturée = 3 secondes (INIT non facturée).&lt;/li&gt;
&lt;li&gt;Durée facturée totale (secondes) : (9&#39;900&#39;000 * 3 s) + (100&#39;000 * 3 s) = 29&#39;700&#39;000 secondes + 300&#39;000 secondes = 30&#39;000&#39;000 secondes.&lt;/li&gt;
&lt;li&gt;Go-secondes totaux : 30&#39;000&#39;000 secondes * (1024 Mo / 1024 Mo) = 30&#39;000&#39;000 Go-s.&lt;/li&gt;
&lt;li&gt;Coût Durée : 30&#39;000&#39;000 Go-s * $0.0000166667/Go-s = &lt;strong&gt;$500.00&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coût total mensuel (Avant) :&lt;/strong&gt; $2.00 + $500.00 = &lt;strong&gt;$502.00&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Calcul du coût APRÈS le 1er août 2025 :&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Coût des requêtes :&lt;/strong&gt; &lt;strong&gt;$2.00&lt;/strong&gt; (inchangé)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coût de la durée :&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Invocations &amp;ldquo;à chaud&amp;rdquo; (9.9 millions) : Durée facturée = 3 secondes.&lt;/li&gt;
&lt;li&gt;Invocations &amp;ldquo;à froid&amp;rdquo; (100 000) : Durée facturée = 3 secondes (&lt;code&gt;Duration&lt;/code&gt;) + 1 seconde (&lt;code&gt;Init Duration&lt;/code&gt;) = 4 secondes.&lt;/li&gt;
&lt;li&gt;Durée facturée totale (secondes) : (9&#39;900&#39;000 * 3 s) + (100&#39;000 * 4 s) = 29&#39;700&#39;000 secondes + 400&#39;000 secondes = 30&#39;100&#39;000 secondes.&lt;/li&gt;
&lt;li&gt;Go-secondes totaux : 30&#39;100&#39;000 secondes * (1024 Mo / 1024 Mo) = 30&#39;100&#39;000 Go-s.&lt;/li&gt;
&lt;li&gt;Coût Durée : 30&#39;100&#39;000 Go-s * $0.0000166667/Go-s = &lt;strong&gt;$501.67&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coût total mensuel (Après) :&lt;/strong&gt; $2.00 + $501.67 = &lt;strong&gt;$503.67&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/details&gt;
&lt;p&gt;Dans ce scénario précis, l&amp;rsquo;augmentation est seulement de &lt;strong&gt;$1.67 par mois&lt;/strong&gt;. C&amp;rsquo;est effectivement minime, et cela confirme la communication d&amp;rsquo;AWS. Mais faites quand même attention, car l&amp;rsquo;impact &lt;em&gt;réel&lt;/em&gt; dépendra fortement de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La mémoire allouée à vos Lambdas (plus de mémoire = coût par ms plus élevé).&lt;/li&gt;
&lt;li&gt;La durée réelle de votre phase &lt;code&gt;INIT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Votre taux de cold start (peut être plus élevé si votre trafic est irrégulier).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il est donc judicieux de vérifier avec vos propres chiffres !&lt;/p&gt;
&lt;p&gt;Je vous mets ci-dessous un petit script qui vous permettra de rapidement tester cela de votre côté.&lt;/p&gt;
&lt;details&gt;
  &lt;summary&gt;Script Python&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;84
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calculate_lambda_costs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_invocations_per_month&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cold_start_rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;average_invocation_duration_sec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;average_init_duration_sec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;allocated_memory_gb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cost_per_million_requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cost_per_gb_second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0000166667&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;num_cold_starts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_invocations_per_month&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cold_start_rate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;num_warm_starts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_invocations_per_month&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_cold_starts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;request_cost&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;total_invocations_per_month&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1_000_000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_per_million_requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Duration cost BEFORE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;billed_duration_warm_starts_sec_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_warm_starts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;average_invocation_duration_sec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;billed_duration_cold_starts_sec_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_cold_starts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;average_invocation_duration_sec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_billed_duration_sec_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;billed_duration_warm_starts_sec_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;billed_duration_cold_starts_sec_before&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_gb_seconds_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_billed_duration_sec_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;allocated_memory_gb&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;duration_cost_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_gb_seconds_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_per_gb_second&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_monthly_cost_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request_cost&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;duration_cost_before&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Duration cost AFTER&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;billed_duration_warm_starts_sec_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_warm_starts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;average_invocation_duration_sec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;billed_duration_cold_starts_sec_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_cold_starts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;average_invocation_duration_sec&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;average_init_duration_sec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_billed_duration_sec_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;billed_duration_warm_starts_sec_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;billed_duration_cold_starts_sec_after&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_gb_seconds_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_billed_duration_sec_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;allocated_memory_gb&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;duration_cost_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_gb_seconds_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_per_gb_second&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;total_monthly_cost_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request_cost&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;duration_cost_after&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_monthly_cost_before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total_monthly_cost_after&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;display_results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cost_before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_after&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cost_difference&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_before&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;Monthly cost increase: $&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cost_difference&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.2f&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_difference&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;percentage_increase&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cost_difference&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inf&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Percentage increase: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;percentage_increase&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.2f&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;%&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS Lambda Cost Calculator (before/after Init Duration pricing change)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Please enter the values for your scenario or press Enter to use default values.&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;default_invocations&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10_000_000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;default_cold_start_rate&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.01&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 1%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;default_invocation_duration&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.0&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# seconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;default_init_duration&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# seconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;default_memory_gb&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.024&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 1024 MB (1.024 GB)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;invocations_str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Total invocations per month (default: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_invocations&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;): &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;total_invocations_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invocations_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;invocations_str&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default_invocations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cold_start_rate_str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Cold start rate (e.g., 0.01 for 1%, default: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_cold_start_rate&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;): &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cold_start_rate_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cold_start_rate_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cold_start_rate_str&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default_cold_start_rate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;invocation_duration_str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Average invocation duration in seconds (default: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_invocation_duration&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;): &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;invocation_duration_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invocation_duration_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;invocation_duration_str&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default_invocation_duration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;init_duration_str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Average initialization duration in seconds (default: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_init_duration&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;): &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;init_duration_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;init_duration_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;init_duration_str&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default_init_duration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;memory_gb_str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Memory allocated to Lambda in GB (e.g., 0.512 for 512MB, default: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_memory_gb&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;): &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;memory_gb_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memory_gb_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;memory_gb_str&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default_memory_gb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cost_before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calculate_lambda_costs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;total_invocations_per_month&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;total_invocations_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;cold_start_rate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cold_start_rate_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;average_invocation_duration_sec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invocation_duration_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;average_init_duration_sec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;init_duration_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;allocated_memory_gb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memory_gb_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;display_results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cost_before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cost_after&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;Error: Please enter valid numbers.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;An unexpected error occurred: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/details&gt;
&lt;h1 id=&#34;comment-surveiller-votre-phase-init-et-estimer-limpact-&#34;&gt;&lt;a href=&#34;#comment-surveiller-votre-phase-init-et-estimer-limpact-&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Comment surveiller votre phase INIT et estimer l&amp;rsquo;impact ?
&lt;/h1&gt;&lt;p&gt;Un script, c&amp;rsquo;est bien, mais si vous avez un paquet de Lambdas à checker, vous risquez de vous épuiser à la tâche.&lt;/p&gt;
&lt;p&gt;Heureusement, AWS nous donne quelques outils pour vérifier ça efficacement. En effet, comme vu plus haut, chaque Lambda va faire un &lt;code&gt;REPORT&lt;/code&gt; de son &lt;code&gt;Init Duration&lt;/code&gt;. Il nous est donc facile d&amp;rsquo;aggréger tout cela dans &lt;strong&gt;CloudWatch Logs Insights&lt;/strong&gt;. Et cerise sur le gâteau, AWS nous offre même la requête qui va bien.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;filter @type = &amp;#34;REPORT&amp;#34; and @billedDuration &amp;lt; (@duration + @initDuration) 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| stats sum((@memorySize/1000000/1024) * (@billedDuration/1000)) as BilledGBs, 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sum((@memorySize/1000000/1024) * ((ceil(@duration + @initDuration) - @billedDuration)/1000)) as UnbilledInitGBs, 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(UnbilledInitGBs/ (UnbilledInitGBs+BilledGBs)) as Ratio
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Gardez en mémoire que CloudWatch Logs Insights vous est facturé $0.005 par GB de data scanné (&lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/cloudwatch/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Plus qu&amp;rsquo;à lancer cette requête sur vos Lambdas (en utilisant le prefix &lt;code&gt;/aws/lambda&lt;/code&gt;), et vous obtiendrez le résultat suivant :&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;BilledGBs&lt;/th&gt;
          &lt;th&gt;UnbilledInitGBs&lt;/th&gt;
          &lt;th&gt;Ratio&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;512.8007&lt;/td&gt;
          &lt;td&gt;86.6699&lt;/td&gt;
          &lt;td&gt;0.1446&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Cette requête vous donne ainsi trois informations clés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BilledGBs&lt;/code&gt; : Le total de Go-secondes actuellement facturé.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UnbilledInitGBs&lt;/code&gt; : Le total de Go-secondes consommés pendant la phase &lt;code&gt;INIT&lt;/code&gt; qui n&amp;rsquo;étaient &lt;em&gt;pas&lt;/em&gt; facturés auparavant.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ratio&lt;/code&gt; : Le pourcentage que représentent ces Go-secondes &lt;code&gt;INIT&lt;/code&gt; non facturés par rapport au total des Go-secondes consommés.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans notre exemple, la part du coût de l&amp;rsquo;&lt;code&gt;INIT&lt;/code&gt; représente &lt;strong&gt;14%&lt;/strong&gt; de notre future facture ! Selon votre facture actuelle, cela pourrait être non négligeable.&lt;/p&gt;
&lt;h1 id=&#34;comprendre-et-optimiser-sa-lambda&#34;&gt;&lt;a href=&#34;#comprendre-et-optimiser-sa-lambda&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Comprendre et optimiser sa Lambda
&lt;/h1&gt;&lt;p&gt;Bon, vous savez que vous allez devoir sortir la carte bleue. Mais n&amp;rsquo;y a-t-il pas un levier d&amp;rsquo;action pour diminuer cette augmentation dans votre facture ?&lt;/p&gt;
&lt;p&gt;Je vous donne ici quelques conseils pour utiliser cette phase INIT au mieux et ainsi réduire vos futurs coûts.&lt;/p&gt;
&lt;h2 id=&#34;utiliser-stratégiquement-la-phase-init&#34;&gt;&lt;a href=&#34;#utiliser-strat%c3%a9giquement-la-phase-init&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Utiliser stratégiquement la phase INIT
&lt;/h2&gt;&lt;p&gt;Votre premier réflexe serait peut-être de vous dire qu&amp;rsquo;il faudrait enlever tout ce code &lt;code&gt;INIT&lt;/code&gt; (celui hors du handler) pour le mettre dans votre handler. Comme ça, plus de facturation de l&amp;rsquo;&lt;code&gt;INIT&lt;/code&gt; ! Mais non seulement vous ne feriez que déplacer le problème (car l&amp;rsquo;exécution de ce code vous sera tout de même facturé), cela sera encore pire, car maintenant, mêmes vos executions de Lambda &amp;ldquo;warm start&amp;rdquo; devront traiter ce code !&lt;/p&gt;
&lt;p&gt;Car oui, rappelons que le code dans la phase &lt;code&gt;INIT&lt;/code&gt; est exécuté &lt;em&gt;uniquement&lt;/em&gt; pendant les &amp;ldquo;cold start&amp;rdquo;. C&amp;rsquo;est donc l&amp;rsquo;endroit idéal pour faire des opérations d&amp;rsquo;initialisation coûteuses qui pourront être réutilisées par les invocations suivantes (&amp;ldquo;warm start&amp;rdquo;). Cela est même &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;recommandé par AWS&lt;/a&gt;. Ainsi, cette phase d&amp;rsquo;&lt;code&gt;INIT&lt;/code&gt; est parfaite pour :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Importer des librairies ou dépendances lourdes.&lt;/li&gt;
&lt;li&gt;Établir des connexions à d&amp;rsquo;autres services AWS (S3, DynamoDB, etc.) via les SDKs (&lt;code&gt;boto3&lt;/code&gt; pour Python).&lt;/li&gt;
&lt;li&gt;Créer des pools de connexions à des bases de données.&lt;/li&gt;
&lt;li&gt;Récupérer des paramètres ou des secrets depuis Systems Manager Parameter Store ou Secrets Manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Maximisez cette phase d&amp;rsquo;inititalisation pour réduire ainsi le temps d&amp;rsquo;exécutions des Lambdas qui elles tourneront en &amp;ldquo;warm start&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;optimiser-la-taille-du-package&#34;&gt;&lt;a href=&#34;#optimiser-la-taille-du-package&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Optimiser la taille du package
&lt;/h2&gt;&lt;p&gt;C&amp;rsquo;est souvent le levier le plus simple, car parfois, on importe un peu tout et n&amp;rsquo;importe quoi dans notre Lambda. Alors, soyez sûr de n&amp;rsquo;inclure que des dépendances strictement nécessaires. Veillez également à exclure tout ce qui est lié à votre environnement de développement (je ne vous dis pas le nombre de fois que j&amp;rsquo;ai trouvé un dossier &lt;code&gt;node_modules&lt;/code&gt; ou &lt;code&gt;tests&lt;/code&gt; dans des Lambdas&amp;hellip;). Enfin, n&amp;rsquo;hésitez pas à consulter les articles d&amp;rsquo;AWS, car &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/blogs/developer/reduce-lambda-cold-start-times-migrate-to-aws-sdk-for-javascript-v3/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;certains taclent directement le sujet des cold start&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;lambda-snapstart&#34;&gt;&lt;a href=&#34;#lambda-snapstart&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Lambda SnapStart
&lt;/h2&gt;&lt;p&gt;Disponible pour les runtimes &lt;strong&gt;Java, .NET et Python&lt;/strong&gt;, &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SnapStart&lt;/a&gt; est une fonctionnalité très intéressante pour combattre les &amp;ldquo;cold start&amp;rdquo;. Quand vous l&amp;rsquo;activez, Lambda prend un &amp;ldquo;snapshot&amp;rdquo; de l&amp;rsquo;environnement d&amp;rsquo;exécution initialisé &lt;em&gt;après&lt;/em&gt; la première phase &lt;code&gt;INIT&lt;/code&gt;. Pour les &amp;ldquo;cold start&amp;rdquo; suivants, la Lambda va restaurer ce snapshot au lieu de refaire toute la phase d&amp;rsquo;&lt;code&gt;INIT&lt;/code&gt;, ce qui vous fera gagner pas mal de temps.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;imagine qu&amp;rsquo;à la lecture de cette fonctionnalité, vous vous dites &amp;ldquo;mais enfin c&amp;rsquo;est super, je vais activer cette feature sur toutes mes Lambdas !&amp;rdquo;. Sauf qu&amp;rsquo;il y a quelques subtilités à connaître.&lt;/p&gt;
&lt;p&gt;Premièrement, SnapStart n&amp;rsquo;est pour l&amp;rsquo;instant &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html#snapstart-runtimes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;compatible qu&amp;rsquo;avec des versions bien précises de certains langages&lt;/a&gt; (Python 3.12 minimum, NodeJS pas supporté, &amp;hellip;). Idem pour les régions, &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html#snapstart-supported-regions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;seulement 9 d&amp;rsquo;entre elles supportent cette feature&lt;/a&gt; pour Python et .NET. Enfin, &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/lambda/pricing/#SnapStart_Pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cette feature n&amp;rsquo;est pas gratuite&lt;/a&gt;. Vérifiez bien le coût que cela pourrait engendrer si vous souhaitez l&amp;rsquo;activer sur vos Lambdas.
ialisation).&lt;/p&gt;
&lt;h2 id=&#34;provisioned-concurrency&#34;&gt;&lt;a href=&#34;#provisioned-concurrency&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Provisioned Concurrency
&lt;/h2&gt;&lt;p&gt;Si votre application a un trafic prévisible ou si la latence des cold start n&amp;rsquo;est pas envisageable, vous pouvez utiliser ce qu&amp;rsquo;on appelle la &amp;ldquo;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Provisioned Concurrency&lt;/a&gt;&amp;rdquo;. Vous demandez à votre Lambda de garder un certain nombre d&amp;rsquo;environnements d&amp;rsquo;exécution pré-initialisés (chauds) en permanence.&lt;/p&gt;
&lt;p&gt;Avantage : les requêtes arrivant sur ces instances provisionnées ne subissent &lt;em&gt;jamais&lt;/em&gt; de cold start. La phase &lt;code&gt;INIT&lt;/code&gt; est faite en amont, avant même la première requête.&lt;/p&gt;
&lt;p&gt;Inconvénient : vous payez pour la durée pendant laquelle ces environnements sont provisionnés, &lt;em&gt;qu&amp;rsquo;ils reçoivent des requêtes ou non&lt;/em&gt;. La phase &lt;code&gt;INIT&lt;/code&gt; est d&amp;rsquo;ailleurs facturée lors de la pré-initialisation.&lt;/p&gt;
&lt;p&gt;Là aussi, à vous de voir si cela vaut le coup d&amp;rsquo;activer cela sur certaines de vos Lambdas clées !&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion
&lt;/h1&gt;&lt;p&gt;Le changement de facturation de la phase &lt;code&gt;INIT&lt;/code&gt; de Lambda qui arrive le &lt;strong&gt;1er août 2025&lt;/strong&gt; est avant tout une standardisation. Pour la majorité des Lambdas, cela signifie que la durée de cette phase sera désormais ajoutée à la durée facturée lors des cold start.&lt;/p&gt;
&lt;p&gt;Même si l&amp;rsquo;impact financier sera probablement faible pour vous, c&amp;rsquo;est une excellente occasion de :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Comprendre&lt;/strong&gt; le cycle de vie de vos Lambdas et ce qui se passe pendant l&amp;rsquo;initialisation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mesurer&lt;/strong&gt; la durée de la phase &lt;code&gt;INIT&lt;/code&gt; de vos fonctions critiques grâce aux outils CloudWatch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimiser&lt;/strong&gt; cette phase si nécessaire, en réduisant la taille de vos packages, en utilisant SnapStart, ou en envisageant la Provisioned Concurrency pour des cas spécifiques.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alors, n&amp;rsquo;attendez pas le mois d&amp;rsquo;août ! Familiarisez-vous avec CloudWatch Logs Insights dès maintenant. Cela vous permettra d&amp;rsquo;identifier les Lambdas à optimiser en priorité et d&amp;rsquo;éviter toute mauvaise surprise sur votre facture AWS.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Comment j&#39;ai automatisé la création de mon blog dans le Cloud</title>
        <link>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-i-automated-my-blog-to-the-cloud/</link>
        <pubDate>Tue, 04 Mar 2025 07:30:00 +0100</pubDate>
        
        <guid>https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-i-automated-my-blog-to-the-cloud/</guid>
        <description>&lt;img src="https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-i-automated-my-blog-to-the-cloud/automated-blog.jpeg" alt="Featured image of post Comment j&#39;ai automatisé la création de mon blog dans le Cloud" /&gt;&lt;h1 id=&#34;le-commencement-et-la-fin&#34;&gt;&lt;a href=&#34;#le-commencement-et-la-fin&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le commencement et la fin
&lt;/h1&gt;&lt;p&gt;Quand j&amp;rsquo;ai envisagé de créer un blog pour la première fois, j&amp;rsquo;étais encore étudiant dans mon école d&amp;rsquo;ingénieurs. Et le monde des sites internets et des blogs était encore quelque chose de nouveau pour moi. Et lorsque je me suis finalement lancé dans l&amp;rsquo;aventure du blogging, c&amp;rsquo;est tout naturellement que je me suis tourné vers ce qui semblait être la meilleure solution à l&amp;rsquo;époque : WordPress.&lt;/p&gt;
&lt;p&gt;Quoi que l&amp;rsquo;on en dise, &lt;strong&gt;WordPress est une solution relativement simple d&amp;rsquo;usage&lt;/strong&gt; pour les débutants qui souhaitent créer leur premier site internet. Et ça tombe bien, car j&amp;rsquo;en faisais parti !&lt;/p&gt;
&lt;p&gt;Alors, armé d&amp;rsquo;un tout nouveau compte chez OVH, j&amp;rsquo;ai pû mettre en ligne mon &lt;a class=&#34;link&#34; href=&#34;https://blog.antoinedelia.fr&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;blog personnel&lt;/a&gt; en quelques cliques !&lt;/p&gt;
&lt;p&gt;Et puis, quelques années plus tard, quand me vint l&amp;rsquo;idée de publier un blog dédié à des sujets professionels, là encore, j&amp;rsquo;ai fait appel à mon bon vieil ami WordPress.&lt;/p&gt;
&lt;p&gt;Les mois passèrent, et l&amp;rsquo;idyle que je vivais avec WordPress commençait petit à petit à se ternir. Certes, rajouter des articles à travers l&amp;rsquo;UI de WordPress était pratique, mais pour ce qui était de gérer les backups, c&amp;rsquo;était une autre paire de manches. En plus, WordPress requiert une base de données pour fonctionner, ce qui rendait le tout très volumineux pour quelques articles, sans compter la facture qui venait avec.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/struggling_blog.jpeg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Les galères avec WordPress&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Je me rendais alors compte que, pour un blog aussi simple, et avec si peu de visites, il y avait certainement un moyen d&amp;rsquo;améliorer les choses.&lt;/p&gt;
&lt;h1 id=&#34;le-début-dun-nouveau-plan&#34;&gt;&lt;a href=&#34;#le-d%c3%a9but-dun-nouveau-plan&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Le début d&amp;rsquo;un nouveau plan
&lt;/h1&gt;&lt;p&gt;Je vais vous raconter ici le cheminement qui m&amp;rsquo;a amené au renouveau de mon blog sur lequel vous vous trouvez aujourd&amp;rsquo;hui. Si vous êtes seulement intéressé par les détails techniques, vous pouvez &lt;a class=&#34;link&#34; href=&#34;#c%c3%b4t%c3%a9-technique--l%c3%a9tat-actuel-des-choses&#34; &gt;avancer à la prochain section&lt;/a&gt;. Sinon, bonne lecture !&lt;/p&gt;
&lt;h2 id=&#34;la-découverte-dhugo&#34;&gt;&lt;a href=&#34;#la-d%c3%a9couverte-dhugo&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;La découverte d&amp;rsquo;Hugo
&lt;/h2&gt;&lt;p&gt;Avant de me mettre en quête d&amp;rsquo;un nouvel outil pour mon blog, j&amp;rsquo;ai d&amp;rsquo;abord réfléchi à ce dont j&amp;rsquo;avais réelement besoin.&lt;/p&gt;
&lt;p&gt;Mon blog était en fait assez rudimentaire : une page d&amp;rsquo;accueil qui listait les différents articles, pas de JavaScript tarabiscoté dans les parages, et aucun besoin d&amp;rsquo;un backend pour gérer une API. Au final, &lt;strong&gt;l&amp;rsquo;utilisation d&amp;rsquo;une base de données était-elle nécessaire ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Il y avait aussi une chose importante à garder en mémoire. Je suis un ingénieur, ce qui fait de moi par définition, un bien piètre designer. Je voulais à tout prix éviter d&amp;rsquo;avoir à gérer le CSS de mon blog : je voualais me concenter sur le contenu, plutôt que sur le style.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc commencé mes recherches, dans l&amp;rsquo;espoir de trouver un outil qui répondrait à ces critères. Et il ne m&amp;rsquo;a pas fallu bien longtemps avant de tomber sur la perle rare : &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/hugo.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Hugo logo&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;À peine eus-je atterri sur le site d&amp;rsquo;Hugo que je fus accueilli par cet intriguant message : &lt;strong&gt;Le framework le plus rapide du monde pour générer des sites web&lt;/strong&gt;. On peut dire que cela a piqué ma curiosité, et je me pressa d&amp;rsquo;aller fouiller dans la documentation. Et je n&amp;rsquo;allais pas être déçu.&lt;/p&gt;
&lt;p&gt;Hugo se charge de convertir des articles au format markdown (comme l&amp;rsquo;on trouve sur les README de GitHub par exemple) vers le format HTML. Qui plus est, il existe une &lt;a class=&#34;link&#34; href=&#34;https://themes.gohugo.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;miriade de thèmes&lt;/a&gt; mis à disposition, ce qui me laissait l&amp;rsquo;embarras du choix, sans avoir besoin de designer quoi que ce soit !&lt;/p&gt;
&lt;p&gt;Sans perdre une seconde, je m&amp;rsquo;empressai de convertir mon blog WordPress vers un site Hugo (j&amp;rsquo;ai utilisé pour ça un super petit script intitulé &lt;a class=&#34;link&#34; href=&#34;https://github.com/SchumacherFM/wordpress-to-hugo-exporter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;wordpress-to-hugo-exporter&lt;/a&gt; qui convertit une base de données WordPress en fichiers markdown avec l&amp;rsquo;arborescence requise pour Hugo).&lt;/p&gt;
&lt;p&gt;Mon site Hugo était désormais prêt ! Il fallait maintenant trouver un moyen de l&amp;rsquo;héberger quelque part.&lt;/p&gt;
&lt;h2 id=&#34;un-hébergeur-à-la-hauteur--aws&#34;&gt;&lt;a href=&#34;#un-h%c3%a9bergeur-%c3%a0-la-hauteur--aws&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Un hébergeur à la hauteur : AWS
&lt;/h2&gt;&lt;p&gt;En même temps que je me creusais la tête pour trouver une alternative pour mon blog, j&amp;rsquo;ai eu une opportunité professionnelle qui m&amp;rsquo;a amené à travailler dans une entreprise spécialisée dans le Cloud, et plus particulièrement &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/aws.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;AWS logo&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;À l&amp;rsquo;époque, le Cloud était tout nouveau pour moi. Mais j&amp;rsquo;en entendais tellement parler, que je voulais connaître la raison de cet engouement. Était-ce vraiment un &amp;ldquo;game-changer&amp;rdquo;, comme certains le disaient, ou était-ce encore un de ces mots-clés techniques qui faisait le buzz ?&lt;/p&gt;
&lt;p&gt;Pour vous la faire courte, &lt;strong&gt;AWS était (et est toujours) absolument incroyable !&lt;/strong&gt; Ce n&amp;rsquo;était pas seulement la découverte d&amp;rsquo;un nouvel outil, il s&amp;rsquo;agissait là d&amp;rsquo;un changement de paradigme qui ne me ferait plus jamais aborder un problème de la même manière (si vous ne connaissez pas AWS et pensez que j&amp;rsquo;en fais trop, attendez de vous y mettre&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Plus j&amp;rsquo;en apprenais sur AWS et la multitude de services qui le composait, plus je me disais : &lt;strong&gt;n&amp;rsquo;y a-t-il pas un moyen pour moi d&amp;rsquo;utiliser le Cloud pour mon blog ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Avec cette idée en tête, je commençais à me renseigner sur toutes les options qu&amp;rsquo;offrait AWS. Et compte tenu de ma récente découverte d&amp;rsquo;Hugo, mon site n&amp;rsquo;avait ni besoin de PHP, ni d&amp;rsquo;une base de données pour fonctionner. Il s&amp;rsquo;agissait maintenant d&amp;rsquo;un site statique qui, à première vue, pouvait très bien être déployé dans un bucket S3.&lt;/p&gt;
&lt;p&gt;Et non seulement AWS offre une &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;documentation sur l&amp;rsquo;hébergement d&amp;rsquo;un site statique dans un bucket S3&lt;/a&gt;, mais &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/s3/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;le coût de stockage d&amp;rsquo;un site si léger ne représentait que quelques centimes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avais trouvé là une manière simple et peu coûteuse d&amp;rsquo;héberger mon site.&lt;/p&gt;
&lt;p&gt;Le dernier point qui me chiffonait, est que pour mettre en place tout cela, je devais créer un bucket AWS S3, le configurer convenablement, rajouter le CDN AWS CloudFront, prendre en compte les certificats via AWS ACM, et finalement créer une entrée DNS dans AWS Route53. Tant d&amp;rsquo;actions qui, si réalisées manuellement, pouvaient être difficiles à reproduire si jamais je venais à accidentellement supprimer mon compte AWS.&lt;/p&gt;
&lt;p&gt;Il me fallait donc maintenant un moyen simple et robuste de configurer cette infrastructure.&lt;/p&gt;
&lt;h2 id=&#34;terraform-à-la-rescousse&#34;&gt;&lt;a href=&#34;#terraform-%c3%a0-la-rescousse&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Terraform à la rescousse
&lt;/h2&gt;&lt;p&gt;Quand vous commencez à apprendre le Cloud, vous allez généralement entendre parler d&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://fr.wikipedia.org/wiki/Infrastructure_as_code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Infrastructure as Code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le principe est simple : décrire son infrastructure Cloud avec&amp;hellip; du code ! (oui, comme son nom l&amp;rsquo;indique).&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;avantage d&amp;rsquo;utiliser un outil d&amp;rsquo;IaC, c&amp;rsquo;est que vous allez pouvoir garder en mémoire les changements effectués sur votre infrastructure, et pouvoir ainsi avoir un historique de toutes les modifications effectuées (un peu comme vous pouvez le faire avec du code classique sur GitHub).&lt;/p&gt;
&lt;p&gt;Imaginons par exemple que quelqu&amp;rsquo;un décide de changer la configuration d&amp;rsquo;un service AWS. Cette personne se connecte sur la console AWS et effectue ces modifications. Mais après plusieurs essais infructueux, cette personne décide de laisser tomber pour le moment, et de revenir en arrière. Mais voilà, elle n&amp;rsquo;est plus vraiment sûr de la manière dont le service était configuré au départ ! Et à moins d&amp;rsquo;avoir pris note de l&amp;rsquo;état initial, cette personne n&amp;rsquo;a plus qu&amp;rsquo;à deviner à coups de plusieurs essais l&amp;rsquo;état dans lequel remettre ce service.&lt;/p&gt;
&lt;p&gt;Tout cela aurait pû être évité si le service avait initialement été configuré avec un outil d&amp;rsquo;Infrastructure as Code. Si tel avait été le cas, un petit coup de déploiement automatique aurait fait l&amp;rsquo;affaire !&lt;/p&gt;
&lt;p&gt;Des outils d&amp;rsquo;IaC, il en existe un paquet. Mais comment ne pas parler du plus populaire, de celui qui a rendu cette pratique commune dans le milieu du Cloud : &lt;a class=&#34;link&#34; href=&#34;https://www.terraform.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/terraform.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Terraform logo&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Terraform est donc un outil d&amp;rsquo;Infrastructure as Code avec une approche déclarative, ce qui signifie que c&amp;rsquo;est à vous de déclarer l&amp;rsquo;état dans lequel vous souhaitez déployer votre infrastructure. Pour cela, il faut utiliser un langage bien particulier : le hcl (pour HashiCorp Configuration Language). Voici par exemple la création d&amp;rsquo;un bucket S3 via Terraform.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_s3_bucket&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;bucket&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;my-tf-test-bucket&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;tags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;My bucket&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Environment&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Dev&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Revenons maintenant à mon blog ! Terraform me semblait l&amp;rsquo;outil parfait pour configurer mon infrastructure qui accueillerait mon blog. Je n&amp;rsquo;avais plus qu&amp;rsquo;à passer par une étape d&amp;rsquo;architecture pour savoir de quels services AWS j&amp;rsquo;aurais besoin et comment les connecter entre eux, avant de mettre la main dans le code pour définir tout cela en langage Terraform.&lt;/p&gt;
&lt;p&gt;Voici d&amp;rsquo;ailleurs le diagramme d&amp;rsquo;architecture que j&amp;rsquo;ai initialement crée pour l&amp;rsquo;occasion.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/blog_architecture_diagram.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Diagramme d’architecture de mon blog sur AWS, déployé par Terraform&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Tout cela était parfait, mais je me rendis vite compte d&amp;rsquo;une chose. À chaque fois que j&amp;rsquo;allais rajouter un article, ou que je devais modifier mon infrastructure, il me fallait cloner le projet sur mon ordinateur, et effectuer tout un tas d&amp;rsquo;opérations manuelles.&lt;/p&gt;
&lt;p&gt;Autant vous dire que cela ne me plaisait pas du tout, et je comptais bien y remédier !&lt;/p&gt;
&lt;h2 id=&#34;oubliez-les-copier-coller-avec-github-actions&#34;&gt;&lt;a href=&#34;#oubliez-les-copier-coller-avec-github-actions&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Oubliez les copier-coller avec GitHub Actions
&lt;/h2&gt;&lt;p&gt;Comme je le disais juste au-dessus, mon site était fin prêt. La dernière étape qui me manquait concernait &lt;strong&gt;le déploiement&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour l&amp;rsquo;instant, quand je voulais créer un nouvel article, il me fallait build le site Hugo à la main, et déplacer les fichiers générés dans mon bucket S3. Quel terrible gâchis de temps et d&amp;rsquo;énergie !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc creusé le sujet des pipelines CI/CD afin de me rendre la vie plus simple (si le sujet vous intéresse, je vous conseille &lt;a class=&#34;link&#34; href=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/fr/posts/2025/how-we-built-a-cicd-strategy-that-onboards-100-python-projects-in-under-a-minute/&#34; &gt;mon article sur la mise en place d&amp;rsquo;une stratégie CI/CD&lt;/a&gt;). Et bien que Jenkins essayait à tout prix de se distinguer, je suis parti sur ce qui semblait être le plus logique : &lt;a class=&#34;link&#34; href=&#34;https://github.com/features/actions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Actions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/github_actions.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;GitHub Actions logo&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Les GitHub Actions sont en fait des pipelines CI/CD qui sont définies directement dans votre repository GitHub. Le gros avantage, est que vous n&amp;rsquo;avez pas besoin de créer un compte supplémentaire ou d&amp;rsquo;installer quoi que ce soit, tout est inclus ! En plus de ça, GitHub Actions utilise une syntaxe YAML très facile à comprendre (contrairement à Jenkins et son groovy des enfers !).&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est donc assez facilement que j&amp;rsquo;ai pû créer une pipeline qui me reconfigure Terraform si mon infrastructure a été modifiée, et qui me build et deploy automatiquement mon blog sur mon bucket S3 en cas de modifications ou ajout d&amp;rsquo;un article.&lt;/p&gt;
&lt;p&gt;Toutes les steps de la pipeline sont au vert, mission accomplie !&lt;/p&gt;
&lt;h1 id=&#34;côté-technique--létat-actuel-des-choses&#34;&gt;&lt;a href=&#34;#c%c3%b4t%c3%a9-technique--l%c3%a9tat-actuel-des-choses&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Côté technique : L&amp;rsquo;état actuel des choses
&lt;/h1&gt;&lt;p&gt;Mon blog est désormais automatisé et se déploie sur AWS automatiquement !&lt;/p&gt;
&lt;p&gt;Si vous voulez plonger directement dedans, tout est publique sur mon repository GitHub : &lt;a class=&#34;link&#34; href=&#34;https://github.com/antoinedelia/cloud-optimist&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/antoinedelia/cloud-optimist&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mais laissez-moi détailler un peu tout ça.&lt;/p&gt;
&lt;h2 id=&#34;structure-du-projet&#34;&gt;&lt;a href=&#34;#structure-du-projet&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Structure du projet
&lt;/h2&gt;&lt;p&gt;La structure de mon projet est comme suit :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cloud-optimist/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── .github/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── workflows/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       └── main.yml  &lt;span class=&#34;c1&#34;&gt;# GitHub Actions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── cloud/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── ...  &lt;span class=&#34;c1&#34;&gt;# Mon blog Hugo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── terraform/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── ...  &lt;span class=&#34;c1&#34;&gt;# La configuration Terraform&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Comme vous le voyez, je sépare ce projet en trois dossiers clés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.github&lt;/code&gt; : contient le fichier &lt;code&gt;main.yml&lt;/code&gt; qui définit les étapes CI/CD de la GitHub Actions&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cloud&lt;/code&gt; : contient mon blog Hugo&lt;/li&gt;
&lt;li&gt;&lt;code&gt;terraform&lt;/code&gt; : contient toute l&amp;rsquo;infrastructure Terraform&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;la-github-actions&#34;&gt;&lt;a href=&#34;#la-github-actions&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;La GitHub Actions
&lt;/h2&gt;&lt;p&gt;Ma GitHub Actions est assez simple, et se décompose en plusieurs étapes.&lt;/p&gt;
&lt;h3 id=&#34;les-étapes-de-préparation&#34;&gt;&lt;a href=&#34;#les-%c3%a9tapes-de-pr%c3%a9paration&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Les étapes de préparation
&lt;/h3&gt;&lt;p&gt;Regardons d&amp;rsquo;abord le haut du fichier.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Build and Deploy&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;master&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pull_request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;build-and-deploy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Build &amp;amp; Deploy&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;production&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;defaults&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bash&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;cloud&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ici, je dis à GitHub de lancer la pipeline uniquement sur la branch &lt;code&gt;master&lt;/code&gt;, ou s&amp;rsquo;il s&amp;rsquo;agit d&amp;rsquo;une Pull Request. Je vous rassure, je ne déplois rien en production via une Pull Request. Vous verrez un peu plus bas, que cela me permet uniquement de build mon blog afin de tester que tout va bien, mais le déploiement ne sera effectué qu&amp;rsquo;une fois les changements mergés sur la branch &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;indique également à GitHub d&amp;rsquo;utiliser &lt;code&gt;bash&lt;/code&gt;, et de se baser par défaut dans le dossier &lt;code&gt;cloud&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Voyons maintenant la suite :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;dorny/paths-filter@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          web:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;            - &amp;#39;cloud/**&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          terraform:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;            - &amp;#39;terraform/**&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Cette première étape est cruciale si vous voulez accélérer vos temps de CI/CD ainsi qu&amp;rsquo;économiser de l&amp;rsquo;argent.&lt;/p&gt;
&lt;p&gt;Je me sers de l&amp;rsquo;actions &lt;a class=&#34;link&#34; href=&#34;https://github.com/dorny/paths-filter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;dorny/paths-filter&lt;/a&gt; qui me permet de &lt;strong&gt;détecter quels fichiers ont été modifiés lors du dernier commit&lt;/strong&gt;. Dans mon cas, je regarde en particulier les dossiers &lt;code&gt;cloud&lt;/code&gt; et &lt;code&gt;terraform&lt;/code&gt;. Ainsi, si je ne détecte pas de changements côté Terraform, aucun besoin de lancer l&amp;rsquo;étape qui va reconfigurer mon infrastructure. Idem, si le dossier &lt;code&gt;cloud&lt;/code&gt; est intact, inutile de build et deploy le blog. Cela vous sauvera quelques centimes liés au coût de transfert de fichiers vers AWS (pas la peine de me remercier !).&lt;/p&gt;
&lt;p&gt;La section suivante parle d&amp;rsquo;elle-même.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Checkout the repository to the GitHub Actions runner&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Checkout&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Update Git Submodules&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;git submodule update --init --recursive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Je viens récupérer le contenu de mon repository et m&amp;rsquo;assure de mettre à jour les submodules. Cette dernière étape me servait du temps où j&amp;rsquo;utilisais les submodules pour mes thèmes Hugo. J&amp;rsquo;utilise désormais les &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/hugo-modules/use-modules/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo Modules&lt;/a&gt;, et je pourrais donc zapper cette étape.&lt;/p&gt;
&lt;h3 id=&#34;les-étapes-terraform&#34;&gt;&lt;a href=&#34;#les-%c3%a9tapes-terraform&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Les étapes Terraform
&lt;/h3&gt;&lt;p&gt;Passons à la partie Terraform :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Setup Terraform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.terraform == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;hashicorp/setup-terraform@v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cli_config_credentials_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.TF_API_TOKEN }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Terraform Init&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.terraform == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./terraform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;terraform init&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Checks that all Terraform configuration files adhere to a canonical format&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Terraform Format&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.terraform == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./terraform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;terraform fmt -check&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Generates an execution plan for Terraform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Terraform Plan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.terraform == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./terraform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;terraform plan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# On push to master, build or change infrastructure according to Terraform configuration files&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Terraform Apply&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./terraform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.terraform == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; github.ref == &amp;#39;refs/heads/master&amp;#39; &amp;amp;&amp;amp; github.event_name == &amp;#39;push&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;terraform apply -auto-approve&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;C&amp;rsquo;est déjà bien plus long ! Analysons ça étape par étape.&lt;/p&gt;
&lt;p&gt;La première chose qui devrait attirer votre attention, c&amp;rsquo;est cette ligne :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.terraform == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Vous vous rappelez, c&amp;rsquo;est ce qui permet de dire si des fichiers ont été modifiés dans le dossier &lt;code&gt;terraform&lt;/code&gt;. Je vérifie donc ici si j&amp;rsquo;ai besoin de lancer ces étapes ou non.&lt;/p&gt;
&lt;p&gt;Ensuite, je lance quelques commandes basiques de Terraform : un &lt;code&gt;terraform init&lt;/code&gt; pour initialiser mon projet, un &lt;code&gt;terraform fmt -check&lt;/code&gt; pour m&amp;rsquo;assurer que mon code est tout joli, et enfin un &lt;code&gt;terraform plan&lt;/code&gt; pour voir les changements à effectuer.&lt;/p&gt;
&lt;p&gt;Reste une dernière étape, et pas des moindres : le &lt;code&gt;terraform apply -auto-approve&lt;/code&gt;, qui permettra de déployer les changements. Mais si vous êtes attentifs, vous remarquerez que j&amp;rsquo;ai rajouté deux conditions :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;github.ref == &amp;#39;refs/heads/master&amp;#39; &amp;amp;&amp;amp; github.event_name == &amp;#39;push&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Cela me garantit que &lt;strong&gt;cette étape ne sera uniquement lancée si l&amp;rsquo;action est un &lt;code&gt;push&lt;/code&gt; sur la branch &lt;code&gt;master&lt;/code&gt;&lt;/strong&gt;. Ainsi, aucun risque de déploiement inopportun si je décide de travailler sur une autre branch ou sur une Pull Request. Ouf !&lt;/p&gt;
&lt;h3 id=&#34;les-étapes-hugo-et-aws&#34;&gt;&lt;a href=&#34;#les-%c3%a9tapes-hugo-et-aws&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Les étapes Hugo et AWS
&lt;/h3&gt;&lt;p&gt;Maintenant que mon infrastructure est au point, il est temps de publier mon blog !&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Build&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/setup-node@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.web == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sudo wget https://github.com/gohugoio/hugo/releases/download/v0.142.0/hugo_extended_0.142.0_linux-amd64.deb -O hugo.deb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sudo dpkg --install ./hugo.deb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;hugo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Deploy to AWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jakejarvis/s3-sync-action@master&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.web == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; github.ref == &amp;#39;refs/heads/master&amp;#39; &amp;amp;&amp;amp; github.event_name == &amp;#39;push&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--&lt;span class=&#34;l&#34;&gt;acl public-read --follow-symlinks --delete&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AWS_S3_BUCKET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_S3_BUCKET }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AWS_REGION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;eu-west-1&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;SOURCE_DIR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cloud/public/&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Comme pour Terraform, nous vérifions si des modifications ont été effectuées au niveau du blog.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;steps.filter.outputs.web == &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ensuite, je récupère une version extended d&amp;rsquo;Hugo directement depuis la release GitHub, ici la version v0.142.0. Je l&amp;rsquo;installe et build mon site en lançant la commande &lt;code&gt;hugo&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cette étape pourrait être simplifiée avec l&amp;rsquo;utilisation de l&amp;rsquo;actions &lt;a class=&#34;link&#34; href=&#34;https://github.com/peaceiris/actions-hugo&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;peaceiris/actions-hugo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enfin, j&amp;rsquo;utilise l&amp;rsquo;actions &lt;a class=&#34;link&#34; href=&#34;https://github.com/jakejarvis/s3-sync-action&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;jakejarvis/s3-sync-action&lt;/a&gt; (je me rends compte en écrivant cet article que cette actions a été archivée quelques jours plus tôt, aïe ! &amp;ndash; je rajouterai un edit plus tard pour parler d&amp;rsquo;une alternative) pour déplacer mon blog vers mon bucket S3.&lt;/p&gt;
&lt;p&gt;Bien sûr, il vous faudra stocker vos credentials au niveau de votre repository GitHub pour autoriser cette opération vers AWS, mais rien de bien sorcier !&lt;/p&gt;
&lt;h2 id=&#34;la-partie-terraform&#34;&gt;&lt;a href=&#34;#la-partie-terraform&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;La partie Terraform
&lt;/h2&gt;&lt;p&gt;Concernant la partie Terraform, je vais essayer d&amp;rsquo;être bref, car il n&amp;rsquo;y a rien de bien compliqué.&lt;/p&gt;
&lt;p&gt;Une particularité dans mon cas, c&amp;rsquo;est que &lt;strong&gt;j&amp;rsquo;aime séparer mes fichiers &lt;code&gt;.tf&lt;/code&gt; en fonction des services AWS utilisés&lt;/strong&gt;, plutôt que d&amp;rsquo;avoir un unique fichier &lt;code&gt;main.tf&lt;/code&gt; qui peut vite devenir difficile à lire. J&amp;rsquo;ai donc un fichier &lt;code&gt;s3.tf&lt;/code&gt; pour les ressources liées au service S3, un &lt;code&gt;cloudfront.tf&lt;/code&gt; pour tout ce qui est lié au service CloudFront, etc.&lt;/p&gt;
&lt;p&gt;Un détail important, c&amp;rsquo;est qu&amp;rsquo;&lt;strong&gt;il est nécessaire de définir à minima la region &lt;code&gt;us-east-1&lt;/code&gt;&lt;/strong&gt;, car c&amp;rsquo;est dans cette region que vous devez créer vos certificats ACM. Pour le reste, toutes mes ressources sont créées dans la region &lt;code&gt;eu-west-1&lt;/code&gt;. J&amp;rsquo;utilise pour cela les &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/providers/configuration#alias-multiple-provider-configurations&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;alias Terraform&lt;/a&gt;. Voici un exemple :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# La configuration par défaut : les ressources qui commencent par `aws_` utiliseront ce provider
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;provider&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;region&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;eu-west-1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;provider&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;region&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-east-1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;alias&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us_east_1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_s3_bucket&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;site&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;bucket&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bucket_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;force_destroy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_acm_certificate&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cert&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;provider&lt;/span&gt;                  &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;aws&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;us_east_1&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;  # Utilise le provider AWS dans us-east-1 via son alias
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;domain_name&lt;/span&gt;               &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;domain_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;subject_alternative_names&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;*.&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;domain_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;validation_method&lt;/span&gt;         &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DNS&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;la-partie-hugo&#34;&gt;&lt;a href=&#34;#la-partie-hugo&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;La partie Hugo
&lt;/h2&gt;&lt;p&gt;Mon blog Hugo se base sur le theme &lt;a class=&#34;link&#34; href=&#34;https://themes.gohugo.io/themes/hugo-theme-stack/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Stack&lt;/a&gt;. Il existe d&amp;rsquo;ailleurs un &lt;a class=&#34;link&#34; href=&#34;https://github.com/CaiJimmy/hugo-theme-stack-starter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;template GitHub&lt;/a&gt; qui vous permet en un clic de récupérer le squelette du blog, et de l&amp;rsquo;adapter selon vos envies, ou de tout simplement vous concentrer directement sur vos articles.&lt;/p&gt;
&lt;p&gt;Pas grande chose de plus à dire sur cette partie, si ce n&amp;rsquo;est que je vous encourage à voir le fonctionnement des &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/hugo-modules/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo Modules&lt;/a&gt;, ce qui vous évitera de gérer vos thèmes via un submodule (et qui vous simplifiera la vie lors de la mise à jour du thème).&lt;/p&gt;
&lt;h1 id=&#34;pistes-daméliorations&#34;&gt;&lt;a href=&#34;#pistes-dam%c3%a9liorations&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Pistes d&amp;rsquo;améliorations
&lt;/h1&gt;&lt;p&gt;Bien que je sois très satisfait du résultat final, j&amp;rsquo;ai noté quelques points qui pourraient être améliorés dans le futur.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;abord, j&amp;rsquo;ai vu qu&amp;rsquo;Hugo dispose d&amp;rsquo;une commande &lt;code&gt;deploy&lt;/code&gt; qui est capable de déployer directement un blog sur un bucket S3. Parfait ! Je dois donc creuser le sujet de &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/hosting-and-deployment/hugo-deploy/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo Deploy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enfin, même si l&amp;rsquo;hébergement dans AWS est peu coûteux (moins de 2$ par mois), il n&amp;rsquo;en est pas moins gratuit. Or, il serait tout à fait possible d&amp;rsquo;utiliser les &lt;a class=&#34;link&#34; href=&#34;https://pages.github.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Pages&lt;/a&gt; pour rendre ce blog accessible, et profiter de GitHub comme hébergement (là-dessus, je suis un peu moins emballé, car je ne pourrais plus me la péter avec mes jolis diagrammes AWS&amp;hellip;).&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion
&lt;/h1&gt;&lt;p&gt;Et voilà, vous savez tout !&lt;/p&gt;
&lt;p&gt;De mes débuts avec WordPress, qui, bien que pratique, présentait des faiblesses du point de vue backup, maintenance et déploiement.&lt;/p&gt;
&lt;p&gt;De mes recherches pour trouver une stack technique parfaite : AWS, Terraform, Hugo et GitHub Actions, tout ça pour permettre un déploiement rapide et à moindre coût !&lt;/p&gt;
&lt;p&gt;Quand je compare avec ce que j&amp;rsquo;avais à l&amp;rsquo;époque, je ne suis que trop heureux d&amp;rsquo;avoir sauté le pas !&lt;/p&gt;
&lt;p&gt;Et vous aussi, vous avez maintenant toutes les informations pour créer un blog à vous, et déployer tout ça en un clin d&amp;rsquo;oeil !&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Happy blogging !&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://antoinedelia.github.io/cloud-optimist/pr-144/img/how-i-automated-my-blog-to-the-cloud/happy_blog.jpeg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Réussite de la migration de mon blog vers le Cloud&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
