Arrête de payer tes environnements de test la nuit

date: Dec 15 2024 4 min de lecture

Le rightsizing une fois ne suffit pas. Planifie les types d'instances par heure et économise 30-60% sur les workloads non-prod.

.finops.aws.cloud.cost-optimization

Ton environnement de staging tourne sur m5.xlarge. 24 heures sur 24. 7 jours sur 7. Personne ne l’utilise entre 20h et 8h. Personne ne l’utilise le weekend

Tu payes pour la capacité max 168 heures par semaine alors que tu en as besoin peut-être 50

Le rightsizing c’est pas un truc qu’on fait une fois

La plupart des équipes rightsizent une fois. Elles regardent l’utilisation CPU et mémoire, choisissent une instance qui colle, et passent à autre chose. L’instance reste fixe pour toujours

Mais les patterns d’usage changent au cours de la journée. Un environnement de test qui a besoin de 4 vCPUs pendant les heures de bureau en a besoin d’1 la nuit. Un cluster analytics qui traite des données la journée reste inactif jusqu’au matin

Le rightsizing statique ignore le temps. Tu optimises pour le pic et tu surpayes tout le reste

Planifie tes types d’instances

Au lieu d’une seule taille d’instance, définis-en deux ou trois selon quand les gens bossent vraiment:

HoraireInstancePourquoi
8h-20h semainem5.xlargeL’équipe dev est active, la CI tourne
20h-8h semainem5.mediumPeut-être une personne, charge minimale
Weekendm5.small ou stoppéePersonne ne bosse

Une fonction Lambda tourne à 8h, passe l’instance en xlarge. Une autre tourne à 20h, la descend en medium. Une troisième la stoppe vendredi soir et la redémarre lundi matin

L’automatisation

AWS Lambda avec EventBridge:

import boto3

ec2 = boto3.client('ec2')

def upsize(event, context):
    ec2.stop_instances(InstanceIds=['i-1234567890abcdef0'])
    waiter = ec2.get_waiter('instance_stopped')
    waiter.wait(InstanceIds=['i-1234567890abcdef0'])

    ec2.modify_instance_attribute(
        InstanceId='i-1234567890abcdef0',
        InstanceType={'Value': 'm5.xlarge'}
    )
    ec2.start_instances(InstanceIds=['i-1234567890abcdef0'])

def downsize(event, context):
    ec2.stop_instances(InstanceIds=['i-1234567890abcdef0'])
    waiter = ec2.get_waiter('instance_stopped')
    waiter.wait(InstanceIds=['i-1234567890abcdef0'])

    ec2.modify_instance_attribute(
        InstanceId='i-1234567890abcdef0',
        InstanceType={'Value': 'm5.medium'}
    )
    ec2.start_instances(InstanceIds=['i-1234567890abcdef0'])

Les règles EventBridge:

# Upsize à 8h en semaine
ScheduleExpression: "cron(0 8 ? * MON-FRI *)"

# Downsize à 20h en semaine
ScheduleExpression: "cron(0 20 ? * MON-FRI *)"

Pour GCP, utilise Cloud Scheduler avec Cloud Functions. Pour Azure, les runbooks Azure Automation

Les chiffres

m5.xlarge on-demand: ~0.192$/heure m5.medium on-demand: ~0.048$/heure

Faire tourner xlarge 24/7 pendant un mois: 140$

Avec la planification:

  • 12h/jour en semaine sur xlarge: 60h × 0.192$ = 11.52$/semaine
  • 12h/jour en semaine sur medium: 60h × 0.048$ = 2.88$/semaine
  • Weekends stoppés: 0$

Coût mensuel: ~58$

Ça fait 58% d’économies sur une seule instance. Multiplie ça par un environnement de test avec 10 instances et tu économises 800$/mois

Où ça marche

Environnements de test et staging: Personne ne lance de tests à 3h du mat. Réduis ou stoppe carrément

Analytics et reporting: Si tes dashboards se mettent à jour pendant les heures de bureau, le cluster peut rétrécir la nuit

Environnements de training ML: Les jobs batch tournent à des heures planifiées. Pas besoin d’instances GPU qui font rien

Bases de données dev: Les devs bossent de 9h à 17h. La base n’a pas besoin de la capacité prod à minuit

Où ça marche pas

La production. Évidemment. Si tu as des utilisateurs partout dans le monde, il n’y a pas d‘“heures creuses”

Tout ce qui a des connexions persistantes qui supportent pas les redémarrages d’instances

Les bases de données avec des temps de démarrage longs où la fenêtre de 2 minutes de restart pose problème

Au-delà des types d’instances

Le même principe s’applique à:

Auto Scaling groups: Change la capacité min/max par schedule. 3 instances la journée, 1 la nuit

Instances RDS: Planifie les changements de classe d’instance. db.r5.large pendant les heures, db.r5.medium la nuit

Node groups EKS: Scale le nombre de nodes selon l’heure. Ou utilise Karpenter avec des configs de provisioner basées sur le temps

Requests/limits Kubernetes: Ajuste les min replicas du HPA par schedule

Commence simple

Choisis un environnement non-prod. Ajoute deux fonctions Lambda. Fais tourner pendant un mois

Check ton cost explorer. Tu verras la baisse immédiatement

Ensuite étends aux autres environnements. Ajoute les arrêts weekend. Ajoute les schedules pour les jours fériés

L’objectif c’est pas la perfection. C’est d’arrêter le gaspillage évident de payer pour des ressources que personne n’utilise

Vous avez aimé cet article ? Partagez-le !

Sofiane Djerbi
Sofiane Djerbi

Architecte Cloud & Kubernetes, Expert FinOps.

Commentaires