GitHub Actions self-hosted runners : déploiement sécurisé sur AWS
← Retour au blogGitHub Actions

GitHub Actions self-hosted runners : déploiement sécurisé sur AWS

2 juillet 20259 min de lectureGitHub ActionsSelf-hosted RunnersAWS

Les runners GitHub hébergés ont leurs limites : coûts, accès réseau privé, performances. Les self-hosted runners sur EC2 résolvent ces problèmes — à condition de les sécuriser correctement.

Pourquoi passer aux self-hosted runners ?

Les runners GitHub hébergés (ubuntu-latest, windows-latest) sont pratiques mais limités : pas d'accès aux ressources réseau privées (RDS, ElastiCache, registres privés), performances plafonnées à 2 vCPU / 7 GB RAM, et coûts qui s'envolent dès que les builds deviennent fréquents ou longs.

Les self-hosted runners permettent d'utiliser n'importe quelle instance EC2 — plus de RAM, GPU, accès VPC, cache local Docker ou Maven. Mais ils introduisent des risques de sécurité qu'il faut maîtriser.

Architecture recommandée sur AWS

La configuration de référence s'articule ainsi :

  • Auto Scaling Group d'instances EC2 dans un subnet privé (pas d'IP publique)
  • NAT Gateway pour les appels sortants (GitHub API, téléchargement des actions)
  • IAM Instance Profile avec les permissions minimales nécessaires aux builds
  • Scale-to-zero : 0 instances au repos, scale-out déclenché par un webhook GitHub via Lambda
  • Éphémère obligatoire : chaque job tourne sur une instance fraîche (--ephemeral), supprimée après exécution

Déploiement avec le runner officiel

#!/bin/bash
# User data EC2 - installation du runner GitHub Actions

RUNNER_VERSION="2.319.1"
GITHUB_ORG="Move2Cloud-FR"
GITHUB_REPO="m2c-website"

# Récupérer le token d'enregistrement via SSM Parameter Store
REG_TOKEN=$(aws ssm get-parameter   --name "/github/runner/registration-token"   --with-decryption   --query Parameter.Value   --output text)

cd /home/ec2-user
curl -sL https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz | tar xz

./config.sh   --url "https://github.com/${GITHUB_ORG}/${GITHUB_REPO}"   --token "${REG_TOKEN}"   --name "ec2-runner-$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"   --labels "self-hosted,linux,x64,aws"   --ephemeral   --unattended

./run.sh

Sécurisation : les règles non négociables

1. Toujours utiliser le mode éphémère

Sans --ephemeral, un job malveillant peut laisser des fichiers, des variables d'environnement ou des credentials dans l'environnement du runner pour le job suivant. En mode éphémère, le runner se désenregistre et l'instance est terminée après chaque job.

2. N'utiliser les self-hosted runners que sur des dépôts privés

Sur un dépôt public, n'importe qui peut soumettre une PR qui déclenche un workflow sur votre runner. Cela peut exposer vos secrets IAM ou votre réseau interne. GitHub le déconseille explicitement.

3. Limiter les permissions IAM au minimum

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetLoginPassword",
        "ecr:BatchGetImage",
        "ecr:PutImage"
      ],
      "Resource": "arn:aws:ecr:eu-west-1:ACCOUNT_ID:repository/my-app"
    },
    {
      "Effect": "Allow",
      "Action": "ecr:GetAuthorizationToken",
      "Resource": "*"
    }
  ]
}

4. Sécurité réseau

  • Security Group : aucune règle entrante — le runner initie toujours la connexion vers GitHub
  • Sortant : HTTPS (443) vers github.com, *.actions.githubusercontent.com, ECR endpoint
  • VPC Endpoint ECR pour éviter le passage par Internet pour les push/pull d'images

5. Rotation automatique des tokens

Ne stockez jamais le token de registration GitHub dans le code ou les variables d'environnement non chiffrées. Utilisez AWS Secrets Manager ou SSM Parameter Store (SecureString) avec une Lambda qui génère un nouveau token via l'API GitHub à chaque démarrage d'instance.

Scale-to-zero avec Lambda + webhook

La solution la plus économique : 0 runner au repos, scale-out automatique à la réception d'un webhook workflow_job GitHub :

# GitHub webhook → API Gateway → Lambda → EC2 Auto Scaling
import boto3, json

def handler(event, context):
    body = json.loads(event['body'])
    if body.get('action') == 'queued':
        ec2 = boto3.client('autoscaling')
        ec2.set_desired_capacity(
            AutoScalingGroupName='github-runners-asg',
            DesiredCapacity=1
        )
    return {'statusCode': 200}

Alternative managée : GitHub Actions Runner Controller (ARC)

Pour les équipes sur Kubernetes, Actions Runner Controller (ARC) déploie des runners comme des pods Kubernetes éphémères. Il s'intègre avec KEDA pour le scale-to-zero et gère automatiquement l'enregistrement/désenregistrement. Avec EKS + Spot nodes, c'est la solution la plus économique pour les charges variables.

Conclusion

Les self-hosted runners sur AWS permettent de combiner la flexibilité de GitHub Actions avec l'accès aux ressources privées et les performances EC2. La clé est la rigueur : éphémère obligatoire, IAM minimal, dépôts privés uniquement, scale-to-zero pour les coûts. Move2Cloud déploie et maintient des architectures de runners CI/CD pour ses clients, intégrées aux pipelines de déploiement existants.

← Retour au blog