Sie können Abrechnungsbenachrichtigungen in CloudWatch festlegen, aber als sehr besorgte Person möchte ich den Abrechnungsbetrag von Anfang des Monats bis zum Vortag jeden Tag per E-Mail überprüfen. Es gab viele Möglichkeiten, Slack-Kanäle mit AWS Lambda und Webhooks zu benachrichtigen, aber es gab nicht viele Möglichkeiten, per E-Mail zu benachrichtigen, daher habe ich sie zusammengefasst.
Insbesondere die Begriffe, die in Amazon SNS vorkommen, und ihre Beziehungen waren kompliziert, daher werde ich sie sehr grob zusammenfassen.
** ARN **: Ein Name, der AWS-Ressourcen eindeutig identifiziert.
** Thema **: Möglichkeit, mehrere Endpunkte zu gruppieren (hier E-Mail-Adressen).
** Endpunkt **: Lieferziel. Diesmal ist es Ihre E-Mail-Adresse.
** Abonnement **: Themen mit Endpunkten verknüpfen
Für ein tieferes Verständnis war der Terminologieabschnitt des folgenden Artikels sehr hilfreich. Es wird daher empfohlen, ihn im Voraus sorgfältig zu lesen.
Grundkenntnisse zum Senden von Push-Benachrichtigungen unter Amazon SNS | UNITRUST
Wenn Sie den Kosten-Explorer nicht aktiviert haben, aktivieren Sie ihn über das Abrechnungs-Dashboard (https://console.aws.amazon.com/billing/home#/costexplorer).
Wechseln Sie zum Servicebildschirm von Amazon SNS.
Drücken Sie im Menü "Thema" auf "Thema erstellen".
Geben Sie "Name" und "Anzeigename" ein und klicken Sie auf "Thema erstellen".
Erstellen Sie ein Abonnement (+ Endpunkt).
Klicken Sie auf "Abonnement erstellen".
Geben Sie die folgenden Elemente ein und klicken Sie auf "Abonnement erstellen".
Artikelname | Eingabewert / Auswahlwert |
---|---|
Thema ARN | ARN des Themas, das Sie aufgeschrieben haben |
Protokoll | |
Endpunkt | E-Mail-Adresse erhalten |
Eine Bestätigungs-E-Mail wird an die für den Endpunkt angegebene E-Mail-Adresse mit dem Betreff "AWS-Benachrichtigung - Abonnementbestätigung" gesendet. Drücken Sie daher auf "Abonnement bestätigen".
Der Status des mit dem Thema verknüpften Abonnements lautet "Bestätigt".
Sie haben einen Themenabonnement-Endpunkt erstellt.
Wenn Sie eine Nachricht an die ARN eines Themas senden, wird die Nachricht an den Endpunkt (E-Mail-Adresse) gesendet, der diesem Thema zugeordnet ist. Erstellen Sie als Nächstes eine Lambda-Funktion, die eine Nachricht generiert, die an die ARN des Themas gesendet wird. Drücken Sie zunächst im AWS Lambda-Dashboard auf "Funktion erstellen".
Vergewissern Sie sich, dass die Option "Von Grund auf neu erstellen" lautet, geben Sie unter "Grundlegende Informationen" Folgendes ein und klicken Sie auf "Funktion erstellen".
Artikelname | Eingabewert / Auswahlwert |
---|---|
Funktionsname | sendCost (mit einem beliebigen Namen) |
Laufzeit | Python 3.7 |
Rollenname | SNSServiceRoleForLambda (mit einem beliebigen Namen) |
Richtlinienvorlage | Amazon SNS-Veröffentlichungsrichtlinie |
Als nächstes schreibe ich den Code, um die Rechnungsinformationen zu erhalten, aber zuerst schreibe ich den Prozess, um eine Testnachricht auszugeben, um die bisherigen Einstellungen zu bestätigen. Geben Sie nach dem Erstellen der Funktion den folgenden Code in das Feld "Funktionscode" unten ein.
lambda_function.py
import boto3
def lambda_handler(event, context):
sns = boto3.client('sns')
subject = 'Der Betreff der Test-E-Mail von Lambda.'
message = 'Dies ist der Hauptteil der Test-E-Mail von Lambda.'
response = sns.publish(
TopicArn = 'arn:aws:sns:*:*:*',
Subject = subject,
Message = message
)
return response
In Wirklichkeit wird es regelmäßig mit einem Auslöser ausgeführt, aber ich werde versuchen, es manuell zu senden.
Nachdem Sie oben rechts auf dem Bildschirm auf "Speichern" geklickt haben, drücken Sie "Test", geben Sie unter "Ereignisname" einen geeigneten Namen ein und drücken Sie auf "Erstellen". Andere können auf ihren Standardwerten belassen werden.
Wenn Sie zum ursprünglichen Bildschirm zurückkehren und oben rechts erneut auf "Test" klicken, wird die Funktion ausgeführt und die E-Mail sollte an der angegebenen empfangenen E-Mail-Adresse angekommen sein.
Wenn Sie es nicht erhalten, überprüfen Sie, ob auf der Konsole (Ausführungsergebnisse) unten im Codeeingabefeld eine Fehlermeldung angezeigt wird und ob die eingegebene ARN korrekt ist.
Schließlich schreibe ich den Code, um den Rechnungsbetrag vom Kosten-Explorer zu erhalten und ihn bei Amazon SNS zu benachrichtigen. Legen Sie für "TopicArn" die ARN fest, die beim Erstellen des SNS-Themas wie zuvor gespeichert wurde.
** * Wie später beschrieben wird, tritt ein Fehler auf, auch wenn Sie ohne zusätzliche Einstellungen testen! ** ** **
lambda_function.py
import boto3
from datetime import datetime, timedelta, date
def lambda_handler(event, context):
ce = boto3.client('ce')
sns = boto3.client('sns')
#Holen Sie sich die Gesamtrechnung für diesen Monat
total_billing = get_total_billing(ce)
#Erhalten Sie den Gesamtabrechnungsbetrag für diesen Monat (für jeden Service)
service_billings = get_service_billings(ce)
#Generieren Sie Nachrichten, die zu Amazon SNS-Themen veröffentlicht werden sollen
(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()Da das gleiche Datum für Anfang und Ende von nicht angegeben werden kann, liegt es heute im Bereich von "1. des letzten Monats bis 1. dieses Monats (heute)".
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')
#Da das Enddatum nicht im Ergebnis enthalten ist, sollte es am Vortag auf dem Display angezeigt werden
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}Rechnungsbetrag:${total:.2f}'
message = []
message.append('[Nervenzusammenbruch]')
for item in service_billings:
service_name = item['service_name']
billing = round(float(item['billing']), 2)
if billing == 0.0:
#Wenn keine Anforderung vorliegt, wird die Aufschlüsselung nicht angezeigt
continue
message.append(f'・{service_name}: ${billing:.2f}')
return subject, '\n'.join(message)
Ich denke, dies ist vollständig, aber ** die Lamda zugewiesene Rolle hat keine Berechtigung zum Zugriff auf den Kosten-Explorer **, sodass der folgende Fehler auftritt.
"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"
Fügen Sie daher auf dem IAM-Verwaltungsbildschirm der Richtlinie eine Richtlinie hinzu, die auf den Kosten-Explorer zugreifen kann.
Zeigen Sie zunächst Richtlinienliste auf dem IAM-Verwaltungsbildschirm an und klicken Sie auf "Richtlinie erstellen".
Geben Sie die folgenden Elemente ein und klicken Sie auf "Richtlinie bestätigen".
Artikelname | Eingabewert / Auswahlwert |
---|---|
Bedienung | Cost Explorer Service |
Aktion | Suchen Sie nach "Kosten und Nutzung abrufen" und überprüfen Sie diese |
Geben Sie auf dem Bildschirm zur Bestätigung der Richtlinie "Name" ein und klicken Sie auf "Richtlinie erstellen".
Wechseln Sie zum Bildschirm Rollenliste (https://console.aws.amazon.com/iam/home#/roles) und wählen Sie die Rolle aus, die Sie Lambda zugewiesen haben.
Klicken Sie auf "Richtlinie anhängen".
Geben Sie unter "Richtlinienfilter" den Namen ein, den Sie beim Erstellen der Richtlinie und bei der Suche festgelegt haben ("AmazonCostExplorerGetCostAccess" im Beispiel dieses Artikels), überprüfen Sie die Treffer und klicken Sie auf "Richtlinie anhängen".
Nachdem die Funktion nun normal ausgeführt werden kann, klicken Sie oben rechts im Einstellungsbildschirm der erstellten Funktion auf "Test".
Wenn alles richtig eingerichtet ist, sollten Sie eine E-Mail wie die folgende erhalten.
Setzen Sie schließlich einen Auslöser, um Sie jeden Tag zu einer festgelegten Zeit per E-Mail zu benachrichtigen. Drücken Sie auf der linken Seite des Funktionseinstellungsbildschirms auf "Trigger hinzufügen".
Stellen Sie wie folgt ein und drücken Sie "Hinzufügen".
Artikelname | Eingabewert / Auswahlwert |
---|---|
Wählen Sie einen Auslöser | CloudWatch Events/EventBridge |
Regel | 新規Regelの作成 |
Regelname | sendDailyCost (entsprechend) |
Regeltyp | Zeitplanformel |
Zeitplanformel | cron(0 14 ? * * *) |
Trigger aktivieren | Überprüfen |
Diesmal habe ich es auf 23:00 eingestellt. Da die Zeit in UTC eingestellt ist, stellen Sie als Einschränkung die Zeit ** ein, die durch Subtrahieren von 9 Stunden von ** JST (japanische Standardzeit) ** erhalten wird.
Stellen Sie danach sicher, dass Sie die E-Mail jeden Tag zur angegebenen Zeit erhalten.
Jetzt können Sie jeden Tag beruhigt schlafen!
Recommended Posts