Vous pouvez définir des alertes de facturation sur CloudWatch, mais en tant que personne très inquiète, j'aimerais vérifier le montant de la facturation du début du mois à la veille par e-mail tous les jours. Il y avait de nombreuses façons de notifier les canaux Slack à l'aide d'AWS Lambda et des webhooks, mais il n'y avait pas beaucoup de façons de notifier par e-mail, donc je les ai résumées.
En particulier, les termes qui apparaissent dans Amazon SNS et leurs relations étaient compliqués, je vais donc les résumer très grossièrement.
** ARN **: un nom qui identifie de manière unique les ressources AWS.
** Sujet **: Possibilité de regrouper plusieurs points de terminaison (ici les adresses e-mail).
** Endpoint **: destination de livraison. Cette fois, ce sera votre adresse e-mail.
** Abonnement **: associer des sujets à des points de terminaison
Pour une meilleure compréhension, la section terminologie de l'article suivant a été très utile, il est donc recommandé de la lire attentivement à l'avance.
Connaissances de base pour l'envoi de notifications push sur Amazon SNS | UNITRUST
Si vous n'avez pas activé Cost Explorer, activez-le depuis Mon tableau de bord de facturation (https://console.aws.amazon.com/billing/home#/costexplorer).
Accédez à l'écran de service d'Amazon SNS.
Dans le menu "Sujet", appuyez sur "Créer un sujet".
Entrez "Nom" et "Nom d'affichage" et appuyez sur "Créer un sujet".
Créez un abonnement (+ point de terminaison).
Cliquez sur "Créer un abonnement".
Entrez les éléments suivants et appuyez sur "Créer un abonnement".
nom de l'article | Valeur d'entrée / valeur de sélection |
---|---|
Sujet ARN | ARN du sujet que vous avez noté |
protocole | |
point final | Adresse e-mail reçue |
Un e-mail de confirmation sera envoyé à l'adresse e-mail spécifiée pour le point de terminaison avec le sujet «Notification AWS - Confirmation d'abonnement», alors appuyez sur «Confirmer l'abonnement».
Le statut de l'abonnement associé au sujet sera "Confirmé".
Vous avez créé un point de terminaison d'abonnement à une rubrique.
Lorsque vous envoyez un message à l'ARN d'une rubrique, le message est remis au point de terminaison (adresse e-mail) associé à cette rubrique. Ensuite, créez une fonction Lambda qui générera un message à émettre vers l'ARN du sujet. Tout d'abord, appuyez sur «Créer une fonction» dans le tableau de bord AWS Lambda.
Confirmez que l'option est "Créer à partir de zéro", entrez ce qui suit dans "Informations de base" et appuyez sur "Créer une fonction".
nom de l'article | Valeur d'entrée / valeur de sélection |
---|---|
Nom de la fonction | sendCost (avec n'importe quel nom que vous aimez) |
Durée | Python 3.7 |
Nom de rôle | SNSServiceRoleForLambda (avec n'importe quel nom que vous aimez) |
Modèle de politique | Politique de publication Amazon SNS |
Ensuite, nous écrirons le code pour acquérir les informations de facturation, mais nous allons d'abord écrire le processus pour émettre un message de test pour confirmer les paramètres jusqu'à présent. Entrez le code suivant dans le champ "Code de fonction" en bas après avoir créé la fonction.
TopicArn
, définissez ** ARN ** que vous avez noté lors de la création du sujet SNS.lambda_function.py
import boto3
def lambda_handler(event, context):
sns = boto3.client('sns')
subject = 'L'objet de l'e-mail de test de Lambda.'
message = 'Il s'agit du corps de l'e-mail de test de Lambda.'
response = sns.publish(
TopicArn = 'arn:aws:sns:*:*:*',
Subject = subject,
Message = message
)
return response
Et, en réalité, il sera exécuté périodiquement avec un déclencheur, mais je vais essayer de l'envoyer manuellement.
Après avoir appuyé sur "Enregistrer" en haut à droite de l'écran, appuyez sur "Test", entrez un nom approprié dans "Nom de l'événement", et appuyez sur "Créer". D'autres peuvent être laissés à leurs valeurs par défaut.
Lorsque vous revenez à l'écran d'origine et cliquez à nouveau sur "Test" en haut à droite, la fonction sera exécutée et le courrier devrait être arrivé à l'adresse électronique de réception spécifiée.
Si vous ne le recevez pas, vérifiez si un message d'erreur s'affiche sur la console (Résultats de l'exécution) en bas du champ de saisie du code et si l'ARN saisi est correct.
Enfin, j'écrirai le code pour obtenir le montant de facturation de Cost Explorer et le notifierai sur Amazon SNS.
Pour TopicArn
, définissez l'ARN qui a été réservé lors de la création de la rubrique SNS comme auparavant.
** * Comme cela sera décrit plus loin, une erreur se produira même si vous testez sans effectuer de réglages supplémentaires! ** **
lambda_function.py
import boto3
from datetime import datetime, timedelta, date
def lambda_handler(event, context):
ce = boto3.client('ce')
sns = boto3.client('sns')
#Obtenez la facture totale pour ce mois
total_billing = get_total_billing(ce)
#Obtenez le montant total de la facturation pour ce mois (pour chaque service)
service_billings = get_service_billings(ce)
#Générer des messages à publier sur des rubriques Amazon SNS
(subject, message) = get_message(total_billing, service_billings)
response = sns.publish(
TopicArn = 'arn:aws:sns:*:*:*',
Subject = subject,
Message = message
)
return response
def get_total_billing(ce):
(start_date, end_date) = get_total_cost_date_range()
response = ce.get_cost_and_usage(
TimePeriod={
'Start': start_date,
'End': end_date
},
Granularity='MONTHLY',
Metrics=[
'AmortizedCost'
]
)
return {
'start': response['ResultsByTime'][0]['TimePeriod']['Start'],
'end': response['ResultsByTime'][0]['TimePeriod']['End'],
'billing': response['ResultsByTime'][0]['Total']['AmortizedCost']['Amount'],
}
def get_service_billings(ce):
(start_date, end_date) = get_total_cost_date_range()
response = ce.get_cost_and_usage(
TimePeriod={
'Start': start_date,
'End': end_date
},
Granularity='MONTHLY',
Metrics=[
'AmortizedCost'
],
GroupBy=[
{
'Type': 'DIMENSION',
'Key': 'SERVICE'
}
]
)
billings = []
for item in response['ResultsByTime'][0]['Groups']:
billings.append({
'service_name': item['Keys'][0],
'billing': item['Metrics']['AmortizedCost']['Amount']
})
return billings
def get_total_cost_date_range():
start_date = date.today().replace(day=1).isoformat()
end_date = date.today().isoformat()
# get_cost_and_usage()Étant donné que la même date ne peut pas être spécifiée pour le début et la fin de, si aujourd'hui est le 1er, elle sera comprise entre "1er du mois dernier et 1er de ce mois (aujourd'hui)"
if start_date == end_date:
end_of_month = datetime.strptime(start_date, '%Y-%m-%d') + timedelta(days=-1)
begin_of_month = end_of_month.replace(day=1)
return begin_of_month.date().isoformat(), end_date
return start_date, end_date
def get_message(total_billing, service_billings):
start = datetime.strptime(total_billing['start'], '%Y-%m-%d').strftime('%Y/%m/%d')
#La date de fin n'étant pas incluse dans le résultat, elle devrait être la veille à l'écran
end_today = datetime.strptime(total_billing['end'], '%Y-%m-%d')
end_yesterday = (end_today - timedelta(days=1)).strftime('%Y/%m/%d')
total = round(float(total_billing['billing']), 2)
subject = f'{start}~{end_yesterday}Montant facturé:${total:.2f}'
message = []
message.append('[Panne]')
for item in service_billings:
service_name = item['service_name']
billing = round(float(item['billing']), 2)
if billing == 0.0:
#S'il n'y a pas de demande, le détail ne sera pas affiché
continue
message.append(f'・{service_name}: ${billing:.2f}')
return subject, '\n'.join(message)
Je pense que c'est complet, mais ** le rôle attribué à Lamda n'a pas l'autorisation d'accéder à Cost Explorer **, donc l'erreur suivante se produit.
"errorMessage": "An error occurred (AccessDeniedException) when calling the GetCostAndUsage operation: User: arn:aws:sts::251745928455:assumed-role/SNSServiceRoleForLambda/sendCost is not authorized to perform: ce:GetCostAndUsage on resource: arn:aws:ce:us-east-1:251745928455:/GetCostAndUsage"
Par conséquent, sur l'écran de gestion IAM, associez une stratégie pouvant accéder à Cost Explorer au rôle.
Tout d'abord, affichez Liste des stratégies sur l'écran de gestion IAM et appuyez sur «Créer une stratégie».
Entrez les éléments suivants et appuyez sur "Confirmer la politique".
nom de l'article | Valeur d'entrée / valeur de sélection |
---|---|
un service | Cost Explorer Service |
action | Recherchez "Get Cost And Usage" et vérifiez-le |
Sur l'écran de confirmation de la politique, entrez «Nom» et appuyez sur «Créer une politique».
Accédez à l'écran Liste des rôles (https://console.aws.amazon.com/iam/home#/roles) et sélectionnez le rôle que vous avez attribué à Lambda.
Cliquez sur «Joindre la politique».
Dans "Filtre de politique", entrez le nom que vous avez défini lors de la création de la politique et de la recherche ("AmazonCostExplorerGetCostAccess" dans l'exemple de cet article), vérifiez les résultats et appuyez sur "Joindre la politique".
Maintenant que la fonction peut être exécutée normalement, cliquez sur "Test" en haut à droite de l'écran de réglage de la fonction créée.
Si tout est configuré correctement, vous devriez recevoir un e-mail comme celui ci-dessous.
Enfin, définissez un déclencheur pour vous avertir par e-mail à une heure fixe chaque jour. Appuyez sur "Add Trigger" sur le côté gauche de l'écran de réglage des fonctions.
Réglez comme suit et appuyez sur "Ajouter".
nom de l'article | Valeur d'entrée / valeur de sélection |
---|---|
Sélectionnez un déclencheur | CloudWatch Events/EventBridge |
règle | 新規règleの作成 |
Nom de la règle | sendDailyCost (de manière appropriée) |
Type de règle | Formule de planification |
Formule de planification | cron(0 14 ? * * *) |
Activer le déclencheur | Vérifier |
Cette fois, je l'ai mis à 23h00. En guise de mise en garde, puisque l'heure est définie en UTC, définissez l'heure ** qui est obtenue en soustrayant 9 heures de ** JST (heure standard japonaise) **.
Après cela, veuillez vous assurer que vous recevez l'e-mail à l'heure spécifiée chaque jour.
Vous pouvez désormais dormir l'esprit tranquille tous les jours!
Recommended Posts