Beispiele für programmatische Budgetbenachrichtigungen

Wenn Sie kostenbewusst arbeiten und Ihre Umgebung entsprechend Ihrem Budget gestalten müssen, können Sie programmatische Budgetbenachrichtigungen verwenden, um Ihre Budgetmaßnahmen zu automatisieren.

Budgetbenachrichtigungen erfolgen in Form von Cloud Pub/Sub-Benachrichtigungen, um den Budgetstatus unter Verwendung der Skalierbarkeit, Flexibilität und Zuverlässigkeit der unternehmensbezogenen nachrichtenorientierten Middleware für die Cloud in Echtzeit wiederzugeben.

Auf dieser Seite finden Sie Beispiele und detaillierte Anleitungen, wie Sie mithilfe von Cloud-Funktionen zur Automatisierung der Kostenverwaltung Budgetbenachrichtigungen nutzen können.

Budgetbenachrichtigungen einrichten

Der erste Schritt besteht darin, für das Budget Cloud Pub/Sub-Benachrichtigungen zu aktivieren. Dieser Schritt wird unter Benachrichtigungen verwalten beschrieben.

Beachten Sie Folgendes, nachdem Sie die Budgetbenachrichtigungen aktiviert haben:

  • Pub/Sub-Thema: Dies ist der konfigurierte Benachrichtigungsendpunkt für das Budget.
  • Budget-ID: Dies ist eine eindeutige ID für das Budget, die Bestandteil aller Benachrichtigungen ist. Sie finden die Budget-ID im Budget unter Benachrichtigungen verwalten. Die ID wird angezeigt, wenn Sie Pub/Sub-Thema mit diesem Budget verbinden auswählen.

Abrechnungsbenachrichtigungen in der GCP Console verwalten

Benachrichtigungen überwachen

Der nächste Schritt besteht darin, Ihre Benachrichtigungen zu überwachen. Abonnieren Sie hierfür das Pub/Sub-Thema. Wenn Sie kein Abo haben, werden veröffentlichte Nachrichten durch Pub/Sub gelöscht und Sie können diese später nicht mehr abrufen.

Es gibt verschiedene Möglichkeiten, ein Thema zu abonnieren. Für die folgenden Beispiele verwenden wir Cloud Functions-Trigger.

Cloud Functions-Funktion erstellen

So erstellen Sie eine neue Cloud Functions-Funktion:

  1. Rufen Sie in der Google Cloud Platform Console die Seite Cloud Functions auf. Erstellen Sie eine neue Funktion und benennen Sie diese entsprechend für das Budget.
  2. Wählen Sie unter Trigger die Option Cloud Pub/Sub-Thema aus.
  3. Wählen Sie das Thema aus, das Sie für das Budget konfiguriert haben.
  4. Stellen Sie den Quellcode und die Abhängigkeiten für die auszuführende Funktion bereit.

Eine neue Funktion in der GCP Console erstellen

Cloud Functions-Funktion beschreiben

Damit die Cloud Functions-Funktion weiß, was mit der Benachrichtigung geschehen soll, können Sie entweder Code mit dem Inline-Editor schreiben oder eine Datei hochladen. Weitere Informationen zu den Benachrichtigungen, die der Code erhalten wird, finden Sie unter Benachrichtigungsformat.

Eine Funktion kann etwa empfangene Pub/Sub-Benachrichtigungen, Attribute und Daten in ein Log schreiben, wenn sie durch eine Budgetbenachrichtigung ausgelöst wird. Weitere Informationen finden Sie unter Google Cloud Pub/Sub-Trigger.

Cloud Functions-Ereignisse ansehen

Nachdem Sie die Cloud Functions-Funktion gespeichert haben, können Sie auf PROTOKOLLE ANSEHEN klicken, um die protokollierten Budgetbenachrichtigungen anzusehen. Es werden die Logs der Funktionsaufrufe angezeigt.

Cloud Functions-Ereignisse in der GCP Console ansehen

Benachrichtigungen an Slack senden

E-Mails sind nicht immer der beste Weg, um hinsichtlich der Cloudkosten auf dem Laufenden zu bleiben, insbesondere wenn ein bestimmtes Budget unbedingt eingehalten werden muss und es zeitkritisch ist. Mit Benachrichtigungen können Sie Budgetnachrichten an andere Medien weiterleiten.

In diesem Beispiel wird beschrieben, wie Budgetbenachrichtigungen an Slack weitergeleitet werden. Hierbei nutzt eine Cloud Functions-Funktion jedes Mal, wenn von Cloud Billing eine Budgetbenachrichtigung veröffentlicht wird, einen Bot, um eine Nachricht an einen Slack-Kanal des Bot-Arbeitsbereichs zu senden.

Slack-Kanal und Berechtigungen einrichten

Der erste Schritt besteht darin, den Slack-Arbeitsbereich und die Bot-Nutzertokens zu erstellen, die zum Aufrufen der Slack API verwendet werden. API-Tokens können unter https://api.slack.com/apps verwaltet werden. Weitere Informationen finden Sie unter Bot Users (Bot-Nutzer) auf der Slack-Website.

Slack-Benachrichtigungen konfigurieren

Cloud Functions-Funktion erstellen

  1. Erstellen Sie eine neue Funktion. Folgen Sie dazu den Schritten unter Cloud Functions-Funktion erstellen.

  2. Fügen Sie Abhängigkeiten hinzu:

    Python

    Fügen Sie der Datei requirements.txt der Funktion slackclient==1.3.0 hinzu:
    slackclient==1.3.0

  3. Schreiben Sie Code, um mithilfe der Slack API die Budgetbenachrichtigungen an einen Slack-Chat-Kanal zu senden.

  4. Legen Sie im Code folgende "postMessage"-Parameter der Slack API fest:

    • OAuth-Zugriffstoken des Bot-Nutzers
    • Kanal
    • SMS

Beispiel:

Python

from slackclient import SlackClient

# See https://api.slack.com/docs/token-types#bot for more info
BOT_ACCESS_TOKEN = 'xxxx-111111111111-abcdefghidklmnopq'

CHANNEL_ID = 'C0XXXXXX'

slack_client = SlackClient(BOT_ACCESS_TOKEN)

def notify_slack(data, context):
    pubsub_message = data

    notification_attrs = json.dumps(pubsub_message['attributes'])
    notification_data = base64.b64decode(data['data']).decode('utf-8')
    budget_notification_text = f'{notification_attrs}, {notification_data}'

    slack_client.api_call(
      'chat.postMessage',
      channel=CHANNEL_ID,
      text=budget_notification_text)

Kosten deckeln (Abrechnung deaktivieren) und Nutzung stoppen

In diesem Beispiel erfahren Sie, wie Sie Kosten deckeln und die Nutzung eines Google Cloud-Projekts stoppen können, indem Sie die Abrechnung deaktivieren. Dadurch werden alle Google Cloud-Dienste für das Projekt beendet, die nicht kostenlos sind.

Sie müssen die Kosten vielleicht begrenzen, weil Ihre Ausgaben für die Google Cloud Platform einen bestimmten Betrag nicht überschreiten dürfen. Dies trifft üblicherweise auf Studenten, Forscher oder Entwickler zu, die in einer Sandbox-Umgebung arbeiten. In diesen Fällen möchten Sie die Ausgaben begrenzen und sind möglicherweise bereit, alle Ihre Google Cloud Platform-Dienste und deren Nutzung zu beenden, wenn das Budgetlimit erreicht ist.

In unserem Beispiel verwenden wir acme-backend-dev als Nicht-Produktionsprojekt, für das die Abrechnung ohne Bedenken deaktiviert werden kann.

Budgetdeckelung in der GCP Console konfigurieren

Bevor Sie beginnen, müssen Sie ein Budget einrichten, um die Projektkosten zu überwachen, und die Budgetbenachrichtigungen aktivieren.

Abrechnungsbenachrichtigungen in der GCP Console verwalten

Dienstkontoberechtigungen konfigurieren

Die Cloud Functions-Funktion wird als automatisch erstelltes Dienstkonto ausgeführt. Damit die Abrechnung durch das Dienstkonto deaktiviert werden kann, müssen Sie dem Konto Rechnungskonto-Administratorberechtigungen erteilen.

Sehen Sie sich die Details der Cloud-Funktion an, um das richtige Dienstkonto zu ermitteln. Das Dienstkonto ist am Ende der Seite aufgeführt.

Dienstkonto in der GCP Console ermitteln

Sie können die Berechtigungen für Abrechnungsadministratoren auf der Seite "Abrechnung" der Google Cloud Platform Console verwalten.

Wählen Sie den Namen des Dienstkontos aus, um dem Konto Rechnungskonto-Administratorberechtigungen zu erteilen.

Berechtigungen in der GCP Console verwalten

Cloud Functions-Funktion erstellen

Als Nächstes müssen Sie Ihre Cloud Functions-Funktion so konfigurieren, dass sie die Cloud Billing API aufruft. Dadurch kann mit der Funktion die Abrechnung für unser Beispielprojekt acme-backend-dev deaktiviert werden.

  1. Erstellen Sie eine neue Funktion. Folgen Sie dazu den Schritten unter Cloud Functions-Funktion erstellen.

  2. Fügen Sie die folgenden Abhängigkeiten hinzu:

    Python

    Fügen Sie der Datei requirements.txt der Funktion oauth2client==4.1.3 und google-api-python-client==1.7.4 hinzu:
    oauth2client==4.1.3
    google-api-python-client==1.7.4
    

  3. Schreiben Sie Code, um die Abrechnung für das Projekt zu deaktivieren. Entfernen Sie es hierfür aus dem Rechnungskonto.

  4. Legen Sie den Parameter PROJECT_NAME fest. Dies ist das Projekt, für das Sie die Kosten deckeln (Abrechnung deaktivieren) möchten.

Python

import base64
import json
import os
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials
PROJECT_ID = os.getenv('GCP_PROJECT')
PROJECT_NAME = f'projects/{PROJECT_ID}'
ZONE = 'us-west1-b'

def limit_use(data, context):
    pubsub_data = base64.b64decode(data['data']).decode('utf-8')
    pubsub_json = json.loads(pubsub_data)
    cost_amount = pubsub_json['costAmount']
    budget_amount = pubsub_json['budgetAmount']
    if cost_amount <= budget_amount:
        print(f'No action necessary. (Current cost: {cost_amount})')
        return

    compute = discovery.build(
        'compute',
        'v1',
        cache_discovery=False,
        credentials=GoogleCredentials.get_application_default()
    )
    instances = compute.instances()

    instance_names = __list_running_instances(PROJECT_ID, ZONE, instances)
    __stop_instances(PROJECT_ID, ZONE, instance_names, instances)

def __list_running_instances(project_id, zone, instances):
    """
    @param {string} project_id ID of project that contains instances to stop
    @param {string} zone Zone that contains instances to stop
    @return {Promise} Array of names of running instances
    """
    res = instances.list(project=project_id, zone=zone).execute()

    if 'items' not in res:
        return []

    items = res['items']
    running_names = [i['name'] for i in items if i['status'] == 'RUNNING']
    return running_names

def __stop_instances(project_id, zone, instance_names, instances):
    """
    @param {string} project_id ID of project that contains instances to stop
    @param {string} zone Zone that contains instances to stop
    @param {Array} instance_names Names of instance to stop
    @return {Promise} Response from stopping instances
    """
    if not len(instance_names):
        print('No running instances were found.')
        return

    for name in instance_names:
        instances.stop(
          project=project_id,
          zone=zone,
          instance=name).execute()
        print(f'Instance stopped successfully: {name}')

Deaktivierung der Abrechnung überprüfen

Wenn die Funktion ausgelöst wird, können Sie überprüfen, ob die Cloud Functions-Funktion erfolgreich war. Das Projekt wird unter dem Rechnungskonto nicht mehr angezeigt und die Ressourcen im Projekt sind deaktiviert.

Deaktivierung der Abrechnung überprüfen

In der GCP Console können Sie die Abrechnung für das Projekt manuell wieder aktivieren.

Nutzung selektiv steuern

Die oben anhand des Beispiels beschriebene Kostendeckelung (Deaktivierung der Abrechnung) ist binär und endgültig. Das Projekt ist entweder aktiviert oder deaktiviert. Wenn es deaktiviert wird, werden keine Dienste mehr ausgeführt und alle Ressourcen werden schließlich gelöscht.

Wenn Sie eine differenziertere Rückmeldung benötigen, können Sie Ressourcen selektiv steuern. Möchten Sie beispielsweise die Nutzung einiger Rechenressourcen beenden, den Speicher jedoch beibehalten, können Sie die Nutzung selektiv steuern. Dadurch verringern sich die Kosten pro Stunde, ohne dass Ihre Umgebung vollständig deaktiviert wird.

Sie können je nach Anforderungen eine individuelle Differenzierung vornehmen. In diesem Beispiel dient unser Projekt einer Untersuchung mithilfe einer Reihe von virtuellen Maschinen als Rechenressourcen. Die Ergebnisse werden in Cloud Storage gespeichert. In diesem Beispiel einer Cloud-Funktion werden alle Recheninstanzen heruntergefahren. Dies hat jedoch keinen Einfluss auf unsere gespeicherten Ergebnisse, nachdem das Budget überschritten wurde.

Dienstkontoberechtigungen konfigurieren

  1. Die Cloud-Funktion wird als automatisch erstelltes Dienstkonto ausgeführt. Zum Steuern der Nutzung müssen Sie dem Dienstkonto Berechtigungen für alle Dienste im Projekt erteilen, die benötigt werden, um Änderungen vorzunehmen.
  2. Sehen Sie sich die Details der Cloud-Funktion an, um das richtige Dienstkonto zu ermitteln. Das Dienstkonto ist am Ende der Seite aufgeführt.
  3. Gehen Sie zur IAM-Seite der GCP Console, um die entsprechenden Berechtigungen festzulegen.
     
    Abrechnungsbenachrichtigungen in der GCP Console verwalten

Cloud Functions-Funktion erstellen

  1. Erstellen Sie eine neue Funktion. Folgen Sie dazu den Schritten unter Cloud Functions-Funktion erstellen.

  2. Prüfen Sie noch einmal, ob Sie die unter Kosten deckeln (Abrechnung deaktivieren) und Nutzung stoppen beschriebenen Abhängigkeiten hinzugefügt haben.

  3. Schreiben Sie Code, um Ressourcen im Projekt stillzulegen.

  4. Legen Sie den Parameter PROJECT_NAME fest. Dies ist das Projekt, für das Sie die Deckelung konfigurieren möchten.

Python

import base64
import json
import os
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials
PROJECT_ID = os.getenv('GCP_PROJECT')
PROJECT_NAME = f'projects/{PROJECT_ID}'
def stop_billing(data, context):
    pubsub_data = base64.b64decode(data['data']).decode('utf-8')
    pubsub_json = json.loads(pubsub_data)
    cost_amount = pubsub_json['costAmount']
    budget_amount = pubsub_json['budgetAmount']
    if cost_amount <= budget_amount:
        print(f'No action necessary. (Current cost: {cost_amount})')
        return

    billing = discovery.build(
        'cloudbilling',
        'v1',
        cache_discovery=False,
        credentials=GoogleCredentials.get_application_default()
    )

    projects = billing.projects()

    if __is_billing_enabled(PROJECT_NAME, projects):
        print(__disable_billing_for_project(PROJECT_NAME, projects))
    else:
        print('Billing already disabled')

def __is_billing_enabled(project_name, projects):
    """
    Determine whether billing is enabled for a project
    @param {string} project_name Name of project to check if billing is enabled
    @return {bool} Whether project has billing enabled or not
    """
    res = projects.getBillingInfo(name=project_name).execute()
    return res['billingEnabled']

def __disable_billing_for_project(project_name, projects):
    """
    Disable billing for a project by removing its billing account
    @param {string} project_name Name of project disable billing on
    @return {string} Text containing response from disabling billing
    """
    body = {'billingAccountName': ''}  # Disable billing
    res = projects.updateBillingInfo(name=project_name, body=body).execute()
    print(f'Billing disabled: {json.dumps(res)}')

Deaktivierung der Abrechnung überprüfen

Sie können ermitteln, ob die Funktion erfolgreich ausgeführt wurde. Überprüfen Sie dazu in der GCP Console, ob die virtuellen Maschinen heruntergefahren wurden.