Introduction
En 2026, les coûts AWS représentent souvent 30-50% des dépassements budgétaires pour les entreprises cloud-native. Une gestion avancée n'est plus optionnelle : elle exige une automation via APIs comme Cost Explorer, Budgets et Cost Anomaly Detection. Ce tutoriel expert vous guide pas à pas pour implémenter une stack complète : requêtes analytiques sur les dépenses par service/Région, budgets avec alertes SNS, activation de tags allocation pour granularité fine, et une Lambda serverless pour détection proactive d'anomalies.
Imaginez comme un tableau de bord financier : Cost Explorer est votre requête SQL sur les métriques coûts ; les budgets, vos seuils d'alerte ; les tags, vos dimensions analytiques. Avec Boto3, vous queryez des milliards de points de données en secondes. Résultat : réduction de 20-40% des coûts via insights actionnables.
Ce guide progresse des fondations IAM aux déploiements SAM, avec 100% de code fonctionnel. Prêt à transformer vos factures AWS en opportunités d'économies ? (142 mots)
Prérequis
- Compte AWS avec permissions administrateur (ou rôle dédié).
- AWS CLI v2 installé (≥ 2.15).
- Python 3.12+ avec
pip install boto3 motplotlib pandas. - AWS SAM CLI pour déploiement Lambda (optionnel mais recommandé).
- Connaissances expertes en IAM, Boto3 et serverless.
- Région AWS par défaut :
us-east-1(modifiable dans codes).
Politique IAM pour Cost Explorer et Budgets
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ce:*",
"budgets:ViewBudget",
"budgets:Describe*",
"budgets:CreateBudget",
"budgets:UpdateBudget",
"budgets:CreateNotification",
"budgets:UpdateNotification",
"sns:Publish",
"tagpolicies:TagResources",
"cur:DescribeReportDefinitions",
"cur:PutReportDefinition"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:CreatePolicy",
"iam:AttachRolePolicy",
"lambda:*",
"cloudwatch:PutMetricAlarm",
"cloudwatch:GetMetricData"
],
"Resource": "*"
}
]
}Cette politique JSON complète autorise l'accès full à Cost Explorer (ce:*), Budgets et CUR. Attachez-la à un rôle IAM via Console ou CLI (aws iam create-policy ...). Piège : sans sns:Publish, les notifications budgets échouent ; testez toujours avec aws sts get-caller-identity.
Attachement IAM et configuration CLI
Créez un rôle IAM, attachez la policy ci-dessus, et assumez-le. Configurez AWS CLI pour authentification. Cela pose les bases sécurisées pour toutes les APIs suivantes, évitant les erreurs 403 Forbidden courantes en prod.
Configuration AWS CLI et test Cost Explorer
#!/bin/bash
# Configurez vos credentials (utilisez MFA si possible)
aws configure set aws_access_key_id YOUR_ACCESS_KEY
aws configure set aws_secret_access_key YOUR_SECRET_KEY
aws configure set default.region us-east-1
# Test : Listez les budgets existants
aws budgets describe-budgets --account-id $(aws sts get-caller-identity --query Account --output text) --max-results 10
# Test Cost Explorer : Get coût total du mois dernier (format JSON)
aws ce get-cost-and-usage \
--time-period Start=2026-01-01,End=2026-01-31 \
--granularity MONTHLY \
--metrics "BlendedCost" \
--group-by Type=DIMENSION,Key=SERVICECe script bash configure CLI et teste les accès. La requête Cost Explorer agrège les coûts par service sur janvier 2026 (adaptez dates). Piège : Time-period doit être < 3 ans ; utilisez --query pour filtrer JSON en CLI.
Script Boto3 : Analyse coûts par service
import boto3
import pandas as pd
from datetime import datetime, timedelta
ce = boto3.client('ce')
end = datetime.now()
start = end - timedelta(days=30)
response = ce.get_cost_and_usage(
TimePeriod={'Start': start.strftime('%Y-%m-%d'), 'End': end.strftime('%Y-%m-%d')},
Granularity='DAILY',
Metrics=['BlendedCost'],
GroupBy=[{'Type': 'DIMENSION', 'Key': 'SERVICE'}]
)
df = pd.json_normalize(response['ResultsByTime'])
print(df[['TimePeriod.Start', 'Total.BlendedCost.Amount', 'GroupBy']].head(10))
# Sauvegarde CSV pour Excel/Tableau
df.to_csv('costs_by_service.csv', index=False)
print('Analyse exportée dans costs_by_service.csv')Ce script Boto3 query 30 derniers jours, groupe par SERVICE et exporte Pandas CSV. Analogy : comme un GROUP BY SQL sur vos factures. Piège : Limite 1000 groupes ; paginez avec NextPageToken pour gros comptes. Exécutez python analyze_costs.py.
Interprétation des insights coûts
Exécutez le script : identifiez les top 5 services (ex: EC2 >40%). Utilisez Pandas pour pivots avancés (coûts par Région/Tag). Cela révèle les fuites : instances idle, data transfer excessif. Prochaine étape : budgets automatisés.
Création budget avec notifications SNS
import boto3
from datetime import datetime, timedelta
budgets = boto3.client('budgets')
account_id = boto3.client('sts').get_caller_identity()['Account']
sns_topic_arn = 'arn:aws:sns:us-east-1:ACCOUNT:cost-alerts' # Créez via Console
budgets.create_budget(
AccountId=account_id,
Budget={'BudgetName': 'Monthly-Total-5000',
'BudgetLimit': {'Amount': '5000', 'Unit': 'USD'},
'TimeUnit': 'MONTHLY',
'TimePeriod': {'Start': datetime.now().strftime('%Y-%m-01')},
'CostTypes': {'IncludeTax': True, 'IncludeSubscription': True,
'IncludeCredit': False, 'IncludeUpfront': True,
'IncludeRecurring': True, 'IncludeRefund': False}},
NotificationsWithSubscribers=[
{'Notification': {'NotificationType': 'FORECASTED', 'ComparisonOperator': 'GREATER_THAN',
'Threshold': 80.0, 'ThresholdType': 'PERCENTAGE'},
'Subscribers': [{'SubscriptionType': 'SNS', 'Address': sns_topic_arn}]},
{'Notification': {'NotificationType': 'ACTUAL', 'ComparisonOperator': 'GREATER_THAN',
'Threshold': 100.0, 'ThresholdType': 'PERCENTAGE'},
'Subscribers': [{'SubscriptionType': 'SNS', 'Address': sns_topic_arn}]}]
)
print('Budget créé avec alertes à 80% forecast / 100% actual.')Crée un budget mensuel 5000 USD avec alertes SNS à 80% prévisionnel / 100% réel. Personnalisez Amount/ARN. Piège : TimePeriod Start au 1er du mois ; listez budgets via aws budgets describe-budgets pour vérifier.
Activation Cost Allocation Tags
import boto3
tag_policies = boto3.client('resourcegroupstaggingapi')
services = ['AmazonEC2', 'AmazonS3', 'AWSLambda'] # Ajoutez services
tags_keys = ['Environment', 'Project', 'Owner']
for service in services:
tag_policies.activate_tag_policy(
ServiceId=service,
TagFilter={'Key': key} for key in tags_keys # Note: Boucle implicite
)
print('Tags activés pour granularité coûts :', tags_keys)
# Vérif : Listez tags activés
response = tag_policies.get_tag_policies()
print('Tags actifs:', [p['Targets'][0]['KeyFilters'] for p in response['TagPolicies']])Active les tags 'Environment/Project/Owner' pour EC2/S3/Lambda, permettant breakdown coûts par tag dans Cost Explorer (24h délai). Piège : Tags doivent exister sur ressources ; utilisez aws resourcegroupstaggingapi get-tag-policies pour monitorer.
Déploiement Lambda pour anomalies
Maintenant, automatisez : une Lambda query quotidienne coûts, détecte +20% vs moyenne, alerte via SNS/CloudWatch. Utilisez SAM pour déploiement zero-config.
Handler Lambda détection anomalies
import boto3
import json
from datetime import datetime, timedelta
def lambda_handler(event, context):
ce = boto3.client('ce')
sns = boto3.client('sns')
end = datetime.now()
start = end - timedelta(days=7)
avg_start = end - timedelta(days=14)
# Coût récent
recent = ce.get_cost_and_usage(
TimePeriod={'Start': start.strftime('%Y-%m-%d'), 'End': end.strftime('%Y-%m-%d')},
Granularity='DAILY', Metrics=['BlendedCost']
)['ResultsByTime'][-1]['Total']['BlendedCost']['Amount']
# Moyenne historique
hist = ce.get_cost_and_usage(
TimePeriod={'Start': avg_start.strftime('%Y-%m-%d'), 'End': start.strftime('%Y-%m-%d')},
Granularity='DAILY', Metrics=['BlendedCost']
)
avg = sum([d['Total']['BlendedCost']['Amount'] for d in hist['ResultsByTime']]) / 7
if float(recent) > float(avg) * 1.2:
sns.publish(TopicArn='arn:aws:sns:us-east-1:ACCOUNT:cost-anomalies',
Message=f"Anomalie détectée: {recent} USD vs avg {avg} USD (+{((float(recent)/avg-1)*100):.1f}%)" )
return {'statusCode': 200, 'body': 'Alerte envoyée'}
return {'statusCode': 200, 'body': 'Normal'}
# Test local: lambda_handler({}, None)Handler compare 7j récents vs moyenne 7j historiques ; alerte si +20%. Trigger via EventBridge quotidien. Piège : Gérez exceptions Boto3 ; attachez rôle avec policy ci-dessus. Testez localement.
Template SAM pour déployer la Lambda
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
AnomalyDetectorFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Handler: lambda_anomaly_detector.lambda_handler
Runtime: python3.12
Policies:
- Statement:
- Effect: Allow
Action:
- ce:GetCostAndUsage
- sns:Publish
Resource: '*'
Events:
DailyTrigger:
Type: Schedule
Properties:
Schedule: rate(1 day)
Outputs:
FunctionArn:
Value: !GetAtt AnomalyDetectorFunction.ArnSAM YAML déploie la Lambda avec rôle inline, trigger quotidien. sam build && sam deploy --guided. Piège : Remplacez ARN SNS ; validez avec sam validate avant prod.
Bonnes pratiques
- Paginer les APIs : Cost Explorer >500 résultats ? Utilisez NextPageToken en boucle Boto3.
- Tags obligatoires : Enforcez via Service Control Policies (SCP) pour 100% coverage.
- RI/SP achat auto : Intégrez Compute Optimizer API dans Lambda pour recommandations.
- CUR + Athena : Exportez CUR S3, queryez SQL pour ML prédictif.
- Multi-comptes : Utilisez AWS Organizations + Control Tower pour budgets centralisés.
Erreurs courantes à éviter
- Oubli pagination : Queries tronquées masquent 20% coûts ; toujours bouclez Token.
- Tags non activés : 24-48h délai ; testez avec
ce get-dimension-values. - Budgets sans forecast : Ajoutez 'FORECASTED' pour proactivité.
- Lambda timeout : Augmentez à 15min pour gros datasets ; monitorez via X-Ray.
Pour aller plus loin
- Docs officielles : AWS Cost Explorer API.
- Outils avancés : AWS Cost Anomaly Detection + QuickSight dashboards.
- Formations expertes : Découvrez nos formations Learni sur AWS FinOps.
- Repo GitHub exemple : fork pour customiser.