<?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: Thibault CORDIER ☁</title>
    <description>The latest articles on DEV Community by Thibault CORDIER ☁ (@laeline).</description>
    <link>https://dev.to/laeline</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%2Fuser%2Fprofile_image%2F497613%2F077a0154-5f51-4d62-9592-18108bd4c0be.jpg</url>
      <title>DEV Community: Thibault CORDIER ☁</title>
      <link>https://dev.to/laeline</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/laeline"/>
    <language>en</language>
    <item>
      <title>Retour d'expérience : Quand ECS s'impose comme une alternative pertinente à Kubernetes</title>
      <dc:creator>Thibault CORDIER ☁</dc:creator>
      <pubDate>Tue, 19 Nov 2024 20:30:14 +0000</pubDate>
      <link>https://dev.to/aws-builders/retour-dexperience-quand-ecs-simpose-comme-une-alternative-pertinente-a-kubernetes-244a</link>
      <guid>https://dev.to/aws-builders/retour-dexperience-quand-ecs-simpose-comme-une-alternative-pertinente-a-kubernetes-244a</guid>
      <description>&lt;p&gt;Ces derniers mois, j'ai accompagné un client dans sa transition d'une infrastructure traditionnelle AWS (EC2 + Auto Scaling Groups, orchestrée via CodePipeline et CodeDeploy) vers AWS ECS. &lt;/p&gt;

&lt;p&gt;Cette migration, que nous appréhendions initialement, s'est révélée étonnamment fluide. Avec peu d'effort, nous avons réussi à mettre en place une infrastructure conteneurisée robuste et efficace, tout en conservant les avantages de l'intégration continue déjà en place.&lt;/p&gt;

&lt;p&gt;Cette expérience m'a ouvert les yeux : ECS ne serait-il pas trop souvent négligé au profit de Kubernetes, particulièrement pour les structures de taille moyenne qui cherchent à moderniser leur infrastructure sans complexité excessive ?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La tendance Kubernetes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ces dernières années, nous avons assisté à une adoption massive de Kubernetes dans le paysage du cloud computing. Ses promesses d'orchestration puissante, de scalabilité et de portabilité en ont fait un standard de facto. Cependant, cette adoption s'accompagne souvent d'une complexité non négligeable en termes de maintenance, de mises à jour et de gestion quotidienne.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Le défi des petites structures&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pour une entreprise disposant d'une équipe DevOps dédiée, la complexité de Kubernetes fait partie du quotidien. Les problèmes techniques trouvent rapidement leur solution grâce à l'expertise interne. &lt;br&gt;
Mais qu'en est-il des structures plus modestes ? En l'absence d'équipe interne, le recours à une ESN ou à des freelances devient nécessaire, engendrant des coûts significatifs et une dépendance externe.&lt;/p&gt;

&lt;p&gt;Au fil de mes missions freelance auprès de startups et PME, une question revient systématiquement : ont-elles réellement besoin de toute la puissance (et la complexité) de Kubernetes ?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECS : L'alternative pragmatique&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;C'est dans ce contexte que j'ai récemment guidé un client vers AWS ECS plutôt que vers EKS (la version managée de Kubernetes par AWS). Bien que moins médiatisé que Kubernetes, ECS offre un ensemble de fonctionnalités particulièrement adaptées aux équipes réduites :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simplicité opérationnelle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aucune gestion de version du cluster requise&lt;br&gt;
Déploiement familier, proche de docker-compose&lt;br&gt;
Debug simplifié via l'accès console aux tâches&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intégration native AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Connexion transparente avec AWS Secret Manager et SSM Parameter Store&lt;br&gt;
Configuration simple des Load Balancers et security groups&lt;br&gt;
Gestion des droits intuitive via IAM et les rôles de tâches&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexibilité et coût-efficacité&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Support de Fargate et Fargate Spot (non disponible sur EKS)&lt;br&gt;
Gestion flexible des volumes&lt;br&gt;
Scaling automatique efficient&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Déploiement continu&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Intégration native avec CodePipeline&lt;br&gt;
Support du rolling release et blue-green deployment&lt;br&gt;
Transition douce depuis une infrastructure EC2 classique&lt;/p&gt;

&lt;p&gt;Le cas concret de notre migration&lt;/p&gt;

&lt;p&gt;Dans le cas de notre client, la transition depuis une architecture EC2 traditionnelle vers ECS s'est faite progressivement, en conservant les pipelines existants et en adaptant simplement la phase de déploiement. Les développeurs ont rapidement pris en main le nouveau système, notamment grâce à la similarité avec docker-compose qu'ils utilisaient déjà en développement.&lt;br&gt;
L'équipe technique réduite a particulièrement apprécié l'absence de maintenance du cluster et la simplification des processus de déploiement, leur permettant de se concentrer sur le développement de fonctionnalités plutôt que sur l'infrastructure.&lt;br&gt;
Un choix pragmatique&lt;/p&gt;

&lt;p&gt;Si Kubernetes reste incontournable pour certains cas d'usage complexes, ECS s'impose comme une alternative crédible pour les équipes qui cherchent à moderniser leur infrastructure sans démultiplier la complexité opérationnelle. Il offre un excellent compromis entre fonctionnalités modernes et simplicité d'utilisation, particulièrement dans l'écosystème AWS.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>containers</category>
      <category>kubernetes</category>
      <category>ecs</category>
    </item>
    <item>
      <title>Github ARC Runners sur EKS - Assume roles</title>
      <dc:creator>Thibault CORDIER ☁</dc:creator>
      <pubDate>Thu, 25 Apr 2024 08:45:46 +0000</pubDate>
      <link>https://dev.to/laeline/github-arc-runners-sur-eks-assume-roles-4c94</link>
      <guid>https://dev.to/laeline/github-arc-runners-sur-eks-assume-roles-4c94</guid>
      <description>&lt;p&gt;Récemment, nous avons migré nos runners Github en "self-hosted" sur Kubernetes (EKS) via l'opérateur ARC.&lt;/p&gt;

&lt;p&gt;L'installation est assez aisée (même si la doc est un peu succincte).&lt;/p&gt;

&lt;p&gt;Une fois avoir installé l'opérateur ARC, on installe des CRD AutoScalingRunnerSet avec Helm dont voici un exemple fichier de values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;githubConfigUrl: "https://github.com/&amp;lt;myorganisation&amp;gt;"
githubConfigSecret: "pre-defined-secret"
maxRunners: 100
runnerScaleSetName: "arc-runner-set-arm"

template:
  metadata:
    annotations:
      karpenter.sh/do-not-disrupt: "true"
  spec:
    nodeSelector:
      kubernetes.io/arch: "arm64"
    serviceAccountName: arc-runner-base-role
    tolerations:
    - key: github/arm
      value: "true"
      effect: NoSchedule
    initContainers:
    - name: init-dind-externals
      image: ghcr.io/actions/actions-runner:latest
      command: ["cp", "-r", "-v", "/home/runner/externals/.", "/home/runner/tmpDir/"]
      volumeMounts:
        - name: dind-externals
          mountPath: /home/runner/tmpDir
    containers:
    - name: runner
      image: ghcr.io/actions/actions-runner:latest
      command: ["/home/runner/run.sh"]
      env:
        - name: DOCKER_HOST
          value: unix:///run/docker/docker.sock
      resources:
        requests:
          cpu: 1
      volumeMounts:
        - name: work
          mountPath: /home/runner/_work
        - name: dind-sock
          mountPath: /run/docker
          readOnly: true

    - name: dind
      image: public.ecr.aws/docker/library/docker:dind
      args:
        - dockerd
        - --host=unix:///run/docker/docker.sock
        - --group=$(DOCKER_GROUP_GID)
      env:
        - name: DOCKER_GROUP_GID
          value: "123"
      securityContext:
        privileged: true
      volumeMounts:
        - name: work
          mountPath: /home/runner/_work
        - name: dind-sock
          mountPath: /run/docker
        - name: dind-externals
          mountPath: /home/runner/externals
    volumes:
    - name: work
      emptyDir: {}
    - name: dind-sock
      emptyDir: {}
    - name: dind-externals
      emptyDir: {}

controllerServiceAccount:
  name: arc-gha-rs-controller
  namespace: arc-systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La partie importante pour les droits va être de renseigner un &lt;code&gt;spec.serviceAccountName&lt;/code&gt; qui sera utilisé par tous les runners qui vont être créés.&lt;/p&gt;

&lt;p&gt;Avec AWS CDK, j'ai auparavant créé un serviceAccount et un rôle associé&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        const arcBaseRole = kubernetesCluster.addServiceAccount('arc-base-role', {
            name: 'arc-runner-base-role',
            namespace: 'arc-systems',
        });
        // Allow to assumeRole in the account starting with arc-runner-*
        arcBaseRole.role.attachInlinePolicy(
            new Policy(this, 'arc-base-role-policy', {
                statements: [
                    new PolicyStatement({
                        actions: ['sts:AssumeRole', 'sts:TagSession'],
                        resources: ['arn:aws:iam::'+ this.account + ':role/arc-runner-*'],
                    }),
                ],
            })
        );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ainsi qu'un rôle à assumer pour ce runner (ici la possibilité de push sur le dépôt ECR.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pusherRole = new Role(this, 'arc-ecr-image-pusher-role', {
    assumedBy: new AccountPrincipal(this.account),
    roleName: 'arc-runner-ecr-image-pusher-role',
});

pusherRoleI.attachInlinePolicy(
    new Policy(this, 'arc-ecr-image-pusher-policy-base', {
        statements: [
            new PolicyStatement({
                actions: [
                    'ecr:GetAuthorizationToken',
                    'ecr:BatchCheckLayerAvailability',
                    'ecr:GetDownloadUrlForLayer',
                    'ecr:BatchGetImage',
                    'ecr:InitiateLayerUpload',
                    'ecr:UploadLayerPart',
                    'ecr:CompleteLayerUpload',
                    'ecr:PutImage',
                ],
                resources: ['*'],
            })
        ]
        })
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensuite dans mon job github, plus qu'à préciser le rôle à assumer et voila !&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eu-central-1&lt;/span&gt;
    &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::${{ secrets.ECR_AWS_ACCOUNT_ID }}:role/arc-runner-ecr-image-pusher-role&lt;/span&gt;
    &lt;span class="na"&gt;role-session-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.workflow }}_${{ github.run_number }}_${{ github.job }}&lt;/span&gt;
    &lt;span class="na"&gt;role-skip-session-tagging&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;p&gt;Pourquoi j'en ai fait un post ?&lt;br&gt;
Parce que ça n'a pas marché tout de suite, notamment à cause du paramètre : &lt;code&gt;role-skip-session-tagging: true&lt;/code&gt; qu'il faut rajouter sous peine de voir le runner répéter le même message en boucle :)&lt;/p&gt;

</description>
      <category>aws</category>
      <category>eks</category>
      <category>github</category>
    </item>
  </channel>
</rss>
