<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: La Formule Nuagique</title>
    <description>The latest articles on DEV Community by La Formule Nuagique (@laformulenuagique).</description>
    <link>https://dev.to/laformulenuagique</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F8700%2F8aadeea2-cac8-4cd9-87fc-de2f3da7ad53.png</url>
      <title>DEV Community: La Formule Nuagique</title>
      <link>https://dev.to/laformulenuagique</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/laformulenuagique"/>
    <language>en</language>
    <item>
      <title>Mettre à jour GKE sans sueurs froides : La stratégie Terraform Zero-Downtime</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Wed, 11 Feb 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/mettre-a-jour-gke-sans-sueurs-froides-la-strategie-terraform-zero-downtime-45m2</link>
      <guid>https://dev.to/laformulenuagique/mettre-a-jour-gke-sans-sueurs-froides-la-strategie-terraform-zero-downtime-45m2</guid>
      <description>&lt;p&gt;Dans la vie d'un ingénieur Cloud, peu de notifications génèrent autant d'anxiété que : "GKE version 1.27 will reach end of life soon". La mise à jour de Kubernetes est souvent perçue comme une opération à cœur ouvert. Pourtant, avec une stratégie Terraform rigoureuse, c'est un non-événement.&lt;/p&gt;

&lt;p&gt;Chez La Formule Nuagique, nous voyons trop souvent des clusters "Snowflake" mis à jour manuellement via la console Google Cloud. C'est une erreur critique en production. Une mise à jour GKE doit être déclarative, prévisible et codifiée.&lt;/p&gt;

&lt;p&gt;Voici comment on architecture les montées de version GKE pour garantir la continuité de service, code Terraform à l'appui.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. La règle d'or : Dissocier control plane et node pools
&lt;/h2&gt;

&lt;p&gt;Sur GKE, la mise à jour se fait en deux temps : le Master (Control Plane) puis les Nodes (Workers). Terraform doit refléter cette réalité.&lt;/p&gt;

&lt;p&gt;Une erreur classique est de tout vouloir mettre à jour en même temps. La bonne pratique consiste à piloter la version via des variables distinctes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le control plane
&lt;/h3&gt;

&lt;p&gt;La mise à jour du master est gérée par Google. Elle ne cause pas de downtime applicatif, mais l'API server peut être indisponible quelques minutes (attention à vos pipelines CI/CD).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_container_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"prod-cluster-01"&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"europe-west1"&lt;/span&gt;

  &lt;span class="c1"&gt;# On fixe la version mineure, mais on laisse Google gérer les patchs de sécu&lt;/span&gt;
  &lt;span class="nx"&gt;min_master_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.29"&lt;/span&gt; 

  &lt;span class="c1"&gt;# ... configuration réseau ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Le conseil de l'expert : Ne spécifiez pas la version complète (ex: 1.29.1-gke.1589000) dans min_master_version sauf nécessité absolue. Ciblez la mineure (1.29) pour bénéficier des auto-upgrades de sécurité critiques sans changer votre code tous les jours.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Les node pools : Là où le danger réside
&lt;/h2&gt;

&lt;p&gt;C'est ici que votre trafic de production est traité. Si vous mettez à jour brutalement, les pods sont tués. Si vos nœuds redémarrent tous en même temps, c'est l'incident majeur.&lt;/p&gt;

&lt;p&gt;Pour éviter cela, nous utilisons une stratégie de surge configurée directement dans Terraform.&lt;/p&gt;

&lt;h3&gt;
  
  
  L'approche max_surge et max_unavailable
&lt;/h3&gt;

&lt;p&gt;L'objectif est de créer de nouveaux nœuds (en version N+1) avant de détruire les anciens (version N).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_container_node_pool"&lt;/span&gt; &lt;span class="s2"&gt;"primary_nodes"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pool-standard-v1"&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"europe-west1"&lt;/span&gt;
  &lt;span class="nx"&gt;cluster&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_container_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;

  &lt;span class="c1"&gt;# La version des noeuds suit celle du master, ou peut être gérée manuellement&lt;/span&gt;
  &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.29"&lt;/span&gt;

  &lt;span class="nx"&gt;upgrade_settings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# Combien de nœuds supplémentaires peut-on créer temporairement ?&lt;/span&gt;
    &lt;span class="c1"&gt;# Ici, on ajoute 1 nœud en plus pour absorber la charge pendant la migration.&lt;/span&gt;
    &lt;span class="nx"&gt;max_surge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="c1"&gt;# Combien de nœuds peuvent être indisponibles en même temps ?&lt;/span&gt;
    &lt;span class="c1"&gt;# 0 = On veut ABSOLUMENT maintenir la capacité actuelle.&lt;/span&gt;
    &lt;span class="nx"&gt;max_unavailable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;node_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;machine_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"e2-standard-4"&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;L'analyse de Benoît Garçon : Avec max_unavailable = 0 et max_surge = 1, GKE va créer un nouveau nœud, attendre qu'il soit "Ready", déplacer les pods dessus (Drain), et seulement ensuite détruire l'ancien nœud. C'est plus lent, mais c'est l'assurance-vie de votre production.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Les fenêtres de maintenance
&lt;/h2&gt;

&lt;p&gt;Ne laissez jamais Google décider quand la mise à jour s'applique. Vous ne voulez pas d'un upgrade le lundi matin à 9h00 lors du pic de charge.&lt;/p&gt;

&lt;p&gt;Utilisez le bloc maintenance_policy dans votre ressource google_container_cluster :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_container_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="nx"&gt;maintenance_policy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;recurring_window&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;start_time&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-01T02:00:00Z"&lt;/span&gt; &lt;span class="c1"&gt;# 2h du matin UTC&lt;/span&gt;
      &lt;span class="nx"&gt;end_time&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-01T06:00:00Z"&lt;/span&gt; &lt;span class="c1"&gt;# Jusqu'à 6h du matin&lt;/span&gt;
      &lt;span class="nx"&gt;recurrence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"FREQ=WEEKLY;BYDAY=SA,SU"&lt;/span&gt; &lt;span class="c1"&gt;# Uniquement le week-end&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Le piège invisible : Les Pod Disruption Budgets
&lt;/h2&gt;

&lt;p&gt;Même avec le meilleur code Terraform, votre montée de version peut rester bloquée indéfiniment. Pourquoi ? À cause des Pod Disruption Budgets.&lt;/p&gt;

&lt;p&gt;Si vous avez une application avec 3 réplicas et un PDB qui exige minAvailable: 3, GKE ne pourra jamais drainer le nœud pour le mettre à jour.&lt;/p&gt;

&lt;p&gt;La checklist de pré-upgrade de La Formule Nuagique :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Vérifier les APIs dépréciées : Utilisez l'outil kubent ou les "Deprecation Insights" dans la console GCP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Audit des PDB : Assurez-vous qu'ils autorisent au moins 1 pod indisponible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StatefulSets : Soyez extrêmement vigilant avec les bases de données hébergées dans Kubernetes, les volumes (PVC) peuvent être lents à se détacher/rattacher.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion : L'automatisation comme standard
&lt;/h2&gt;

&lt;p&gt;La montée de version GKE ne doit pas être un projet héroïque, mais un processus standardisé. En codant ces stratégies dans Terraform, vous transformez un risque opérationnel en une simple Pull Request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Besoin d'auditer la résilience de vos clusters Kubernetes ?
&lt;/h3&gt;

&lt;p&gt;Benoît Garçon, via La Formule Nuagique, accompagne les équipes Tech dans la sécurisation de leurs infrastructures GCP et l'automatisation de leurs opérations Day-2.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>googlecloud</category>
      <category>kubernetes</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Sécurisez et optimisez vos transferts de fichiers avec les signed URLs Cloud Storage</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Sun, 11 Jan 2026 22:30:17 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/securisez-et-optimisez-vos-transferts-de-fichiers-avec-les-signed-urls-cloud-storage-aa4</link>
      <guid>https://dev.to/laformulenuagique/securisez-et-optimisez-vos-transferts-de-fichiers-avec-les-signed-urls-cloud-storage-aa4</guid>
      <description>&lt;p&gt;En tant qu'architecte cloud, je vois encore trop souvent une anti-pattern tenace dans le développement d'applications web : le streaming de fichiers à travers le serveur backend.&lt;/p&gt;

&lt;p&gt;Le scénario est classique : un utilisateur doit uploader une photo de profil ou télécharger une facture PDF. L'application reçoit le fichier sur le serveur API, le met en mémoire tampon, puis l'envoie vers Google Cloud Storage (GCS).&lt;/p&gt;

&lt;p&gt;Pourquoi est-ce une mauvaise idée ?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Goulot d'étranglement : Votre serveur API (Compute Engine, Cloud Run ou GKE) consomme de la CPU et de la RAM pour du simple transit de données.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Latence : Vous ajoutez un saut supplémentaire (Client -&amp;gt; Serveur -&amp;gt; GCS).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coûts : Vous payez pour la bande passante et le temps de calcul de votre serveur, alors que GCS est conçu pour ingérer des pétaoctets à moindre coût.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La solution architecturale élégante ? Les URL signées.&lt;/p&gt;

&lt;p&gt;Dans cet article, nous allons voir comment déléguer le transfert de fichiers directement au client (le navigateur) de manière totalement sécurisée, en utilisant Python et le SDK GCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qu'est-ce qu'une Signed URL ?
&lt;/h2&gt;

&lt;p&gt;Une Signed URL est un lien temporaire qui donne une permission spécifique (lecture, écriture, suppression) sur un objet précis de votre bucket, pour une durée limitée.&lt;/p&gt;

&lt;p&gt;Imaginez un valet de parking. Vous ne lui donnez pas les clés de votre maison (vos identifiants IAM Admin), mais un ticket temporaire qui lui permet juste de garer la voiture (uploader un fichier) et qui expire au bout de 5 minutes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Demande : Le client (Frontend) demande au Backend l'autorisation d'uploader un fichier (ex: avatar.jpg).&lt;/li&gt;
&lt;li&gt;Signature : Le Backend, via ses crédentiels IAM (Service Account), génère une URL signée cryptographiquement.&lt;/li&gt;
&lt;li&gt;Envoi : Le Backend renvoie cette URL au client.&lt;/li&gt;
&lt;li&gt;Action : Le client effectue un PUT ou un GET directement sur cette URL vers Google Cloud Storage.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implémentation technique
&lt;/h2&gt;

&lt;p&gt;Pour cet exemple, nous allons générer une URL permettant à un utilisateur d'uploader un fichier (méthode PUT).&lt;/p&gt;

&lt;h3&gt;
  
  
  Prérequis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Un bucket GCS privé (pas d'accès public allUsers).&lt;/li&gt;
&lt;li&gt;Un Service Account avec le rôle roles/storage.objectCreator (pour l'upload) ou roles/storage.objectViewer (pour le download).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Le code (Backend Python)
&lt;/h3&gt;

&lt;p&gt;Utilisons la méthode &lt;code&gt;generate_signed_url&lt;/code&gt; du SDK Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.cloud&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_upload_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blob_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Génère une URL signée v4 pour uploader un objet.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;storage_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_signed_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# L'URL expire dans 15 minutes
&lt;/span&gt;        &lt;span class="n"&gt;expiration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="c1"&gt;# Autorise uniquement la méthode PUT
&lt;/span&gt;        &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PUT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# Sécurité critique : force le type de contenu
&lt;/span&gt;        &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="c1"&gt;# Exemple d'utilisation
# L'utilisateur veut uploader 'mon-image.png'
&lt;/span&gt;&lt;span class="n"&gt;signed_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_upload_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mon-bucket-app&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uploads/user_123/mon-image.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image/png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;URL d&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;upload générée : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;signed_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Le code (Frontend JavaScript)
&lt;/h3&gt;

&lt;p&gt;Côté client, plus besoin d'authentification complexe. L'URL contient déjà le token nécessaire.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Récupérer l'URL signée depuis votre API&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/get-upload-url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signedUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Uploader directement vers GCS&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signedUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PUT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="c1"&gt;// Doit matcher celui défini lors de la signature !&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Upload réussi directement sur le Cloud Storage !&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Les pièges à éviter
&lt;/h2&gt;

&lt;p&gt;C'est ici que l'expérience fait la différence entre un code qui "marche" et une architecture de production.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. La configuration CORS
&lt;/h3&gt;

&lt;p&gt;C'est l'erreur numéro 1. Par défaut, votre bucket GCS refusera les requêtes venant de votre domaine (ex: mon-app.com). Vous devez configurer le CORS sur le bucket via la CLI gcloud ou Terraform.&lt;/p&gt;

&lt;p&gt;Créez un fichier cors.json :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://mon-app.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"PUT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HEAD"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"responseHeader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"maxAgeSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Appliquez-le :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets update gs://mon-bucket-app &lt;span class="nt"&gt;--cors-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cors.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Validez le Content-Type
&lt;/h3&gt;

&lt;p&gt;Ne laissez jamais le champ &lt;code&gt;content_type&lt;/code&gt; vide lors de la génération de la signature. Si vous ne le fixez pas, un utilisateur malveillant pourrait uploader un script exécutable (application/x-sh) à la place d'une image, ouvrant la porte à des failles de sécurité si ce fichier est ensuite servi à d'autres utilisateurs.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Gestion des noms de fichiers
&lt;/h3&gt;

&lt;p&gt;Ne faites pas confiance aux noms de fichiers envoyés par les utilisateurs. Générez le nom de l'objet côté backend (par exemple avec un UUID) pour éviter les collisions et les caractères spéciaux non gérés.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;L'utilisation des Signed URLs sur Google Cloud Storage est un "quick win" architectural. Vous déchargez votre infrastructure, améliorez l'expérience utilisateur grâce au réseau global de Google, et maintenez un niveau de sécurité granulaire.&lt;/p&gt;

&lt;p&gt;C'est typiquement le genre d'optimisation Cloud Native qui permet de passer d'une application "bricolée" à une infrastructure capable de scaler.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>googlecloud</category>
      <category>security</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>Interconnexion multi-cloud GCP, AWS, Azure : Maîtriser le coût, la performance et la sécurité de vos flux</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Thu, 11 Dec 2025 17:32:17 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/interconnexion-multi-cloud-gcp-aws-azure-maitriser-le-cout-la-performance-et-la-securite-de-4e4l</link>
      <guid>https://dev.to/laformulenuagique/interconnexion-multi-cloud-gcp-aws-azure-maitriser-le-cout-la-performance-et-la-securite-de-4e4l</guid>
      <description>&lt;p&gt;L'ère du mono-cloud est révolue. Aujourd'hui, 82 % des entreprises adoptent une stratégie &lt;strong&gt;multi-cloud&lt;/strong&gt; intentionnelle pour exploiter les services "Best-of-Breed" : l'IA de Google Cloud (GCP), la robustesse transactionnelle d'AWS, ou l'intégration Azure.&lt;/p&gt;

&lt;p&gt;Cependant, le transfert de données entre ces environnements devient le goulot d'étranglement critique. L'approche historique par &lt;strong&gt;VPN sur l'Internet public&lt;/strong&gt; est désormais obsolète, souffrant de latence imprévisible et de coûts de sortie (&lt;strong&gt;Egress&lt;/strong&gt;) prohibitifs. Le marché a pivoté vers des solutions d'&lt;strong&gt;Interconnexion Cloud-to-Cloud&lt;/strong&gt; dédiées.&lt;/p&gt;

&lt;p&gt;Ce guide, basé sur notre analyse stratégique, vous fournit les clés pour choisir l'architecture d'interconnexion qui maximise la performance, garantit la sécurité (MACsec) et, surtout, optimise votre facture cloud (FinOps).&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Performance : Adieu l'imprévisible, bonjour la latence déterministe
&lt;/h2&gt;

&lt;p&gt;Le choix de votre méthode de connexion se résume à une question de performance garantie.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le problème du VPN HA
&lt;/h3&gt;

&lt;p&gt;Le &lt;strong&gt;Cloud VPN Haute Disponibilité (HA)&lt;/strong&gt;, bien que fiable (SLA 99,99 %), utilise l'Internet public. Les fluctuations du routage BGP et la congestion des nœuds d'échange Internet (IXP) introduisent une &lt;strong&gt;gigue (jitter)&lt;/strong&gt; destructive pour les applications synchrones ou les bases de données distribuées. De plus, le débit est plafonné à environ &lt;strong&gt;3 Gbps par tunnel&lt;/strong&gt; en raison de la charge CPU de chiffrement IPsec.&lt;/p&gt;

&lt;h3&gt;
  
  
  La promesse de l'interconnexion privée
&lt;/h3&gt;

&lt;p&gt;Les solutions dédiées comme &lt;strong&gt;Cross-Cloud Interconnect (CCI)&lt;/strong&gt; de GCP ou &lt;strong&gt;Direct Connect&lt;/strong&gt; d'AWS sont des autoroutes numériques :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latence Ultra-Faible :&lt;/strong&gt; Les benchmarks entre GCP (us-east4) et AWS (us-east-1) via interconnexion privée montrent une latence souvent &lt;strong&gt;inférieure à 2 ms&lt;/strong&gt;, équivalente à la connexion entre deux zones de disponibilité internes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Débit Garanti :&lt;/strong&gt; Un circuit &lt;strong&gt;10 Gbps&lt;/strong&gt; ou &lt;strong&gt;100 Gbps&lt;/strong&gt; délivre son débit de façon constante (24/7), essentiel pour les fenêtres de sauvegarde nocturnes ou l'alimentation en données de modèles d'IA massifs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Le facteur FinOps : Le point de rentabilité (Break-Even)
&lt;/h2&gt;

&lt;p&gt;L'interconnexion privée est un investissement. Comprendre le point de bascule de rentabilité est essentiel pour le DAF et le CTO.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coûts Fixes (Ports) vs. Coûts Variables (Egress)
&lt;/h3&gt;

&lt;p&gt;L'interconnexion privée remplace un coût variable élevé (frais de sortie Internet) par un coût fixe (frais de port) et un coût variable réduit.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type de Coût&lt;/th&gt;
&lt;th&gt;Internet Public (VPN)&lt;/th&gt;
&lt;th&gt;Interconnexion Privée (CCI/Direct Connect)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coût Variable (Sortie/Egress)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Élevé (Ex: $0.08 - $0.12/GB sur GCP)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Très Réduit&lt;/strong&gt; (Ex: &lt;strong&gt;~ $0.02/GB&lt;/strong&gt; sur GCP/AWS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coût Fixe (Port)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Faible (Frais minimes)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Élevé&lt;/strong&gt; (Ex: ~ $5,900/mois pour 10G GCP-AWS)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Le seuil critique de 100 To
&lt;/h3&gt;

&lt;p&gt;Notre analyse FinOps démontre que pour une connexion dédiée &lt;strong&gt;10 Gbps entre GCP et AWS&lt;/strong&gt;, le point de rentabilité se situe à &lt;strong&gt;environ 100 To de transfert mensuel&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Si Volume &amp;gt; 100 To/mois :&lt;/strong&gt; La solution dédiée (CCI 10G/100G) est &lt;strong&gt;moins chère&lt;/strong&gt; que le VPN sur Internet, tout en offrant une performance supérieure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Si Volume &amp;lt; 50 To/mois :&lt;/strong&gt; Privilégiez l'option &lt;strong&gt;Partner Interconnect&lt;/strong&gt; (via Equinix ou Megaport). Leurs ports granulaires (dès 1 Gbps) offrent des frais fixes drastiquement plus bas, optimisant le ROI pour les volumes intermédiaires.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Piège à éviter :&lt;/strong&gt; Les &lt;strong&gt;frais inter-régions&lt;/strong&gt;. Si votre port Interconnect n'est pas géolocalisé au plus près de vos VMs, vous paierez des frais de transfert inter-région additionnels &lt;em&gt;avant&lt;/em&gt; que les données n'atteignent le port physique.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Sécurité de Couche 2 : Le Bouclier MACsec
&lt;/h2&gt;

&lt;p&gt;Pour les entreprises soumises à une conformité stricte (RGPD, secteur financier), la sécurité des données en transit est non négociable.&lt;/p&gt;

&lt;p&gt;Le &lt;strong&gt;Cross-Cloud Interconnect (CCI)&lt;/strong&gt; et la nouvelle offre &lt;strong&gt;AWS Interconnect&lt;/strong&gt; supportent nativement le chiffrement &lt;strong&gt;MACsec&lt;/strong&gt; (Media Access Control Security - IEEE 802.1AE).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MACsec vs. IPsec :&lt;/strong&gt; Contrairement à IPsec (chiffrement de couche 3, logiciel, impact sur la performance), MACsec chiffre les trames Ethernet à la &lt;strong&gt;vitesse de la ligne (line-rate)&lt;/strong&gt; sans dégradation de débit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protection Physique :&lt;/strong&gt; MACsec protège contre l'interception physique (tapping) sur les fibres noires partagées, garantissant que les données sont chiffrées de la carte réseau du routeur de bordure GCP à celle d'AWS/Azure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommandation :&lt;/strong&gt; Le support de MACsec est un argument décisif pour choisir l'interconnexion native directe (CCI/Direct Connect/ExpressRoute Direct) pour toute charge de travail nécessitant une sécurité de couche 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Stratégie simplifiée : Choisir l'architecture adaptée
&lt;/h2&gt;

&lt;p&gt;Le choix final dépend de votre cible cloud et de vos besoins en débit/agilité.&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Connexion GCP vers AWS
&lt;/h3&gt;

&lt;p&gt;La collaboration récente entre Google et AWS a simplifié l'architecture.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;th&gt;Débit/Capacité&lt;/th&gt;
&lt;th&gt;Délai de Déploiement&lt;/th&gt;
&lt;th&gt;Cas d'Usage Idéal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Partner Cross-Cloud Interconnect pour AWS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Granulaire (1 Gbps à 100 Gbps)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&amp;lt; 1 jour&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flexibilité (Retail, Débordement), volumes modérés (1-80 To). Recommandation standard pour un meilleur équilibre.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CCI Standard (Dédié) / AWS Interconnect&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fixe (10 Gbps ou 100 Gbps)&lt;/td&gt;
&lt;td&gt;1 à 4 semaines&lt;/td&gt;
&lt;td&gt;Volumes massifs et stables (IA/ML, Data Lake), exigences MACsec strictes.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  B. Connexion GCP vers Azure
&lt;/h3&gt;

&lt;p&gt;L'écosystème Azure est marqué par le coût élevé d'&lt;strong&gt;ExpressRoute Direct&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Option Recommandée : Modèle Fournisseur (ExpressRoute Partner) :&lt;/strong&gt; Utilisez des partenaires comme &lt;strong&gt;Equinix Fabric&lt;/strong&gt; ou &lt;strong&gt;Megaport Cloud Router (MCR)&lt;/strong&gt;. Cela permet d'acheter des circuits de &lt;strong&gt;50 Mbps à 10 Gbps&lt;/strong&gt; pour une fraction du coût d'ExpressRoute Direct, assurant agilité et économie (&lt;strong&gt;~$436/mois&lt;/strong&gt; pour 1 Gbps, sans compter les frais partenaires).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Option ExpressRoute Direct :&lt;/strong&gt; À n'envisager que si vous avez un besoin absolu de &lt;strong&gt;100 Gbps&lt;/strong&gt; ou des exigences de régulation très strictes. Le coût d'entrée ($50 000/mois pour 100 Gbps) est souvent prohibitif.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion et recommandations
&lt;/h2&gt;

&lt;p&gt;Le passage au multi-cloud nécessite une infrastructure de réseau pensée comme un service financier et sécuritaire.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Priorité FinOps :&lt;/strong&gt; Sortez d'Internet pour tout flux de données constant &lt;strong&gt;supérieur à 50 To/mois&lt;/strong&gt;. L'économie sur les frais de sortie amortira le coût des ports dédiés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardisation AWS :&lt;/strong&gt; &lt;strong&gt;Standardisez sur Partner Cross-Cloud Interconnect pour AWS&lt;/strong&gt; pour son déploiement rapide, sa gestion simplifiée et sa flexibilité bidirectionnelle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilité Azure :&lt;/strong&gt; Adoptez une approche hybride pour Azure en utilisant des &lt;strong&gt;Partenaires d'Interconnexion&lt;/strong&gt; (Equinix/Megaport) pour éviter les frais excessifs d'ExpressRoute Direct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sécurité d'infrastructure :&lt;/strong&gt; Activez &lt;strong&gt;MACsec&lt;/strong&gt; systématiquement sur tous les liens physiques pour garantir l'intégrité et la confidentialité de vos données au niveau de la couche 2.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>googlecloud</category>
      <category>multicloud</category>
      <category>aws</category>
      <category>azure</category>
    </item>
    <item>
      <title>Guide pour l'installation de GKE on-prem sur VMware</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Tue, 11 Nov 2025 22:32:12 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/guide-pour-linstallation-de-gke-on-prem-sur-vmware-57l</link>
      <guid>https://dev.to/laformulenuagique/guide-pour-linstallation-de-gke-on-prem-sur-vmware-57l</guid>
      <description>&lt;p&gt;Dans l'univers du cloud hybride, &lt;strong&gt;Google Distributed Cloud (GDC)&lt;/strong&gt;, anciennement connu sous le nom d'&lt;strong&gt;Anthos&lt;/strong&gt;, s'est imposé comme une solution de premier plan. Il promet d'étendre la puissance et l'agilité de Google Kubernetes Engine (GKE) directement dans votre data center. Pour de nombreuses entreprises, GDC sur VMware est la passerelle vers la modernisation applicative sans abandonner leurs investissements sur site.&lt;/p&gt;

&lt;p&gt;Mais soyons honnêtes : le déploiement de GDC (ou GKE on-prem) n'est pas une simple formalité. C'est un exercice d'architecture qui exige une planification méticuleuse. En tant qu'&lt;strong&gt;experts Google Distributed Cloud&lt;/strong&gt;, nous avons constaté que la majorité des échecs d'installation proviennent d'une phase de préparation insuffisante.&lt;/p&gt;

&lt;p&gt;Ce guide n'est pas une simple copie de la documentation. Nous allons décortiquer le processus d'installation d'une configuration minimale, en mettant l'accent sur les &lt;em&gt;pourquoi&lt;/em&gt; et les points de vigilance critiques que seul un expert GDC identifiera.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'architecture GDC sur VMware : Les 3 piliers
&lt;/h2&gt;

&lt;p&gt;Avant de taper la moindre commande, il est vital de comprendre les trois composants fondamentaux que nous allons construire.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Le &lt;strong&gt;poste de travail administrateur (Admin Workstation)&lt;/strong&gt; : C'est une machine virtuelle (VM) dédiée dans votre vSphere qui servira de tour de contrôle. Elle héberge les outils CLI, comme &lt;code&gt;gkeadm&lt;/code&gt; et &lt;code&gt;gkectl&lt;/code&gt;, ainsi que les fichiers de configuration nécessaires pour créer et gérer vos clusters.&lt;/li&gt;
&lt;li&gt;Le &lt;strong&gt;cluster d'administrateur (Admin Cluster)&lt;/strong&gt; : C'est le cerveau de votre installation GDC on-prem. Il est lui-même un cluster Kubernetes qui gère le cycle de vie (création, mise à jour, suppression) de vos clusters d'utilisateur.&lt;/li&gt;
&lt;li&gt;Le &lt;strong&gt;cluster d'utilisateur (User Cluster)&lt;/strong&gt; : C'est ici que la magie opère. Ce cluster exécute vos charges de travail applicatives, exactement comme un cluster GKE standard dans le cloud.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Phase 1 : La planification, clé du succès avec Anthos
&lt;/h2&gt;

&lt;p&gt;Ne sous-estimez jamais cette étape. Une installation de GKE on-prem réussie repose entièrement sur une planification rigoureuse de votre infrastructure existante.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prérequis vSphere : Au-delà de la simple version
&lt;/h3&gt;

&lt;p&gt;Vous avez besoin d'un environnement vSphere fonctionnel, avec vCenter Server et des hôtes ESXi. La documentation spécifie les versions minimales, typiquement 7.0u2+ ou 8.0+. Cependant, un expert regardera immédiatement la &lt;strong&gt;licence&lt;/strong&gt;. Une licence vSphere Standard est suffisante pour une preuve de concept (POC) minimale. En revanche, une installation de &lt;strong&gt;production&lt;/strong&gt; exige vSphere Enterprise Plus. Pourquoi ? Pour activer des fonctionnalités cruciales comme VMware DRS (Distributed Resource Scheduler) et les règles d'anti-affinité , qui garantissent la haute disponibilité de votre plan de contrôle GDC en répartissant les nœuds sur des hôtes physiques distincts.&lt;/p&gt;

&lt;p&gt;L'autre point d'expertise concerne les &lt;strong&gt;permissions vCenter&lt;/strong&gt;. N'utilisez jamais un compte administrateur global pour votre installation. Un expert GDC travaillera avec votre administrateur vSphere pour créer des rôles personnalisés avec les privilèges minimums requis, segmentés par objet vSphere (Datacenter, Cluster, Datastore, Réseau). C'est une question fondamentale de sécurité et de conformité.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le point de bascule : La planification des adresses IP
&lt;/h3&gt;

&lt;p&gt;C'est ici que 90% des déploiements échouent. GDC en mode "statique"  (le plus courant pour une installation minimale avec l'équilibreur de charge MetalLB intégré ) exige une planification IP exhaustive. Vous ne pouvez pas inventer ces adresses au fur et à mesure. Vous devez définir et réserver &lt;em&gt;avant&lt;/em&gt; de commencer :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Une adresse IP pour le poste de travail administrateur.&lt;/li&gt;
&lt;li&gt;Trois adresses IP pour les nœuds du plan de contrôle du cluster d'administrateur.&lt;/li&gt;
&lt;li&gt;Une adresse IP pour le nœud du plan de contrôle du cluster d'utilisateur.&lt;/li&gt;
&lt;li&gt;Plusieurs adresses IP pour les nœuds de calcul (workers) du cluster d'utilisateur .&lt;/li&gt;
&lt;li&gt;Une adresse IP virtuelle (VIP) pour le serveur d'API du cluster d'administrateur.&lt;/li&gt;
&lt;li&gt;Une adresse IP virtuelle (VIP) pour le serveur d'API du cluster d'utilisateur.&lt;/li&gt;
&lt;li&gt;Une adresse IP virtuelle (VIP) pour l'entrée Ingress du cluster d'utilisateur.&lt;/li&gt;
&lt;li&gt;Une plage d'adresses IP virtuelles pour les services de type LoadBalancer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;De plus, vous devez définir vos plages CIDR pour les Pods et les Services de chaque cluster. Ces plages ne doivent &lt;strong&gt;absolument pas&lt;/strong&gt; chevaucher vos réseaux existants (VMs, serveurs vCenter, DNS, etc.) pour éviter des cauchemars de routage .&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2 : Configurer la connexion au cloud Google
&lt;/h2&gt;

&lt;p&gt;Votre installation sur site doit communiquer avec Google Cloud pour télécharger les composants, s'enregistrer et être gérée.&lt;/p&gt;

&lt;p&gt;Vous devez d'abord choisir un projet Google Cloud  et y activer une série d'APIs essentielles. Les plus importantes sont &lt;code&gt;gkeonprem.googleapis.com&lt;/code&gt; (l'API GKE On-Prem), &lt;code&gt;gkehub.googleapis.com&lt;/code&gt; (pour enregistrer vos clusters dans un "Fleet") et &lt;code&gt;anthos.googleapis.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ensuite, vient la gestion des identités via les &lt;strong&gt;comptes de service (Service Accounts)&lt;/strong&gt;. C'est un point critique. Vous devez en créer manuellement deux:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Le &lt;strong&gt;compte de service d'accès aux composants&lt;/strong&gt; (component-access-sa)  : C'est lui qui a les droits (comme &lt;code&gt;serviceusage.serviceUsageViewer&lt;/code&gt;) pour télécharger les binaires et images de GDC depuis Artifact Registry .&lt;/li&gt;
&lt;li&gt;Le &lt;strong&gt;compte de service de journalisation d'audit&lt;/strong&gt; (audit-logging-sa)  : Il permet à vos clusters on-prem d'envoyer leurs journaux d'audit Kubernetes directement à Google Cloud Audit Logs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Créez les clés JSON pour ces comptes, elles seront bientôt nécessaires. D'autres comptes de service, comme &lt;code&gt;connect-register&lt;/code&gt; et &lt;code&gt;logging-monitoring&lt;/code&gt;, seront créés automatiquement par l'outil d'installation &lt;code&gt;gkeadm&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 3 : Création du poste de travail administrateur
&lt;/h2&gt;

&lt;p&gt;Le déploiement commence. Depuis votre machine locale (où &lt;code&gt;gcloud&lt;/code&gt; est installé ), vous téléchargerez l'exécutable &lt;code&gt;gkeadm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La création du poste de travail se fait via deux fichiers de configuration. D'abord, &lt;code&gt;credential.yaml&lt;/code&gt;, qui contient simplement vos identifiants vCenter. Ensuite, le fichier principal &lt;code&gt;admin-ws-config.yaml&lt;/code&gt;. Ce YAML décrit à &lt;code&gt;gkeadm&lt;/code&gt; votre environnement vSphere (datacenter, datastore, réseau)  et les détails réseau de la VM du poste de travail (son IP statique, la passerelle, les serveurs DNS) .&lt;/p&gt;

&lt;p&gt;Une fois ces fichiers remplis, vous lancez la commande &lt;code&gt;./gkeadm create admin-workstation&lt;/code&gt;. Cet outil va alors se connecter à vCenter, créer la VM, y installer les outils, et, comme mentionné, créer les comptes de service restants dans GCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 4 : Déployer le cerveau, le cluster d'administrateur
&lt;/h2&gt;

&lt;p&gt;Connectez-vous en SSH au poste de travail administrateur que vous venez de créer. Vous y trouverez des modèles de configuration, dont le crucial &lt;code&gt;admin-cluster.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;C'est le fichier de configuration le plus dense. Vous devez le remplir avec &lt;strong&gt;toutes&lt;/strong&gt; les informations planifiées : les détails vCenter , les plages CIDR des Pods et Services , la configuration de l'équilibreur de charge MetalLB, les 3 adresses IP statiques pour les nœuds du plan de contrôle du cluster admin , la VIP de son serveur d'API , et les chemins vers les différents fichiers de clés JSON des comptes de service.&lt;/p&gt;

&lt;p&gt;Avant la création, une étape indispensable est d'importer les images des OS (les modèles de VM) dans vSphere. Cela se fait avec &lt;code&gt;gkectl prepare --config admin-cluster.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Enfin, lancez la création avec &lt;code&gt;gkectl create admin --config admin-cluster.yaml&lt;/code&gt;. Ce processus est long. Il provisionne trois VM, y installe un cluster Kubernetes haute disponibilité, déploie les opérateurs GDC, et enregistre ce cluster auprès de Google Cloud. Une fois terminé, vous disposez d'un fichier &lt;code&gt;kubeconfig&lt;/code&gt; local pour interagir avec votre nouveau cluster d'administrateur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Étape suivante : Votre premier cluster utilisateur
&lt;/h2&gt;

&lt;p&gt;Votre cluster d'administrateur est l'usine ; il est maintenant prêt à construire des clusters d'utilisateur. Le processus est similaire, en utilisant un fichier &lt;code&gt;user-cluster.yaml&lt;/code&gt;  ou, de manière plus moderne, en utilisant directement la &lt;code&gt;gcloud&lt;/code&gt; CLI, car votre cluster admin est désormais géré par l'API GKE On-Prem. Une commande comme &lt;code&gt;gcloud container vmware clusters create ...&lt;/code&gt;  pilotera votre cluster d'administrateur on-prem pour qu'il déploie un nouveau cluster utilisateur.&lt;/p&gt;

&lt;p&gt;Ce que nous avons couvert est l'installation "minimale". Le véritable travail d'un &lt;strong&gt;expert GDC / Anthos&lt;/strong&gt; commence ici : configurer l'équilibrage de charge avancé (BGP avec MetalLB ou intégration F5), sécuriser les flux, mettre en place l'authentification OIDC, gérer les mises à niveau et assurer la surveillance à l'échelle de la production.&lt;/p&gt;

&lt;p&gt;Si cette architecture et ce processus vous semblent complexes, c'est qu'ils le sont. Assurer la robustesse de votre fondation cloud hybride est notre métier. N'hésitez pas à contacter un expert pour sécuriser et accélérer votre parcours vers Google Distributed Cloud.&lt;/p&gt;

</description>
      <category>gcp</category>
      <category>devops</category>
      <category>anthos</category>
      <category>gdc</category>
    </item>
    <item>
      <title>Simplifiez vos workflows DevOps avec Task, le "Makefile" moderne</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Sat, 11 Oct 2025 20:43:19 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/simplifiez-vos-workflows-devops-avec-task-le-makefile-moderne-1coa</link>
      <guid>https://dev.to/laformulenuagique/simplifiez-vos-workflows-devops-avec-task-le-makefile-moderne-1coa</guid>
      <description>&lt;p&gt;Aujourd'hui, on va parler d'un outil qui va changer votre façon de gérer vos workflows quotidiens : &lt;strong&gt;Task&lt;/strong&gt;. Si le mot "Makefile" vous fait frissonner ou si vous en avez marre de jongler avec des scripts shell complexes et non portables, vous êtes au bon endroit. Task est là pour vous offrir une alternative moderne, simple et puissante.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qu'est-ce que Task et pourquoi s'y intéresser ?
&lt;/h2&gt;

&lt;p&gt;Imaginez un instant que vous puissiez définir des ensembles de commandes, des scripts et même des dépendances entre tâches, le tout dans un fichier YAML lisible et versionnable. C'est exactement ce que propose Task. Développé en Go, il se positionne comme une solution agnostique et multiplateforme pour automatiser vos tâches récurrentes en développement, en intégration continue, et bien sûr, en DevOps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pourquoi l'avoir adopté ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dans notre monde où l'infrastructure as code et l'automatisation règnent, Task s'intègre parfaitement. Que ce soit pour :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Builder des images Docker&lt;/li&gt;
&lt;li&gt;Déployer des applications sur Kubernetes&lt;/li&gt;
&lt;li&gt;Exécuter des tests unitaires ou d'intégration&lt;/li&gt;
&lt;li&gt;Gérer des environnements de développement&lt;/li&gt;
&lt;li&gt;Ou simplement organiser vos scripts de démarrage de services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Task vous offre une syntaxe claire et une exécution cohérente, peu importe la machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation : Votre premier pas vers l'automatisation
&lt;/h2&gt;

&lt;p&gt;L'installation de Task est un jeu d'enfant, quelle que soit votre plateforme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;macOS/Linux (avec Homebrew) :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;go-task/tap/go-task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows (avec Chocolatey) :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;choco &lt;span class="nb"&gt;install &lt;/span&gt;go-task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ou téléchargez le binaire directement :&lt;/strong&gt;&lt;br&gt;
Rendez-vous sur &lt;a href="https://taskfile.dev/docs/installation" rel="noopener noreferrer"&gt;taskfile.dev/docs/installation&lt;/a&gt; pour les binaires pré-compilés et d'autres méthodes d'installation.&lt;/p&gt;

&lt;p&gt;Une fois installé, vérifiez-le avec :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vous devriez voir la version de Task s'afficher, preuve que l'outil est prêt à rugir !&lt;/p&gt;

&lt;h2&gt;
  
  
  Votre premier &lt;code&gt;Taskfile.yml&lt;/code&gt; : Le cœur de l'action
&lt;/h2&gt;

&lt;p&gt;Toutes les tâches sont définies dans un fichier nommé &lt;code&gt;Taskfile.yml&lt;/code&gt; (ou &lt;code&gt;Taskfile.yaml&lt;/code&gt;), placé à la racine de votre projet. C'est là que la magie opère.&lt;/p&gt;

&lt;p&gt;Créons un exemple simple. Dans votre répertoire de projet, créez un fichier &lt;code&gt;Taskfile.yml&lt;/code&gt; avec le contenu suivant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dit bonjour au monde&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Bonjour, La Formule Nuagique !"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Aujourd'hui, nous explorons Task."&lt;/span&gt;

  &lt;span class="na"&gt;env-info&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Affiche quelques informations sur l'environnement&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hostname&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;whoami&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pwd&lt;/span&gt;

  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Simule une étape de build&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Lancement du build..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# Simule un travail long&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Build terminé avec succès !"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exécuter vos tâches
&lt;/h3&gt;

&lt;p&gt;Pour exécuter une tâche, c'est très simple :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vous devriez voir :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task: &lt;span class="o"&gt;[&lt;/span&gt;hello] &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bonjour, La Formule Nuagique !"&lt;/span&gt;
Bonjour, La Formule Nuagique &lt;span class="o"&gt;!&lt;/span&gt;
task: &lt;span class="o"&gt;[&lt;/span&gt;hello] &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Aujourd'hui, nous explorons Task."&lt;/span&gt;
Aujourd&lt;span class="s1"&gt;'hui, nous explorons Task.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et pour l'info d'environnement :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task env-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lister toutes les tâches
&lt;/h3&gt;

&lt;p&gt;Si vous avez de nombreuses tâches, vous pouvez toutes les lister avec leurs descriptions :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;span class="c"&gt;# Ou simplement&lt;/span&gt;
task &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ceci est incroyablement utile pour les collaborateurs qui découvrent un projet et ont besoin de savoir quelles sont les actions disponibles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fonctionnalités avancées pour le DevOps moderne
&lt;/h2&gt;

&lt;p&gt;Task ne se contente pas d'exécuter des scripts. Il offre des fonctionnalités robustes qui en font un outil DevOps de choix.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Dépendances entre tâches
&lt;/h3&gt;

&lt;p&gt;C'est là que Task devient vraiment puissant. Vous pouvez définir qu'une tâche doit s'exécuter &lt;em&gt;après&lt;/em&gt; une ou plusieurs autres tâches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;clean&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nettoie les artefacts de build&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Nettoyage des fichiers..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm -rf dist/&lt;/span&gt; &lt;span class="c1"&gt;# Supprime un dossier de distribution fictif&lt;/span&gt;

  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Compile l'application&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Compilation de l'application..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mkdir -p dist/&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;touch dist/app.bin&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Déploie l'application&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;clean&lt;/span&gt; &lt;span class="c1"&gt;# S'assure que le nettoyage est fait avant le déploiement&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt; &lt;span class="c1"&gt;# S'assure que l'application est compilée&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Déploiement de dist/app.bin vers le serveur..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Application déployée !"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant, si vous exécutez &lt;code&gt;task deploy&lt;/code&gt;, Task s'assurera d'abord que &lt;code&gt;clean&lt;/code&gt; puis &lt;code&gt;build&lt;/code&gt; sont exécutés séquentiellement avant de lancer les commandes de &lt;code&gt;deploy&lt;/code&gt;. C'est idéal pour créer des pipelines CI/CD locaux !&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Variables et paramètres
&lt;/h3&gt;

&lt;p&gt;Rendez vos tâches dynamiques avec des variables. Vous pouvez définir des variables globales, locales à une tâche, ou passer des arguments en ligne de commande.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;PROJECT_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mon-app-nuagique&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Salue un utilisateur ou le projet&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Bonjour, ${USER_NAME:-équipe} !"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Bienvenue sur le projet ${PROJECT_NAME}."&lt;/span&gt;
    &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;USER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{.CLI_ARGS}}"&lt;/span&gt; &lt;span class="c1"&gt;# Permet de passer un nom en ligne de commande&lt;/span&gt;

  &lt;span class="na"&gt;docker-build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Construit l'image Docker&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker build -t la-formule-nuagique/${PROJECT_NAME}:{{.VERSION}} .&lt;/span&gt;
    &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.0.0'&lt;/span&gt; &lt;span class="c1"&gt;# Version par défaut si non spécifiée&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exemple d'utilisation :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task greet &lt;span class="s2"&gt;"Alice"&lt;/span&gt; &lt;span class="c"&gt;# output: "Bonjour, Alice !" et le nom du projet&lt;/span&gt;
task docker-build &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.1.0 &lt;span class="c"&gt;# Override la version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Gestion des erreurs et conditions
&lt;/h2&gt;

&lt;p&gt;Task offre des moyens de gérer les échecs et d'exécuter des commandes conditionnellement, ce qui est crucial pour des scripts robustes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;check-docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Vérifie si Docker est en cours d'exécution&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker info &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 || { echo "Docker n'est pas en cours d'exécution. Veuillez le démarrer." &amp;amp;&amp;amp; exit 1; }&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Docker est opérationnel !"&lt;/span&gt;
    &lt;span class="na"&gt;errors_to_stdout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# Affiche les erreurs de la commande si elle échoue&lt;/span&gt;

  &lt;span class="na"&gt;run-app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Démarre l'application si Docker est prêt&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;check-docker&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Lancement de l'application..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker run -d --name my-app my-image:latest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Application démarrée !"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dans cet exemple, &lt;code&gt;check-docker&lt;/code&gt; s'assure que le démon Docker est actif. Si ce n'est pas le cas, un message d'erreur est affiché et la tâche se termine avec un code d'erreur, empêchant &lt;code&gt;run-app&lt;/code&gt; de s'exécuter.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Exécution parallèle
&lt;/h3&gt;

&lt;p&gt;Pour les tâches indépendantes, Task peut les exécuter en parallèle pour gagner du temps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test-frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exécute les tests frontend&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Lancement des tests frontend..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;test-backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exécute les tests backend&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Lancement des tests backend..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;

  &lt;span class="na"&gt;full-tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exécute tous les tests en parallèle&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-frontend&lt;/span&gt;
        &lt;span class="na"&gt;silent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# Rend la sortie plus propre&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-backend&lt;/span&gt;
        &lt;span class="na"&gt;silent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="c1"&gt;# Ou alternativement, en utilisant `deps` avec un flag parallèle&lt;/span&gt;
    &lt;span class="c1"&gt;# deps: [test-frontend, test-backend]&lt;/span&gt;
    &lt;span class="c1"&gt;# vars: { PARALLEL: true } # Non directement supporté comme ça, mais on peut le faire avec `cmd` et `&amp;amp;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour exécuter &lt;code&gt;test-frontend&lt;/code&gt; et &lt;code&gt;test-backend&lt;/code&gt; simultanément, vous pouvez le faire en ligne de commande ou en les orchestrant avec un script shell dans une tâche:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task test-frontend &amp;amp; task test-backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cependant, l'approche la plus propre avec Task est de créer une tâche qui les lance :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test-frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exécute les tests frontend&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Lancement des tests frontend..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Tests frontend terminés."&lt;/span&gt;

  &lt;span class="na"&gt;test-backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exécute les tests backend&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Lancement des tests backend..."&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sleep &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Tests backend terminés."&lt;/span&gt;

  &lt;span class="na"&gt;run-all-tests-parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Exécute les tests frontend et backend en parallèle&lt;/span&gt;
    &lt;span class="na"&gt;cmds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-frontend &amp;amp;&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-backend &amp;amp;&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;wait&lt;/span&gt; &lt;span class="c1"&gt;# Attend la fin de tous les processus en arrière-plan&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exécutez &lt;code&gt;task run-all-tests-parallel&lt;/code&gt; pour voir les tâches s'exécuter côte à côte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task vs. Makefile vs. scripts Shell
&lt;/h2&gt;

&lt;p&gt;C'est une question légitime. Voici pourquoi Task se démarque :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lisibilité et simplicité (vs. Makefile) :&lt;/strong&gt; Le YAML est intrinsèquement plus facile à lire et à écrire que la syntaxe parfois archaïque et les subtilités des Makefiles. Pas de problèmes avec les tabulations vs. espaces !&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portabilité (vs. scripts Shell) :&lt;/strong&gt; Les scripts shell (&lt;code&gt;.sh&lt;/code&gt;, &lt;code&gt;.bat&lt;/code&gt;) sont souvent liés à un système d'exploitation spécifique. Task, compilé en Go, garantit que vos &lt;code&gt;Taskfile.yml&lt;/code&gt; fonctionnent de manière identique sur Linux, macOS et Windows, avec une seule installation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonctionnalités intégrées :&lt;/strong&gt; Dépendances, variables, descriptions, exécution parallèle, gestion d'erreurs... Task offre des fonctionnalités de "pipeline" sans avoir à écrire des logiques complexes dans vos scripts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discoverability :&lt;/strong&gt; &lt;code&gt;task --list&lt;/code&gt; est une fonctionnalité clé qui permet à quiconque de comprendre rapidement ce qu'un projet peut faire.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonnes pratiques avec Task pour la Formule Nuagique
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Un &lt;code&gt;Taskfile.yml&lt;/code&gt; par projet/module :&lt;/strong&gt; Organisez vos tâches logiquement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descriptions claires (&lt;code&gt;desc&lt;/code&gt;) :&lt;/strong&gt; N'oubliez jamais la description de vos tâches. C'est la documentation embarquée de vos workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Petit et modulaire :&lt;/strong&gt; Gardez vos tâches courtes et faites en sorte qu'elles fassent une seule chose. Utilisez les dépendances pour chaîner des opérations complexes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variables pour la flexibilité :&lt;/strong&gt; Utilisez des variables pour les chemins, les noms de conteneurs, les versions, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gestion des erreurs :&lt;/strong&gt; Anticipez les échecs et incluez des vérifications ou des instructions claires en cas de problème.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intégration CI/CD :&lt;/strong&gt; Task est parfait pour être appelé dans vos pipelines Jenkins, GitLab CI, GitHub Actions, etc., assurant une cohérence entre votre environnement local et votre CI/CD.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion : adoptez Task et gagnez en efficacité !
&lt;/h2&gt;

&lt;p&gt;Task est un outil simple à prendre en main, mais incroyablement puissant pour quiconque souhaite automatiser et standardiser ses workflows. Que vous soyez développeur, ingénieur DevOps ou architecte cloud, l'intégration de Task dans vos projets vous fera gagner un temps précieux et assurera une meilleure cohérence dans l'exécution de vos tâches.&lt;/p&gt;

&lt;p&gt;Fini le temps des "ça marche sur ma machine" ou des scripts obscurs ! Avec Task, vos opérations sont claires, portables et faciles à gérer. Essayez-le dès aujourd'hui et transformez vos processus !&lt;/p&gt;

</description>
      <category>devops</category>
      <category>makefile</category>
      <category>developer</category>
      <category>programming</category>
    </item>
    <item>
      <title>Google Cloud Storage : Le guide du débutant pour maîtriser vos fichiers</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Thu, 11 Sep 2025 11:00:00 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/google-cloud-storage-le-guide-du-debutant-pour-maitriser-vos-fichiers-281a</link>
      <guid>https://dev.to/laformulenuagique/google-cloud-storage-le-guide-du-debutant-pour-maitriser-vos-fichiers-281a</guid>
      <description>&lt;p&gt;Le terme "Cloud" peut souvent sembler intimidant, un univers abstrait rempli de jargon technique et de services complexes. Pourtant, au cœur de cette nébuleuse se trouvent des concepts fondamentalement simples et puissants. L'un des plus essentiels est le stockage d'objets. Il est temps de démystifier l'un des outils les plus robustes et accessibles dans ce domaine : Google Cloud Storage (GCS).&lt;/p&gt;

&lt;p&gt;Imaginez GCS non pas comme une technologie obscure, mais comme un disque dur quasi infini, accessible de n'importe où dans le monde, ultra-sécurisé et d'une flexibilité remarquable. C'est un service conçu pour stocker ce que l'on appelle des "données non structurées", ce qui inclut pratiquement tout ce à quoi vous pouvez penser : les images et vidéos de votre site web, les sauvegardes (backups) de vos bases de données, les fichiers de logs de vos applications, ou même les immenses jeux de données pour l'intelligence artificielle.&lt;/p&gt;

&lt;p&gt;Ce guide a pour but de vous accompagner, pas à pas, dans la découverte de GCS. Nous n'allons pas seulement survoler les fonctionnalités ; nous allons comprendre la logique qui les sous-tend. Nous nous concentrerons sur l'utilisation de l'outil en ligne de commande gcloud, un incontournable pour tout développeur qui souhaite automatiser ses tâches et travailler efficacement. En maîtrisant GCS, vous n'apprenez pas seulement à stocker des fichiers ; vous posez la première pierre pour construire des applications scalables, de l'hébergement de sites statiques à l'analyse de données à grande échelle (Big Data). En effet, GCS est une solution de stockage d'objets unifiée, ce qui signifie qu'il est conçu pour être le socle de stockage pour une multitude d'autres services Google Cloud, comme BigQuery pour l'analyse de données ou Vertex AI pour le machine learning. Apprendre GCS, c'est donc ouvrir la porte à tout l'écosystème de Google Cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les concepts clés
&lt;/h2&gt;

&lt;p&gt;Avant de taper notre première commande, il est crucial de comprendre les deux briques de base qui constituent Google Cloud Storage. Tout comme un système de fichiers est composé de dossiers et de fichiers, GCS est structuré autour de "buckets" et d'"objets".&lt;/p&gt;

&lt;h3&gt;
  
  
  Les "buckets", vos conteneurs dans le cloud
&lt;/h3&gt;

&lt;p&gt;Un "bucket" (qui se traduit par "seau" en anglais) est le conteneur fondamental dans GCS. C'est l'équivalent d'un dossier racine ou d'un disque dur principal où vous allez stocker vos données. Lorsque vous commencez à utiliser GCS, la première chose que vous ferez est de créer un bucket.&lt;/p&gt;

&lt;p&gt;La caractéristique la plus importante, et souvent une source de confusion pour les débutants, est que le nom d'un bucket doit être globalement unique. Cela signifie que le nom que vous choisissez ne peut pas déjà être utilisé par un autre utilisateur de Google Cloud, où que ce soit dans le monde. La raison est simple : chaque bucket peut potentiellement être adressé via une URL standard sur Internet (par exemple, &lt;code&gt;storage.googleapis.com/mon-nom-de-bucket-unique&lt;/code&gt;). Il fait donc partie d'un espace de noms mondial, un peu comme les noms de domaine de sites web.&lt;/p&gt;

&lt;p&gt;Pour éviter les erreurs, les noms de buckets doivent respecter quelques règles simples :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ils ne peuvent contenir que des lettres minuscules, des chiffres, des tirets (&lt;code&gt;-&lt;/code&gt;), des underscores (&lt;code&gt;_&lt;/code&gt;) et des points (&lt;code&gt;.&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Ils doivent commencer et se terminer par une lettre ou un chiffre.&lt;/li&gt;
&lt;li&gt;Leur longueur doit être comprise entre 3 et 63 caractères.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cette contrainte de nommage unique n'est pas seulement une limitation technique ; elle a une implication directe sur la sécurité. Puisqu'un nom de bucket est public et découvrable, un tiers pourrait essayer de deviner des noms pour vérifier l'existence de projets ou d'informations. Cela mène à une règle d'or fondamentale : &lt;strong&gt;ne jamais inclure d'informations sensibles dans les noms de buckets ou d'objets&lt;/strong&gt;. Par exemple, au lieu de nommer un bucket &lt;code&gt;gs://rapports-secrets-clients-2024&lt;/code&gt;, il est infiniment préférable d'utiliser un nom non descriptif et difficile à deviner, comme &lt;code&gt;gs://archive-data-alpha-7b3d&lt;/code&gt;. La sensibilité doit résider dans les données elles-mêmes et dans leurs permissions, pas dans leur nom.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les "objects", vos fichiers et leurs métadonnées
&lt;/h3&gt;

&lt;p&gt;Si un bucket est le dossier, un "objet" est simplement le fichier qu'il contient. Il peut s'agir de n'importe quel type de fichier (une image, un document PDF, une vidéo, un fichier binaire) et sa taille peut aller jusqu'à 5 To.&lt;/p&gt;

&lt;p&gt;Chaque objet dans GCS est composé de deux éléments indissociables :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Les données : Le contenu brut du fichier lui-même.&lt;/li&gt;
&lt;li&gt;Les métadonnées : Un ensemble d'informations qui décrivent l'objet. Cela inclut des métadonnées standard comme le nom de l'objet, sa taille, son type de contenu (par exemple, &lt;code&gt;image/jpeg&lt;/code&gt;), et la date de sa dernière modification. Vous pouvez également ajouter vos propres métadonnées personnalisées pour étiqueter et organiser vos données.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En résumé, la structure est simple : vous créez des buckets pour organiser vos projets, et vous placez des objets (vos fichiers) à l'intérieur de ces buckets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partie 2 : Vos premiers pas avec &lt;code&gt;gcloud storage&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Maintenant que les concepts sont clairs, passons à la pratique. L'outil gcloud est une interface en ligne de commande (CLI) puissante qui vous permet d'interagir avec tous les services Google Cloud, y compris GCS. Le sous-ensemble de commandes dédié au stockage est gcloud storage. Il est important de noter que gcloud storage est l'outil moderne et unifié recommandé par Google, qui remplace progressivement l'ancien outil gsutil pour offrir une expérience plus cohérente.&lt;/p&gt;

&lt;p&gt;La syntaxe de ces commandes a été conçue pour être intuitive pour quiconque a déjà utilisé un terminal Linux ou macOS. Les commandes de base comme cp (copier), ls (lister) et rm (supprimer) fonctionnent de manière très similaire, ce qui réduit considérablement la courbe d'apprentissage. Ce choix de conception n'est pas anodin ; il vise à rendre l'interaction avec le stockage cloud aussi naturelle que la gestion de fichiers sur votre propre machine.&lt;/p&gt;

&lt;p&gt;Voici les opérations fondamentales que vous devez maîtriser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Créer votre premier bucket
&lt;/h3&gt;

&lt;p&gt;La première étape est de créer un conteneur pour vos fichiers. N'oubliez pas que le nom doit être unique au monde!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets create gs://
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Par exemple : &lt;code&gt;gcloud storage buckets create gs://mon-projet-media-8a9b7c&lt;/code&gt;. Le préfixe &lt;code&gt;gs://&lt;/code&gt; est la manière standard de désigner une ressource dans Google Cloud Storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Envoyer (uploader) votre premier fichier
&lt;/h3&gt;

&lt;p&gt;Une fois le bucket créé, vous pouvez y copier un fichier depuis votre ordinateur local.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage &lt;span class="nb"&gt;cp&lt;/span&gt; &amp;lt;FILE&amp;gt; gs://
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Par exemple, pour envoyer un fichier nommé &lt;code&gt;logo.png&lt;/code&gt; depuis votre répertoire courant : &lt;code&gt;gcloud storage cp logo.png gs://mon-projet-media-8a9b7c/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lister le contenu d'un bucket
&lt;/h3&gt;

&lt;p&gt;Pour voir les objets que contient votre bucket, utilisez la commande ls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage &lt;span class="nb"&gt;ls &lt;/span&gt;gs://
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette commande affichera la liste de tous les objets à la racine de votre bucket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Télécharger un fichier
&lt;/h3&gt;

&lt;p&gt;Pour récupérer un fichier depuis votre bucket vers votre machine locale, utilisez la même commande cp, mais en inversant la source et la destination.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage &lt;span class="nb"&gt;ls &lt;/span&gt;gs:// &amp;lt;PATH&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Par exemple, pour télécharger logo.png dans votre répertoire courant : &lt;code&gt;gcloud storage cp gs://mon-projet-media-8a9b7c/logo.png .&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supprimer un objet et un bucket
&lt;/h3&gt;

&lt;p&gt;Enfin, pour nettoyer, vous pouvez supprimer un objet spécifique ou un bucket entier. Soyez prudent, car ces opérations sont généralement irréversibles, à moins que des mécanismes de protection comme la suppression réversible (soft delete) ou la gestion des versions ne soient activés.&lt;/p&gt;

&lt;p&gt;Pour supprimer un objet :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage &lt;span class="nb"&gt;rm &lt;/span&gt;gs://
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour supprimer un bucket et tout son contenu (option récursive -r) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; gs://
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avec ces cinq commandes, vous détenez déjà les clés pour effectuer 90% des opérations courantes sur Google Cloud Storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partie 3 : Optimiser les coûts
&lt;/h2&gt;

&lt;p&gt;L'un des plus grands avantages du cloud est son modèle de paiement à l'usage (pay-as-you-go). Cependant, cela peut aussi être un piège si l'on ne comprend pas comment les coûts sont structurés. Pour GCS, le coût ne dépend pas seulement de la quantité de données que vous stockez (le "stockage au repos"), mais aussi de la fréquence à laquelle vous y accédez (les "opérations" et la "sortie réseau"). Google propose des outils pour gérer intelligemment ce compromis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les classes de stockage, à chaque donnée son usage
&lt;/h3&gt;

&lt;p&gt;Toutes les données n'ont pas la même valeur ni la même fréquence d'accès. Un fichier image pour votre site web est consulté des milliers de fois par jour ("donnée chaude"), tandis qu'une archive légale peut ne jamais être consultée pendant des années ("donnée glacée"). GCS vous permet d'aligner le coût de stockage sur le profil d'accès de vos données grâce aux classes de stockage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard&lt;/strong&gt; : La classe Standard est idéale pour les données "chaudes", c'est-à-dire celles qui sont fréquemment consultées et modifiées. Cela inclut les sites web dynamiques, le streaming de contenu vidéo, les applications mobiles et les charges de travail analytiques actives. Bien que cette classe présente le coût de stockage le plus élevé, elle offre en contrepartie le coût d'accès le plus bas, ce qui la rend parfaite pour des données nécessitant une disponibilité immédiate et constante. Aucune durée minimale de stockage n'est imposée.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nearline&lt;/strong&gt; : Pour les données "tièdes", la classe Nearline est la plus appropriée. Il s'agit de données consultées de manière peu fréquente, comme des sauvegardes (backups) vérifiées mensuellement, des fichiers de logs ou du contenu multimédia rarement sollicité. Elle propose un coût de stockage bas en échange d'un coût d'accès moyen. Une durée minimale de stockage de 30 jours est requise pour cette classe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coldline&lt;/strong&gt; : La classe Coldline est conçue pour les données "froides", telles que les archives consultées de manière occasionnelle (par exemple, trimestriellement) ou les données destinées à la reprise après sinistre. Elle se caractérise par un coût de stockage très bas, mais un coût d'accès élevé, la rendant économique pour les informations rarement nécessaires. La durée minimale de conservation pour cette classe est de 90 jours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Archive&lt;/strong&gt; : Enfin, la classe Archive est réservée aux données "glacées", qui sont rarement, voire jamais, consultées. Cela concerne typiquement les archives légales ou réglementaires qui doivent être conservées sur le long terme pour des raisons de conformité. Cette classe offre le coût de stockage le plus bas du marché, mais son coût d'accès est le plus élevé, ce qui la destine à une conservation à très long terme. Une durée minimale de stockage de 365 jours est appliquée.&lt;/p&gt;

&lt;p&gt;La "durée minimale de stockage" est un concept clé : si vous supprimez un objet d'une classe autre que Standard avant cette durée, des frais de suppression anticipée s'appliqueront. Le choix d'une classe est donc un engagement sur la durée de vie prévue de la donnée.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le Cycle de Vie des Objets - L'Automatisation au Service de vos Économies
&lt;/h3&gt;

&lt;p&gt;Changer manuellement la classe de stockage de millions de fichiers serait une tâche titanesque. C'est là qu'intervient l'une des fonctionnalités les plus puissantes de GCS : la gestion du cycle de vie des objets (Object Lifecycle Management).&lt;/p&gt;

&lt;p&gt;Cette fonctionnalité vous permet de définir des règles automatiques qui s'appliquent à tous les objets d'un bucket. C'est comme avoir un majordome personnel qui, sans que vous ayez à intervenir, range votre grenier pour vous faire économiser de l'argent. Vous pouvez créer des règles pour :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changer la classe de stockage d'un objet après un certain temps.&lt;/li&gt;
&lt;li&gt;Supprimer un objet après une période définie.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prenons un exemple concret et courant : nous voulons que tous nos fichiers de logs (se terminant par .log) soient automatiquement déplacés vers la classe de stockage Coldline après 90 jours pour réduire les coûts. De plus, pour des raisons de conformité, nous voulons que ces logs soient définitivement supprimés après 7 ans (soit 2555 jours).&lt;/p&gt;

&lt;p&gt;Pour cela, nous créons un fichier de configuration au format JSON, que nous pourrions nommer lifecycle.json :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lifecycle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2555&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matchesSuffix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".log"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expliquons ce fichier :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rule&lt;/code&gt; : Définit une liste de règles.&lt;/li&gt;
&lt;li&gt;Première règle :

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;action&lt;/code&gt; : L'action à effectuer est SetStorageClass (changer la classe de stockage) pour la mettre à COLDLINE.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;condition&lt;/code&gt; : Cette action se déclenche quand l'âge (&lt;code&gt;age&lt;/code&gt;) de l'objet atteint 90 jours ET si son nom se termine (&lt;code&gt;matchesSuffix&lt;/code&gt;) par &lt;code&gt;.log&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Deuxième règle :

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;action&lt;/code&gt; : L'action est de type &lt;code&gt;Delete&lt;/code&gt; (supprimer).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;condition&lt;/code&gt; : Elle se déclenche quand l'âge de l'objet atteint 2555 jours ET si son nom se termine par &lt;code&gt;.log&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Une fois ce fichier créé, il suffit d'une seule commande gcloud pour l'appliquer à votre bucket :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets update gs://&amp;lt;PATH&amp;gt; &lt;span class="nt"&gt;--lifecycle-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lifecycle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette approche n'est pas seulement une fonctionnalité technique ; elle incarne un principe fondamental de l'architecture cloud. La valeur de la plupart des données diminue avec le temps. Les règles de cycle de vie sont le mécanisme qui vous permet d'aligner de manière programmatique et automatique vos coûts de stockage sur la valeur métier de vos données, une stratégie essentielle pour tout architecte cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partie 4 : L'astuce de fin, partager un fichier de manière sécurisée et temporaire
&lt;/h2&gt;

&lt;p&gt;Nous arrivons à l'astuce qui distingue souvent un débutant d'un utilisateur averti. Imaginez le scénario suivant : vous stockez des factures PDF pour les utilisateurs de votre application dans un bucket GCS. Ce bucket doit absolument rester privé ; personne sur Internet ne doit pouvoir lister son contenu. Comment permettez-vous à un utilisateur spécifique de télécharger sa propre facture, et uniquement la sienne, pour une durée limitée ?&lt;/p&gt;

&lt;p&gt;La mauvaise approche serait de rendre le fichier public temporairement, ou de gérer des permissions complexes. La solution élégante et sécurisée s'appelle les URL signées (Signed URLs).&lt;/p&gt;

&lt;p&gt;Une URL signée est une URL spéciale et unique qui contient une signature cryptographique. Cette signature accorde des permissions très spécifiques (par exemple, lire un objet précis) pour une durée limitée (par exemple, 5 minutes) à quiconque possède cette URL. Une fois le délai expiré, l'URL devient invalide.&lt;/p&gt;

&lt;p&gt;Les avantages sont immenses :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sécurité : Le bucket et ses objets restent privés. Vous n'ouvrez jamais l'accès publiquement.&lt;/li&gt;
&lt;li&gt;Contrôle granulaire : Vous accordez un accès à un seul objet, pour une seule action (lecture, écriture, suppression), et pour une durée que vous définissez.&lt;/li&gt;
&lt;li&gt;Simplicité : L'utilisateur final n'a pas besoin d'un compte Google ou de s'authentifier auprès de GCP. Il lui suffit de cliquer sur un lien.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voici comment générer une URL signée avec &lt;code&gt;gcloud&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prérequis&lt;/strong&gt; : Pour générer une signature, vous avez besoin d'une identité qui a la permission de le faire. Dans GCP, les identités pour les applications et les scripts s'appellent des "comptes de service". Vous devez en créer un et lui donner un rôle qui lui permet de lire les objets, par exemple &lt;em&gt;Storage Object Viewer&lt;/em&gt; (&lt;strong&gt;roles/storage.objectViewer&lt;/strong&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;La commande&lt;/strong&gt; : La méthode la plus moderne et sécurisée pour générer une URL signée est d'utiliser l'impersonation de compte de service. Votre compte utilisateur (avec lequel vous êtes authentifié dans &lt;code&gt;gcloud&lt;/code&gt;) demande à &lt;code&gt;gcloud&lt;/code&gt; de générer l'URL au nom du compte de service.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage sign-url gs://&amp;lt;PATH&amp;gt; &lt;span class="nt"&gt;--impersonate-service-account&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;ACCOUNT&amp;gt; &lt;span class="nt"&gt;--duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Décortiquons cette commande :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gs://[...]/[...]&lt;/code&gt; : Cible l'objet exact pour lequel vous voulez générer l'URL.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--impersonate-service-account&lt;/code&gt; : Spécifie l'email du compte de service qui a les permissions de lire l'objet. gcloud utilisera cette identité pour "signer" la requête.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--duration=10m&lt;/code&gt; : Définit la durée de validité de l'URL. Vous pouvez utiliser &lt;code&gt;s&lt;/code&gt; pour les secondes, &lt;code&gt;m&lt;/code&gt; pour les minutes, ou &lt;code&gt;h&lt;/code&gt; pour les heures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le résultat de cette commande est une longue URL que vous pouvez donner à votre utilisateur.&lt;/p&gt;

&lt;p&gt;Cette technique est plus qu'une simple astuce de sécurité ; c'est un puissant modèle d'architecture pour des applications cloud performantes. Un flux de travail naïf serait que l'utilisateur demande la facture à votre serveur, que votre serveur télécharge le fichier depuis GCS, puis le renvoie à l'utilisateur. Ce processus fait de votre serveur un goulot d'étranglement et consomme sa bande passante. Avec une URL signée, votre serveur ne fait que la partie légère : il vérifie les droits de l'utilisateur et génère l'URL. Ensuite, le transfert du fichier (la partie lourde) se fait directement entre le navigateur de l'utilisateur et l'infrastructure massive et ultra-performante de Google. Votre application devient ainsi plus rapide, moins chère à opérer et beaucoup plus scalable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Si vous avez suivi ce guide jusqu'au bout, vous avez accompli un parcours significatif. Vous avez non seulement appris les concepts fondamentaux de Google Cloud Storage comme les buckets et les objets, mais vous avez aussi mis les mains dans le cambouis avec les commandes essentielles (&lt;code&gt;create&lt;/code&gt;, &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;rm&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Plus important encore, vous avez commencé à penser comme un architecte cloud. Vous savez désormais que toutes les données ne se valent pas et vous avez découvert comment utiliser stratégiquement les classes de stockage et les règles de cycle de vie pour aligner les coûts sur la valeur de vos données. Enfin, avec les URL signées, vous disposez d'une technique de niveau professionnel pour construire des applications sécurisées et performantes qui partagent des données de manière contrôlée.&lt;/p&gt;

&lt;p&gt;Vous n'êtes plus un débutant complet. Vous possédez les connaissances fondamentales et une astuce puissante pour commencer à construire des solutions robustes et efficaces avec Google Cloud Storage. Le chemin ne s'arrête pas là. Vous pouvez maintenant explorer des fonctionnalités plus avancées comme la gestion des versions d'objets (Object Versioning) pour vous protéger contre les suppressions accidentelles, ou les notifications Pub/Sub pour déclencher des actions (comme le traitement d'une image) dès qu'un nouvel objet est uploadé. Le monde du stockage cloud est vaste, mais vous avez désormais une base solide pour l'explorer avec confiance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.google.com/cloud/answer/6250993?hl=en" rel="noopener noreferrer"&gt;https://support.google.com/cloud/answer/6250993?hl=en&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gcp.tools/article/Exploring_Google_Cloud_Storage_Features_Benefits_and_Use_Cases.html" rel="noopener noreferrer"&gt;https://gcp.tools/article/Exploring_Google_Cloud_Storage_Features_Benefits_and_Use_Cases.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://8grams.medium.com/gcp-101-google-cloud-storage-30471c98edbb" rel="noopener noreferrer"&gt;https://8grams.medium.com/gcp-101-google-cloud-storage-30471c98edbb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elite.cloud/post/google-cloud-storage-buckets-a-step-by-step-guide/" rel="noopener noreferrer"&gt;https://www.elite.cloud/post/google-cloud-storage-buckets-a-step-by-step-guide/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elite.cloud/post/google-cloud-storage-buckets-a-step-by-step-guide/" rel="noopener noreferrer"&gt;https://www.elite.cloud/post/google-cloud-storage-buckets-a-step-by-step-guide/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.terra.bio/hc/en-us/articles/6453490899099-gcloud-storage-tutorial" rel="noopener noreferrer"&gt;https://support.terra.bio/hc/en-us/articles/6453490899099-gcloud-storage-tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.uninets.com/blog/features-of-gcp" rel="noopener noreferrer"&gt;https://www.uninets.com/blog/features-of-gcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage/docs/discover-object-storage-console" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/discover-object-storage-console&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage/docs/best-practices" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/best-practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cloudkeeper.com/insights/blog/gcp-cost-optimization-top-10-effective-strategies-maximum-impact" rel="noopener noreferrer"&gt;https://www.cloudkeeper.com/insights/blog/gcp-cost-optimization-top-10-effective-strategies-maximum-impact&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/products/storage-data-transfer/best-practices-for-cloud-storage-cost-optimization" rel="noopener noreferrer"&gt;https://cloud.google.com/blog/products/storage-data-transfer/best-practices-for-cloud-storage-cost-optimization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage" rel="noopener noreferrer"&gt;https://cloud.google.com/storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage/docs/lifecycle" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/lifecycle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage/docs/lifecycle-configurations" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/lifecycle-configurations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudStorage/enable-lifecycle-management.html" rel="noopener noreferrer"&gt;https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudStorage/enable-lifecycle-management.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage/docs/access-control/signed-urls" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/access-control/signed-urls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pluralsight.com/labs/gcp/applying-signed-urls-to-cloud-storage-objects" rel="noopener noreferrer"&gt;https://www.pluralsight.com/labs/gcp/applying-signed-urls-to-cloud-storage-objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/cdn/docs/using-signed-urls" rel="noopener noreferrer"&gt;https://cloud.google.com/cdn/docs/using-signed-urls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@nikhil.nagarajappa/secure-uploads-with-signed-urls-in-google-cloud-storage-6dc1c728850e" rel="noopener noreferrer"&gt;https://medium.com/@nikhil.nagarajappa/secure-uploads-with-signed-urls-in-google-cloud-storage-6dc1c728850e&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers" rel="noopener noreferrer"&gt;https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://download.huihoo.com/google/gdgdevkit/DVD1/developers.google.com/storage/docs/gsutil/commands/signurl.html" rel="noopener noreferrer"&gt;https://download.huihoo.com/google/gdgdevkit/DVD1/developers.google.com/storage/docs/gsutil/commands/signurl.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cloud</category>
      <category>googlecloud</category>
      <category>google</category>
      <category>gcp</category>
    </item>
    <item>
      <title>IAP sur GKE : Google change les règles, êtes-vous prêt pour la migration ?</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Mon, 11 Aug 2025 17:01:05 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/iap-sur-gke-google-change-les-regles-etes-vous-pret-pour-la-migration--2g2</link>
      <guid>https://dev.to/laformulenuagique/iap-sur-gke-google-change-les-regles-etes-vous-pret-pour-la-migration--2g2</guid>
      <description>&lt;p&gt;Vous utilisez Identity-Aware Proxy (IAP) pour sécuriser l'accès à vos applications sur Google Kubernetes Engine (GKE) ? C'est une excellente pratique. IAP agit comme un garde du corps intelligent pour vos services, vérifiant l'identité de chaque utilisateur avant de lui laisser franchir la porte. C'est la solution idéale pour protéger une application interne ou un environnement de pré-production.&lt;/p&gt;

&lt;p&gt;Cependant, une annonce de Google est peut-être passée sous votre radar : la méthode historique pour activer IAP sur GKE est en cours de dépréciation. Si vous avez configuré IAP il y a quelque temps, il est fort probable que vous soyez concerné. Pas de panique ! Ce changement est en réalité une bonne nouvelle, et ce guide est là pour vous accompagner dans une migration tout en douceur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi ce changement ? L'ancien monde face au nouveau
&lt;/h2&gt;

&lt;p&gt;Pour comprendre l'intérêt de cette migration, revenons un instant sur la manière dont les choses fonctionnaient. Auparavant, pour activer IAP, il fallait se rendre dans la console Google Cloud, créer manuellement un client OAuth, puis copier-coller l'identifiant de ce client dans les annotations de votre ressource Ingress sur Kubernetes. Cette approche, bien que fonctionnelle, présentait quelques inconvénients. Elle mélangeait une configuration faite à la main dans la console avec des manifestes déclaratifs dans Kubernetes, ce qui n'est pas idéal pour l'automatisation et les pratiques GitOps.&lt;/p&gt;

&lt;p&gt;La nouvelle méthode est bien plus élégante et s'intègre parfaitement à l'écosystème Kubernetes. Tout se passe désormais à l'intérieur de votre cluster. La configuration d'IAP est définie via une ressource Kubernetes dédiée appelée BackendConfig. C'est une approche "Kubernetes-native" : votre configuration IAP vit aux côtés de vos déploiements et de vos services, directement dans vos fichiers YAML. C'est plus propre, plus simple à suivre et entièrement automatisable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le plan de migration, étape par étape
&lt;/h2&gt;

&lt;p&gt;Migrer vers la nouvelle méthode est un processus simple qui se déroule en quelques étapes logiques. L'objectif est de passer d'une configuration manuelle à une configuration déclarée dans votre cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Première étape : Vérifiez si vous êtes concerné
&lt;/h3&gt;

&lt;p&gt;La première chose à faire est de regarder la configuration de votre service Kubernetes. Plus précisément, inspectez les champs de votre ressource &lt;code&gt;GCPBackendPolicy&lt;/code&gt;. Si vous ne voyez pas de champ &lt;code&gt;iap.enabled: true&lt;/code&gt;, il y a de fortes chances que vous deviez migrer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deuxième étape : Définir votre GCPBackendPolicy
&lt;/h3&gt;

&lt;p&gt;C'est le cœur de la nouvelle configuration. Vous allez créer un nouveau fichier YAML pour une ressource de type &lt;code&gt;GCPBackendPolicy&lt;/code&gt;. Dans ce fichier, vous activerez IAP. Ce manifeste est très clair et se lit presque comme une phrase : "Active IAP pour ce backend".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.gke.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GCPBackendPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;policy&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;targetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;iap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Les avantages concrets de cette migration
&lt;/h2&gt;

&lt;p&gt;Ce changement n'est pas qu'une simple mise à jour technique, il apporte de réels bénéfices. Votre configuration de sécurité est désormais entièrement gérée "en tant que code" (as code), ce qui facilite le suivi des versions, les audits et les déploiements automatisés. Il n'est plus nécessaire de gérer les brands IAP et on peut simplifier l'utilisation des clients. Enfin, toute votre configuration d'application, de son déploiement à sa sécurité, est centralisée au sein de vos manifestes Kubernetes, simplifiant la gestion globale de votre projet.&lt;/p&gt;

&lt;h2&gt;
  
  
  N'attendez pas le dernier moment
&lt;/h2&gt;

&lt;p&gt;Google a fixé des dates butoirs pour cette dépréciation. Le 21 septembre 2025, l'ancienne API sera coupée. Même si la migration est simple, il est préférable de ne pas la remettre à plus tard pour éviter toute interruption de service. En adoptant dès maintenant cette nouvelle approche, vous modernisez votre infrastructure et vous vous alignez sur les meilleures pratiques de l'écosystème Kubernetes.&lt;/p&gt;

&lt;p&gt;Si cette migration vous semble complexe, si vous n'êtes pas sûr d'être concerné ou si vous souhaitez simplement un audit de vos pratiques de sécurité sur GCP, n'hésitez pas à faire appel à un expert. En tant que consultant freelance, je peux vous aider à naviguer ces changements et à garantir que votre infrastructure reste sécurisée, performante et à la pointe de la technologie.&lt;/p&gt;

</description>
      <category>gcp</category>
      <category>devops</category>
      <category>googlecloud</category>
      <category>iap</category>
    </item>
    <item>
      <title>Proxy-only subnet sur GCP : Le guide pour bien démarrer</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Fri, 11 Jul 2025 09:20:37 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/proxy-only-subnet-sur-gcp-le-guide-pour-bien-demarrer-3p0i</link>
      <guid>https://dev.to/laformulenuagique/proxy-only-subnet-sur-gcp-le-guide-pour-bien-demarrer-3p0i</guid>
      <description>&lt;p&gt;Vous êtes sur le point de déployer votre nouvelle application sur Google Cloud, et pour exposer celle-ci au monde, vous avez choisi un répartiteur de charge moderne basé sur Envoy. Il peut s'agir d'un Global External HTTPS Load Balancer ou de ses cousins régionaux. Au moment de la configuration, une question vous est posée : la création d'un "proxy-only subnet". C'est une étape obligatoire, mais qui soulève souvent des interrogations. Ce sous-réseau n'est pas destiné à vos machines virtuelles, mais il s'agit d'un espace réseau réservé que Google Cloud utilisera pour allouer des adresses IP à ses proxys Envoy managés. Ces proxys sont le cœur de votre répartiteur de charge. Comprendre comment dimensionner et gérer ce sous-réseau est donc essentiel pour garantir la performance et la scalabilité de vos services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quelle taille pour mon subnet ?
&lt;/h2&gt;

&lt;p&gt;La première décision à prendre concerne la taille de ce sous-réseau. La documentation de Google Cloud impose une taille minimale qui doit pouvoir fournir au moins 64 adresses IP, ce qui correspond à un masque de sous-réseau en &lt;code&gt;/26&lt;/code&gt;. Cependant, se contenter du strict minimum est rarement une bonne idée en production. L'approche recommandée est bien plus confortable. Il est conseillé de démarrer avec un préfixe en &lt;code&gt;/23&lt;/code&gt;, ce qui vous alloue 512 adresses IP. C'est un excellent point de départ qui offre une marge de manœuvre suffisante pour la plupart des applications, tout en restant raisonnable. Si votre réseau VPC commence à être à l'étroit en adresses privées RFC 1918, sachez qu'il est tout à fait possible d'utiliser une plage d'adresses non-RFC 1918 pour ce subnet spécifique, une astuce précieuse pour éviter les conflits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comment Google choisit le nombre de proxys ?
&lt;/h2&gt;

&lt;p&gt;Le véritable intérêt de ce système est son élasticité. Le nombre de proxys n'est pas fixe. Google Cloud l'ajuste dynamiquement en fonction du trafic que votre application reçoit. Toutes les dix minutes, le service évalue la capacité nécessaire pour gérer la charge et ajuste le nombre de proxys en conséquence. Pour ce faire, il se base sur le plus grand des besoins calculés entre la bande passante et le volume de connexions ou de requêtes.&lt;/p&gt;

&lt;p&gt;Imaginons que votre service diffuse des tutoriels vidéo. Chaque instance de proxy peut gérer jusqu'à 18 Mo par seconde de trafic. Si, pendant la période d'observation, votre application doit servir un total de 180 Mo par seconde, Google Cloud calculera qu'il a besoin de dix proxys pour satisfaire la demande en bande passante.&lt;/p&gt;

&lt;p&gt;Maintenant, pensons à un site de commerce en ligne durant une vente flash. Le calcul se portera sur les connexions et les requêtes. Un proxy peut gérer environ 600 nouvelles connexions par seconde en HTTP, ou 150 en HTTPS à cause de la charge supplémentaire du chiffrement. Il peut aussi maintenir 3000 connexions actives simultanément. Si votre site reçoit une vague de 2000 nouvelles connexions HTTPS par seconde, le système saura qu'il doit provisionner plus de treize proxys juste pour absorber ce pic de nouvelles connexions. De la même manière, un proxy peut traiter jusqu'à 1400 requêtes par seconde, un chiffre important pour les API très sollicitées.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'impact caché de la journalisation
&lt;/h2&gt;

&lt;p&gt;Un détail crucial à ne pas négliger est l'impact de la journalisation, ou logging, sur les performances. Le chiffre de 1400 requêtes par seconde est valable lorsque la journalisation via Cloud Logging est désactivée. Si vous décidez d'activer la journalisation pour 100% de vos requêtes afin d'avoir une observabilité complète, la capacité de traitement d'un proxy chute de moitié, pour atteindre environ 700 requêtes par seconde. Cela signifie que pour un même trafic, vous aurez besoin de deux fois plus de proxys, ce qui a une incidence directe sur la facture. Heureusement, il est possible de configurer l'échantillonnage des journaux pour ne tracer qu'un pourcentage du trafic, trouvant ainsi le juste équilibre entre observabilité et maîtrise des coûts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quelques détails importants
&lt;/h2&gt;

&lt;p&gt;Il est primordial de se rappeler que ces proxys sont alloués au niveau du VPC et de la région, et non par répartiteur de charge individuel. Vous devez donc créer un unique proxy-only subnet dans chaque région où vous déployez des répartiteurs de charge basés sur Envoy. Si vous avez trois load balancers différents dans la même région du même VPC, ils partageront tous le même pool de proxys hébergés dans ce subnet. Enfin, n'oubliez pas que chaque proxy provisionné pour répondre à vos besoins en trafic engendre un coût horaire supplémentaire. La compréhension de ces mécanismes de mise à l'échelle vous permet non seulement d'anticiper les performances, mais aussi d'estimer plus finement vos dépenses sur le cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Le proxy-only subnet peut sembler n'être qu'un détail technique dans la configuration d'un load balancer sur GCP. Pourtant, le choix de sa taille initiale et la compréhension de son fonctionnement dynamique sont des éléments clés pour construire une architecture robuste et évolutive. En démarrant avec une taille confortable comme un &lt;code&gt;/23&lt;/code&gt; et en gardant à l'esprit les facteurs qui influencent le scaling automatique, vous vous assurez que votre infrastructure pourra encaisser les montées en charge sans sourciller. Vous avez maintenant toutes les cartes en main pour dimensionner ce composant essentiel avec confiance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Documentation Google Cloud : &lt;a href="https://cloud.google.com/load-balancing/docs/proxy-only-subnets#planning_the_size_of_your_proxy-only_subnet" rel="noopener noreferrer"&gt;Planning the size of your proxy-only subnet&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gcp</category>
      <category>googlecloud</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Le chaînon manquant de la documentation GCP : cartographier la toile invisible des dépendances d'API</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Tue, 10 Jun 2025 23:58:53 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/le-chainon-manquant-de-la-documentation-gcp-cartographier-la-toile-invisible-des-dependances-dapi-33o</link>
      <guid>https://dev.to/laformulenuagique/le-chainon-manquant-de-la-documentation-gcp-cartographier-la-toile-invisible-des-dependances-dapi-33o</guid>
      <description>&lt;p&gt;Naviguer dans l'écosystème Google Cloud Platform peut parfois s'apparenter à l'exploration d'une métropole tentaculaire. Des centaines de services, chacun doté de sa propre puissance, offrent des possibilités quasi infinies. Mais comme dans toute grande ville, des réseaux souterrains et invisibles connectent chaque quartier. Dans GCP, ces réseaux sont les dépendances entre les services d'API, des liens cruciaux mais étonnamment absents des cartes officielles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constat
&lt;/h2&gt;

&lt;p&gt;Quand on travaille avec Google Cloud Platform (GCP), on finit toujours par passer par la case &lt;code&gt;gcloud services enable&lt;/code&gt;. Que ce soit pour Cloud Functions, BigQuery, ou l’incontournable IAM, chaque service repose sur un ensemble parfois obscur d’APIs qu’il faut activer dans un ordre souvent flou. Et pourtant, la documentation officielle ne fournit aucune carte des dépendances entre ces services. Impossible de savoir à l’avance si désactiver &lt;code&gt;anthos.googleapis.com&lt;/code&gt; va faire tomber dix autres services — jusqu’à ce que cela vous arrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le résultat obtenu
&lt;/h2&gt;

&lt;p&gt;C'est face à cette opacité que l'idée a germé : pourquoi ne pas construire la carte nous-mêmes ? C'est ainsi qu'est née l'application web que j'ai développée, disponible sur &lt;a href="https://gcp.gar%C3%A7on.fr/" rel="noopener noreferrer"&gt;gcp.garçon.fr&lt;/a&gt;. L'objectif était simple : offrir une vue claire, interactive et intuitive de la toile des dépendances entre les services de Google Cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffb5x7gajhp5h1594zkns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffb5x7gajhp5h1594zkns.png" alt="Image description" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L'application se présente comme une page unique, sobre, inspirée du design de Google pour ne pas dépayser les habitués. Elle s'articule autour de trois composants essentiels. Au centre, un graphe dynamique représente l'ensemble des services sous forme de nœuds. Lorsqu'une dépendance existe, une arête les relie, matérialisant enfin ces connexions invisibles. Sur la droite, une liste exhaustive de tous les services permet une recherche et une identification rapide.&lt;/p&gt;

&lt;p&gt;La véritable valeur ajoutée se révèle à l'interaction. En sélectionnant un service, que ce soit dans la liste ou directement sur le graphe, l'interface s'anime. Le graphe zoome sur le nœud choisi et met en évidence ses relations. Les dépendances que le service consomme (ce dont il a besoin pour fonctionner) s'affichent en rouge, tandis que les services qui, à l'inverse, dépendent de lui, se colorent en vert. Simultanément, le panneau de droite se transforme pour afficher un résumé détaillé, listant clairement ces deux catégories : "Depends On" et "Dependency Of". La complexité se démêle sous nos yeux.&lt;/p&gt;

&lt;p&gt;L'application elle-même est bâtie sur des technologies web standards, s'appuyant sur la puissante bibliothèque JavaScript Vis.js pour la partie la plus complexe : le rendu et la physique du graphe. Le résultat est un outil léger, rapide et ne nécessitant aucune installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cartographier les dépendances entre APIs GCP : là où la doc s'arrête, le code commence
&lt;/h2&gt;

&lt;p&gt;Le défi principal n'était pas tant technique que informationnel. Il a fallu patiemment compiler et croiser les informations pour établir cette cartographie. La méthode repose sur un test systématique des APIs. On commence par créer un projet GCP vierge. Ensuite, on active toutes les APIs disponibles (oui, ça fait beaucoup de trafic réseau), puis on les désactive une par une. À chaque tentative de désactivation, si une erreur apparaît mentionnant qu’un service est « depended on by the following active service(s) », on enregistre la relation. En réactivant ensuite l’API désactivée, on revient à l’état initial pour recommencer avec la suivante. C’est fastidieux, long (très long), mais redoutablement efficace.&lt;/p&gt;

&lt;p&gt;Les résultats sont ensuite collectés dans un simple fichier texte de type &lt;code&gt;serviceA=&amp;gt;serviceB&lt;/code&gt;, signifiant que &lt;code&gt;serviceB&lt;/code&gt; dépend de &lt;code&gt;serviceA&lt;/code&gt;. Ce fichier brut a été transformé en graphe interactif sur le site. Il est possible de cliquer sur une API et de voir en temps réel quelles autres APIs en dépendent, ou inversement, lesquelles elle requiert pour fonctionner.&lt;/p&gt;

&lt;p&gt;L’enjeu dépasse la simple curiosité. Dans une logique DevSecOps ou de gouvernance fine du cloud, il est essentiel de savoir ce que l’on expose, ce qui est actif, et surtout ce que l’on pourrait désactiver sans effet de bord. Google fournit bien des descriptions d’API, mais reste silencieux sur leurs dépendances techniques. Ce manque de transparence, sans doute volontaire pour des raisons d’évolution interne, peut poser problème dans des environnements contraints.&lt;/p&gt;

&lt;p&gt;L'application n’a pas la prétention d’être exhaustive ni parfaite. Elle se base sur des expérimentations dans un contexte contrôlé, sur un seul projet vierge. Mais elle a déjà mis en lumière des dépendances inattendues — comme le fait que certains services de réseau ou de machine learning sont étroitement liés à des APIs que l’on aurait pensé optionnelles.&lt;/p&gt;

&lt;p&gt;Au-delà de la simple curiosité intellectuelle, cet outil apporte une valeur tangible. Pour un architecte cloud, il permet d'anticiper les besoins et de concevoir des infrastructures plus robustes. Pour un développeur, il accélère le diagnostic des erreurs de configuration. Pour un responsable FinOps, il offre une meilleure visibilité sur les coûts indirects qu'un service peut engendrer en sollicitant d'autres API facturables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;En résumé, quand la documentation ne suffit plus, il faut expérimenter. Et si ce travail peut servir à d'autres, tant mieux. La cartographie est disponible publiquement, sans inscription ni tracking. C’est un outil de plus pour comprendre un peu mieux cette immense boîte noire qu’est parfois GCP. Cette application ne prétend pas remplacer la documentation officielle, mais plutôt la compléter là où elle est silencieuse. Elle est une invitation à explorer, à comprendre et à maîtriser la mécanique interne de Google Cloud. La complexité n'est pas une fatalité lorsqu'on dispose des bons outils pour la visualiser. Je vous invite à l'explorer sur &lt;a href="https://gcp.gar%C3%A7on.fr/" rel="noopener noreferrer"&gt;gcp.garçon.fr&lt;/a&gt; et à voir par vous-même la structure cachée de la plateforme que nous utilisons chaque jour.&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>gcp</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Introduction à OpenTofu pour les utilisateurs Terraform</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Sun, 11 May 2025 21:57:33 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/introduction-a-opentofu-pour-les-utilisateurs-terraform-4e9l</link>
      <guid>https://dev.to/laformulenuagique/introduction-a-opentofu-pour-les-utilisateurs-terraform-4e9l</guid>
      <description>&lt;p&gt;OpenTofu est un fork communautaire de Terraform, compatible en grande partie avec ce dernier, mais qui prend une orientation technique différente sur certains points clés. Pour les utilisateurs expérimentés de Terraform, la transition vers OpenTofu est quasi transparente tout en offrant des fonctionnalités avancées comme le chiffrement natif de l'état ou une évaluation anticipée des expressions.&lt;/p&gt;

&lt;p&gt;Ce tutoriel illustre l'utilisation d'OpenTofu pour déployer une architecture répartie sur deux régions GCP avec deux machines virtuelles GCE faisant tourner NGINX, exposées via un Global Load Balancer. Le backend de stockage d'état utilisera GitLab comme source de vérité.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation d'OpenTofu
&lt;/h2&gt;

&lt;p&gt;Installation Debian/Ubuntu :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.opentofu.org/install-opentofu.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--install-method&lt;/span&gt; deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour vérifier la bonne installation de OpenTofu :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tofu version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration du backend GitLab
&lt;/h2&gt;

&lt;p&gt;GitLab permet de stocker l'état via un repository en tant que backend "HTTP" compatible.&lt;/p&gt;

&lt;p&gt;Exemple &lt;code&gt;terragrunt.hcl&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yamldecode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"config.yaml"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nx"&gt;gitlab_project_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;
  &lt;span class="nx"&gt;gitlab_username&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;
  &lt;span class="nx"&gt;gitlab_token&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;get_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"GITLAB_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;gitlab_path&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"blog"&lt;/span&gt;
  &lt;span class="nx"&gt;gitlab_url&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://gitlab.com/api/v4/projects/${local.gitlab_project_id}/terraform/state/${local.gitlab_path}"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"backend"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;path&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"backend.tf"&lt;/span&gt;
  &lt;span class="nx"&gt;if_exists&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"overwrite_terragrunt"&lt;/span&gt;
  &lt;span class="nx"&gt;contents&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
terraform {
  backend "http" {
    address        = "${local.gitlab_url}"
    lock_address   = "${local.gitlab_url}/lock"
    unlock_address = "${local.gitlab_url}/lock"
    username       = "${local.gitlab_username}"
    password       = "${local.gitlab_token}"
    lock_method    = "POST"
    unlock_method  = "DELETE"
    retry_wait_min = 5
  }
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"providers"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;path&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"providers.tf"&lt;/span&gt;
  &lt;span class="nx"&gt;if_exists&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"overwrite_terragrunt"&lt;/span&gt;
  &lt;span class="nx"&gt;contents&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
provider "google" {
  project = "${local.config.cloud.project_id}"
  region  = "${local.config.cloud.region}"
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ce module Terragrunt va charger un fichier &lt;code&gt;config.yaml&lt;/code&gt; de ce type :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;gitlab&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;project_id&amp;gt;"&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;username&amp;gt;"&lt;/span&gt;

&lt;span class="na"&gt;cloud&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;gcp_project_id&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;europe-west9&lt;/span&gt;
  &lt;span class="na"&gt;workload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;france&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0000BB"&lt;/span&gt;
      &lt;span class="na"&gt;machine&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e2-micro&lt;/span&gt;
      &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;europe-west9&lt;/span&gt;
      &lt;span class="na"&gt;traffic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.80&lt;/span&gt;
    &lt;span class="na"&gt;belgium&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#BB0000"&lt;/span&gt;
      &lt;span class="na"&gt;machine&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e2-micro&lt;/span&gt;
      &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;europe-west1&lt;/span&gt;
      &lt;span class="na"&gt;traffic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Remplacez &lt;code&gt;&amp;lt;project_id&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;gcp_project_id&amp;gt;&lt;/code&gt;, et les identifiants par les vôtres. Le projet doit être configuré pour permettre le remote backend via HTTP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pour pouvoir utiliser OpenTofu et le backend GitLab, il faut aussi exporter une variable d'environnement :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GITLAB_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Infrastructure cible
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deux instances GCE (dans &lt;code&gt;europe-west9&lt;/code&gt; et &lt;code&gt;europe-west1&lt;/code&gt;) avec NGINX&lt;/li&gt;
&lt;li&gt;Global Load Balancer HTTP(S)&lt;/li&gt;
&lt;li&gt;Priorité pondérée sur les backends (ex : 80/20)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exemple d’infrastructure (fichiers principaux)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;workload.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_instance"&lt;/span&gt; &lt;span class="s2"&gt;"nginx"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workload&lt;/span&gt;

  &lt;span class="nx"&gt;machine_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;machine&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nginx-${each.key}"&lt;/span&gt;
  &lt;span class="nx"&gt;zone&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${each.value.region}-b"&lt;/span&gt;

  &lt;span class="nx"&gt;boot_disk&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;initialize_params&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"debian-cloud/debian-12"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;network_interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;
    &lt;span class="nx"&gt;access_config&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;metadata_startup_script&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
    #!/bin/bash
    apt-get update
    apt-get install -y nginx
    echo " &amp;lt;!DOCTYPE html&amp;gt; &amp;lt;html lang="fr"&amp;gt; &amp;lt;head&amp;gt; &amp;lt;meta charset="UTF-8"&amp;gt; &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt; &amp;lt;title&amp;gt;${upper(each.key)}&amp;lt;/title&amp;gt; &amp;lt;style&amp;gt; body { background-color: ${each.value.color}; color: white; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial, sans-serif; } h1 { font-size: 5rem; } &amp;lt;/style&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body&amp;gt; &amp;lt;h1&amp;gt;${upper(each.key)}&amp;lt;/h1&amp;gt; &amp;lt;/body&amp;gt; &amp;lt;/html&amp;gt;" &amp;gt; /var/www/html/index.nginx-debian.html
    systemctl restart nginx
&lt;/span&gt;&lt;span class="no"&gt;  EOF

&lt;/span&gt;  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;google_project_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apis&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;load_balancing.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_instance_group"&lt;/span&gt; &lt;span class="s2"&gt;"group"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workload&lt;/span&gt;

  &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"group-${each.key}"&lt;/span&gt;
  &lt;span class="nx"&gt;zone&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${each.value.region}-b"&lt;/span&gt;
  &lt;span class="nx"&gt;instances&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;google_compute_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;self_link&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;named_port&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http"&lt;/span&gt;
    &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_health_check"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http-health-check"&lt;/span&gt;
  &lt;span class="nx"&gt;check_interval_sec&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="nx"&gt;timeout_sec&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

  &lt;span class="nx"&gt;http_health_check&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_backend_service"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nginx-backend"&lt;/span&gt;
  &lt;span class="nx"&gt;load_balancing_scheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"EXTERNAL"&lt;/span&gt;
  &lt;span class="nx"&gt;port_name&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http"&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"HTTP"&lt;/span&gt;
  &lt;span class="nx"&gt;timeout_sec&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="nx"&gt;health_checks&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;google_compute_health_check&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;self_link&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="s2"&gt;"backend"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workload&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;group&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_instance_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;self_link&lt;/span&gt;
      &lt;span class="nx"&gt;balancing_mode&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"UTILIZATION"&lt;/span&gt;
      &lt;span class="nx"&gt;capacity_scaler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traffic&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_url_map"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"url-map"&lt;/span&gt;
  &lt;span class="nx"&gt;default_service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_backend_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;self_link&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_target_http_proxy"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http-proxy"&lt;/span&gt;
  &lt;span class="nx"&gt;url_map&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_url_map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;self_link&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_global_forwarding_rule"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http-forwarding-rule"&lt;/span&gt;
  &lt;span class="nx"&gt;target&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_target_http_proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;self_link&lt;/span&gt;
  &lt;span class="nx"&gt;port_range&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;
  &lt;span class="nx"&gt;load_balancing_scheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"EXTERNAL"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;network.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_firewall"&lt;/span&gt; &lt;span class="s2"&gt;"allow_http"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"allow-http"&lt;/span&gt;
  &lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;

  &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;ports&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;source_ranges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;target_tags&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;api.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_project_service"&lt;/span&gt; &lt;span class="s2"&gt;"apis"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"compute.googleapis.com"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;variables.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"config"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Utilisation de Terragrunt avec OpenTofu
&lt;/h2&gt;

&lt;p&gt;Terragrunt est pleinement compatible avec OpenTofu. Il suffit de remplacer la commande &lt;code&gt;terraform&lt;/code&gt; par &lt;code&gt;tofu&lt;/code&gt; dans votre via votre variable TERRAGRUNT_TFPATH :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TERRAGRUNT_TFPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tofu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Ce projet démontre la maturité d'OpenTofu pour gérer des infrastructures complexes tout en restant compatible avec l'écosystème Terraform. Couplé à Terragrunt, il devient un outil de choix pour l'automatisation multi-environnement. L'intégration avec GitLab pour la gestion d'état et les pipelines CI renforce encore sa pertinence pour des workflows GitOps en production : il est tout aussi cpable que Terraform.&lt;/p&gt;

&lt;p&gt;Grâce à une configuration modulaire, un backend distant sécurisé, et une exposition via un load balancer global, ce cas d’usage illustre comment industrialiser un déploiement cloud fiable avec des outils modernes, ouverts et maintenus par la communauté.&lt;/p&gt;

&lt;h2&gt;
  
  
  Références
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OpenTofu documentation : &lt;a href="https://opentofu.org/docs/" rel="noopener noreferrer"&gt;https://opentofu.org/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitLab HTTP backend support : &lt;a href="https://docs.gitlab.com/ee/user/infrastructure/terraform_backend.html" rel="noopener noreferrer"&gt;https://docs.gitlab.com/ee/user/infrastructure/terraform_backend.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GCP Terraform provider : &lt;a href="https://registry.terraform.io/providers/hashicorp/google/latest/docs" rel="noopener noreferrer"&gt;https://registry.terraform.io/providers/hashicorp/google/latest/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Terragrunt official site : &lt;a href="https://terragrunt.gruntwork.io/" rel="noopener noreferrer"&gt;https://terragrunt.gruntwork.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Exemple Load Balancer GCP avec Terraform : &lt;a href="https://cloud.google.com/load-balancing/docs/https/ext-https-lb-tf" rel="noopener noreferrer"&gt;https://cloud.google.com/load-balancing/docs/https/ext-https-lb-tf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>terraform</category>
      <category>devops</category>
    </item>
    <item>
      <title>KubeCon Europe 2025 : entre hype et réalité</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Fri, 11 Apr 2025 11:41:46 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/kubecon-europe-2025-entre-hype-et-realite-3pm6</link>
      <guid>https://dev.to/laformulenuagique/kubecon-europe-2025-entre-hype-et-realite-3pm6</guid>
      <description>&lt;p&gt;La semaine dernière, j'ai eu le plaisir de participer à la KubeCon Europe 2025, qui s'est tenue à Londres du 1er au 4 avril. Cet événement est l'un des plus grands rassemblements de la communauté cloud native en Europe, réunissant développeurs, architectes, et passionnés autour des technologies open source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Une ambiance dynamique
&lt;/h2&gt;

&lt;p&gt;Dès mon arrivée, j'ai été impressionné par l'effervescence qui régnait au sein de l'ExCeL London. Avec 229 sessions programmées, allant des keynotes inspirantes aux ateliers techniques, en passant par des lightning talks percutants, il y en avait pour tous les goûts. Les co-located events, tels que l'ArgoCon, ont offert des perspectives sur leurs roadmaps spécifiques.&lt;/p&gt;

&lt;h2&gt;
  
  
  Des échanges engagés
&lt;/h2&gt;

&lt;p&gt;Au-delà des conférences, ce sont les rencontres qui ont marqué mon expérience. Les discussions informelles lors des pauses café, les échanges sur les stands des sponsors, et les afterworks ont été autant d'occasions de partager des retours d'expérience, de découvrir de nouveaux outils, et de tisser des liens avec des professionnels venus des quatre coins du monde.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Une omniprésence de l'IA, parfois au détriment de la profondeur technique
&lt;/h2&gt;

&lt;p&gt;Cependant, un aspect m'a quelque peu déçu : la présence omniprésente de l'intelligence artificielle. Bien que l'IA soit un sujet incontournable, j'ai eu le sentiment que de nombreuses présentations l'abordaient de manière superficielle, plus comme un argument marketing que comme une réelle avancée technique. Certains talks semblaient manquer de profondeur, privilégiant les effets d'annonce aux démonstrations concrètes.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Un événement à la croisée des chemins
&lt;/h2&gt;

&lt;p&gt;En conclusion, la KubeCon Europe 2025 a été une expérience enrichissante, tant sur le plan professionnel que personnel. L'organisation impeccable, la diversité des sessions, et la richesse des échanges en font un rendez-vous incontournable pour tout professionnel du cloud native. Néanmoins, j'espère que les prochaines éditions sauront rééquilibrer le contenu, en mettant davantage l'accent sur la profondeur technique et les retours d'expérience concrets, afin de satisfaire les attentes des praticiens chevronnés.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubecon</category>
      <category>kubernetes</category>
      <category>london</category>
    </item>
    <item>
      <title>Simplifiez votre infra avec les Stacks Terragrunt</title>
      <dc:creator>Benoît Garçon</dc:creator>
      <pubDate>Tue, 11 Mar 2025 21:03:48 +0000</pubDate>
      <link>https://dev.to/laformulenuagique/simplifiez-votre-infra-avec-les-stacks-terragrunt-50mk</link>
      <guid>https://dev.to/laformulenuagique/simplifiez-votre-infra-avec-les-stacks-terragrunt-50mk</guid>
      <description>&lt;p&gt;Terragrunt, l'outil de gestion de configurations pour Terraform, a récemment introduit une fonctionnalité majeure : les stacks. Cette nouveauté vise à simplifier et optimiser la gestion des infrastructures en réduisant la répétition et en améliorant l'organisation des configurations. Dans cet article, nous explorerons en détail cette fonctionnalité, en la rendant accessible aux débutants tout en fournissant des informations approfondies pour les experts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qu'est-ce qu'une Stack dans Terragrunt ?
&lt;/h2&gt;

&lt;p&gt;Dans le contexte de Terragrunt, une &lt;em&gt;stack&lt;/em&gt; est une collection d'unités gérées ensemble. Elle peut représenter un environnement complet, tel que &lt;em&gt;dev&lt;/em&gt;, &lt;em&gt;staging&lt;/em&gt; ou &lt;em&gt;prod&lt;/em&gt;, ou un projet entier. Les stacks permettent de gérer la complexité liée à la gestion de multiples unités à travers différents environnements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi les Stacks ?
&lt;/h2&gt;

&lt;p&gt;Avant l'introduction des stacks, les utilisateurs de Terragrunt devaient souvent gérer un grand nombre de fichiers &lt;code&gt;terragrunt.hcl&lt;/code&gt;, ce qui entraînait une répétition et une complexité accrues. Les stacks offrent une abstraction au-dessus de ces fichiers, permettant de regrouper et de gérer plusieurs unités au sein d'une seule configuration. Cette approche réduit la redondance et facilite la maintenance des configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fonctionnalités clés des Stacks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fichier &lt;code&gt;terragrunt.stack.hcl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Le fichier &lt;code&gt;terragrunt.stack.hcl&lt;/code&gt; est au cœur de cette nouvelle fonctionnalité. Il sert de raccourci pour définir une stack, similaire à la manière dont les unités peuvent être définies directement dans un dossier. Ce fichier permet de centraliser la configuration de plusieurs unités, simplifiant ainsi la gestion et la lisibilité.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bloc &lt;code&gt;unit&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Au sein du fichier &lt;code&gt;terragrunt.stack.hcl&lt;/code&gt;, le bloc &lt;code&gt;unit&lt;/code&gt; est utilisé pour définir une unité de déploiement. Chaque unité représente un composant d'infrastructure distinct à déployer dans le cadre de la stack. Le bloc &lt;code&gt;unit&lt;/code&gt; prend en charge plusieurs arguments, permettant une configuration détaillée et flexible de chaque composant.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commande &lt;code&gt;terragrunt stack output&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Terragrunt introduit la commande &lt;code&gt;terragrunt stack output&lt;/code&gt;, qui permet aux utilisateurs de récupérer et d'interagir avec les sorties de plusieurs unités au sein d'une stack. Cette fonctionnalité simplifie la gestion des sorties d'infrastructure en les consolidant en une vue unique.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avantages des Stacks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Réduction de la répétition&lt;/strong&gt; : En consolidant les configurations, les stacks diminuent la duplication de code, rendant les configurations plus propres et plus faciles à maintenir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gestion simplifiée des dépendances&lt;/strong&gt; : Les stacks permettent de définir clairement les dépendances entre les unités, assurant que les composants d'infrastructure sont déployés dans le bon ordre.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visualisation améliorée&lt;/strong&gt; : Avec les stacks, il est plus facile de visualiser et de comprendre la structure et les relations au sein de l'infrastructure, ce qui facilite la planification et le dépannage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considérations actuelles
&lt;/h2&gt;

&lt;p&gt;Bien que les stacks apportent de nombreux avantages, il est important de noter que cette fonctionnalité est encore en phase expérimentale. Pour qu'elle soit stabilisée, plusieurs aspects doivent être abordés, notamment :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support des commandes stack&lt;/strong&gt; : Ajouter la prise en charge des commandes &lt;code&gt;stack run *&lt;/code&gt; pour étendre les opérations au niveau des stacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support des sorties stack&lt;/strong&gt; : Intégrer les commandes &lt;code&gt;stack output&lt;/code&gt; pour améliorer l'interaction avec les sorties des stacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support des valeurs de stack&lt;/strong&gt; : Introduire la gestion des "valeurs" au niveau des stacks pour une configuration plus flexible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support des stacks récursives&lt;/strong&gt; : Permettre la gestion de stacks imbriquées pour des architectures d'infrastructure plus complexes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tests d'intégration&lt;/strong&gt; : Effectuer des tests approfondis pour assurer une gestion fluide des stacks dans divers scénarios opérationnels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compatibilité avec le parallélisme&lt;/strong&gt; : Vérifier la compatibilité avec les indicateurs de parallélisme, en particulier pour les stacks avec des dépendances.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exemple d'application
&lt;/h2&gt;

&lt;p&gt;Voici un exemple de &lt;strong&gt;stack Terragrunt&lt;/strong&gt; sur &lt;strong&gt;Google Cloud Platform (GCP)&lt;/strong&gt;. Cette stack va gérer :  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;VPC&lt;/strong&gt; avec un sous-réseau
&lt;/li&gt;
&lt;li&gt;Une &lt;strong&gt;instance Compute Engine&lt;/strong&gt; (VM)
&lt;/li&gt;
&lt;li&gt;Une &lt;strong&gt;base de données Cloud SQL&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Structure du projet
&lt;/h3&gt;

&lt;p&gt;On va organiser le projet en trois modules Terraform :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcp-stack/
│── modules/
│   │── vpc/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │── compute/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │── database/
│       ├── main.tf
│       ├── variables.tf
│       ├── outputs.tf
│── terragrunt.stack.hcl
│── terragrunt.hcl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Définition de la stack (&lt;code&gt;terragrunt.stack.hcl&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Dans &lt;strong&gt;Terragrunt&lt;/strong&gt;, une stack est définie dans le fichier &lt;code&gt;terragrunt.stack.hcl&lt;/code&gt;. Voici un exemple :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Activer la fonctionnalité expérimentale des stacks&lt;/span&gt;
&lt;span class="nx"&gt;experiments&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"stacks"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="s2"&gt;"gcp-infra"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Infrastructure GCP avec VPC, VM et base de données"&lt;/span&gt;

  &lt;span class="nx"&gt;unit&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/vpc"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;unit&lt;/span&gt; &lt;span class="s2"&gt;"compute"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/compute"&lt;/span&gt;
    &lt;span class="nx"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"vpc"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;unit&lt;/span&gt; &lt;span class="s2"&gt;"database"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/database"&lt;/span&gt;
    &lt;span class="nx"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"vpc"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explications
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;La stack &lt;strong&gt;"gcp-infra"&lt;/strong&gt; regroupe trois &lt;strong&gt;units&lt;/strong&gt; : &lt;code&gt;vpc&lt;/code&gt;, &lt;code&gt;compute&lt;/code&gt;, &lt;code&gt;database&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Chaque unit représente un module Terraform
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compute&lt;/code&gt; et &lt;code&gt;database&lt;/code&gt; dépendent du &lt;code&gt;vpc&lt;/code&gt;, donc ils ne seront déployés qu'après
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Configuration Terragrunt (&lt;code&gt;terragrunt.hcl&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ce fichier permet d'éviter les répétitions et de centraliser certaines configurations :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${path_relative_to_include()}"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;remote_state&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gcs"&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-terraform-state-bucket"&lt;/span&gt;
    &lt;span class="nx"&gt;prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${path_relative_to_include()}"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;project_id&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-gcp-project"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-central1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Module VPC (&lt;code&gt;modules/vpc/main.tf&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ce module crée un &lt;strong&gt;VPC&lt;/strong&gt; avec un sous-réseau :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_network"&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-vpc"&lt;/span&gt;
  &lt;span class="nx"&gt;auto_create_subnetworks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_subnetwork"&lt;/span&gt; &lt;span class="s2"&gt;"subnet"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-subnet"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;
  &lt;span class="nx"&gt;network&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;ip_cidr_range&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/24"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"vpc_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_subnetwork&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Module Compute Engine (&lt;code&gt;modules/compute/main.tf&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ce module déploie une &lt;strong&gt;VM&lt;/strong&gt; qui utilise le VPC créé :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_instance"&lt;/span&gt; &lt;span class="s2"&gt;"vm"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-vm"&lt;/span&gt;
  &lt;span class="nx"&gt;machine_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"e2-medium"&lt;/span&gt;
  &lt;span class="nx"&gt;zone&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.region}-a"&lt;/span&gt;

  &lt;span class="nx"&gt;boot_disk&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;initialize_params&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"debian-cloud/debian-11"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;network_interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;network&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc_id&lt;/span&gt;
    &lt;span class="nx"&gt;subnetwork&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnet_id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"vm_ip"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network_interface&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;network_ip&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Module Cloud SQL (&lt;code&gt;modules/database/main.tf&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ce module crée une &lt;strong&gt;base de données Cloud SQL&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_sql_database_instance"&lt;/span&gt; &lt;span class="s2"&gt;"db"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-database"&lt;/span&gt;
  &lt;span class="nx"&gt;database_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"MYSQL_8_0"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;

  &lt;span class="nx"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"db-f1-micro"&lt;/span&gt;
    &lt;span class="nx"&gt;ip_configuration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;private_network&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc_id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"db_instance"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_sql_database_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection_name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Déploiement de la stack
&lt;/h3&gt;

&lt;p&gt;Avec &lt;strong&gt;Terragrunt&lt;/strong&gt;, il est possible d'exécuter toutes les unités de la stack en une seule commande :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terragrunt run-all apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette commande :  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Déploie d'abord le &lt;strong&gt;VPC&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Puis la &lt;strong&gt;VM&lt;/strong&gt; et la &lt;strong&gt;base de données&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Gère les dépendances automatiquement
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour voir les outputs de toute la stack :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terragrunt stack output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les &lt;strong&gt;stacks dans Terragrunt&lt;/strong&gt; offrent une &lt;strong&gt;organisation claire&lt;/strong&gt; et &lt;strong&gt;une gestion automatique des dépendances&lt;/strong&gt; entre les modules. Sur GCP, elles permettent de déployer une infrastructure complète &lt;strong&gt;en une seule commande&lt;/strong&gt;, tout en centralisant la configuration.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;L'introduction des stacks dans Terragrunt représente une avancée significative pour la gestion des infrastructures en tant que code. En offrant une abstraction au-dessus des configurations existantes, les stacks simplifient la gestion, réduisent la répétition et améliorent la clarté des infrastructures complexes. Bien que la fonctionnalité soit encore en phase expérimentale, elle offre déjà des outils puissants pour les praticiens du cloud, qu'ils soient novices ou experts.&lt;/p&gt;

&lt;p&gt;Pour ceux qui souhaitent explorer davantage cette fonctionnalité, il est recommandé de consulter la documentation officielle de Terragrunt et de participer aux discussions communautaires pour rester informés des évolutions futures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://terragrunt.gruntwork.io/docs/features/stacks/" rel="noopener noreferrer"&gt;https://terragrunt.gruntwork.io/docs/features/stacks/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://terragrunt.gruntwork.io/docs/reference/experiments/#stacks" rel="noopener noreferrer"&gt;https://terragrunt.gruntwork.io/docs/reference/experiments/#stacks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gruntwork-io/terragrunt/issues/3313" rel="noopener noreferrer"&gt;https://github.com/gruntwork-io/terragrunt/issues/3313&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>terragrunt</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
