Secret Manager mit Python verwenden

1. Übersicht

In diesem Codelab konzentrieren Sie sich auf die Verwendung von Secret Manager in Python.

Mit Secret Manager können Sie Secrets als binäre Blobs oder Textstrings speichern, verwalten und aufrufen. Mit den entsprechenden Berechtigungen können Sie den Inhalt des Secrets aufrufen.

Secret Manager eignet sich gut zum Speichern von Konfigurationsinformationen wie Datenbankpasswörtern, API-Schlüsseln oder TLS-Zertifikaten, die eine Anwendung zur Laufzeit benötigt.

Lerninhalte

  • Cloud Shell verwenden
  • Secret Manager-Clientbibliothek für Python installieren
  • Secrets mit der Python-Clientbibliothek erstellen und darauf zugreifen
  • Mit der Python-Clientbibliothek auf Secrets in Cloud Functions zugreifen

Voraussetzungen

  • Ein Google Cloud-Projekt
  • Ein Browser, z. B. Chrome oder Firefox
  • Python 3-Vorkenntnisse

Umfrage

Wie möchten Sie diese Anleitung nutzen?

<ph type="x-smartling-placeholder"></ph> Nur bis zum Ende lesen Lies sie dir durch und absolviere die Übungen

Wie würden Sie Ihre Erfahrung mit Python bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Mittel Kompetent

Wie würden Sie Ihre Erfahrungen im Umgang mit Google Cloud-Diensten bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Mittel Kompetent

2. Einrichtung und Anforderungen

Umgebung für das selbstbestimmte Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Projektteilnehmer. Es handelt sich um eine Zeichenfolge, die von Google APIs nicht verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID muss für alle Google Cloud-Projekte eindeutig sein und ist unveränderlich. Sie kann nach dem Festlegen nicht mehr geändert werden. Die Cloud Console generiert automatisch einen eindeutigen String. ist Ihnen meist egal, was es ist. In den meisten Codelabs musst du auf die Projekt-ID verweisen, die üblicherweise als PROJECT_ID gekennzeichnet ist. Wenn Ihnen die generierte ID nicht gefällt, können Sie eine weitere zufällige ID erstellen. Alternativ können Sie einen eigenen verwenden und nachsehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information gibt es noch einen dritten Wert, die Projektnummer, die von manchen APIs verwendet wird. Weitere Informationen zu allen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Cloud-Ressourcen/APIs verwenden zu können. Dieses Codelab sollte möglichst wenig kosten. Wenn Sie Ressourcen herunterfahren möchten, um über diese Anleitung hinaus keine Kosten zu verursachen, können Sie die von Ihnen erstellten Ressourcen oder das gesamte Projekt löschen. Neue Google Cloud-Nutzer haben Anspruch auf eine kostenlose Testversion mit 300$Guthaben.

Cloud Shell starten

Sie können Google Cloud zwar von Ihrem Laptop aus der Ferne bedienen, in diesem Codelab verwenden Sie jedoch Google Cloud Shell, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Wenn Sie Cloud Shell noch nie gestartet haben, wird ein Zwischenbildschirm (below the fold) angezeigt, in dem beschrieben wird, worum es sich dabei handelt. Klicken Sie in diesem Fall auf Weiter. Der Chat wird nie wieder angezeigt. So sieht dieser einmalige Bildschirm aus:

9c92662c6a846a5c.png

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

9f0e51b578fecce5.png

Diese virtuelle Maschine verfügt über alle Entwicklungstools, die Sie benötigen. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können Sie ganz einfach mit einem Browser oder Ihrem Chromebook erledigen.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und dass das Projekt bereits auf Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Secret Manager API aktivieren

Bevor Sie die Secret Manager API verwenden können, müssen Sie sie aktivieren. In Cloud Shell können Sie die API mit dem folgenden Befehl aktivieren:

gcloud services enable secretmanager.googleapis.com

Die Ausgabe sollte in etwa so aussehen:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

4. Secret Manager-Clientbibliothek für Python installieren

Installieren Sie die Secret Manager-Clientbibliothek:

pip3 install --user google-cloud-secret-manager==2.10.0

5. Interaktives Python starten

Für einen Teil dieser Anleitung verwenden Sie den interaktiven Python-Interpreter mit dem Namen IPython, der in Cloud Shell vorinstalliert ist. Starten Sie eine Sitzung, indem Sie ipython in Cloud Shell ausführen:

ipython

Auf dem Bildschirm sollte Folgendes zu sehen sein:

Python 3.9.2 (default, Feb 28 2021, 17:03:44)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.3.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

6. Secrets erstellen

Ein Secret enthält eine oder mehrere Secret-Versionen. Sie können mit der gcloud-Befehlszeile oder auch mit Python erstellt werden.

Wenn Sie ein Secret verwenden möchten, müssen Sie zuerst das Secret mit dem Namen des Secrets erstellen und dann eine Version des Secrets hinzufügen, die dem Wert des Secrets entspricht.

Legen Sie Ihre Projekt-ID in IPython fest:

PROJECT_ID = "<PROJECT_ID>"

Secret erstellen

Kopieren Sie den folgenden Code in Ihre IPython-Sitzung:

from google.cloud import secretmanager

def create_secret(secret_id):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the parent project.
    parent = f"projects/{PROJECT_ID}"

    # Build a dict of settings for the secret
    secret = {'replication': {'automatic': {}}}

    # Create the secret
    response = client.create_secret(secret_id=secret_id, parent=parent, secret=secret)

    # Print the new secret name.
    print(f'Created secret: {response.name}')   

Rufen Sie die Funktion auf, um ein neues Secret mit dem Namen my_secret_value zu erstellen:

create_secret("my_secret_value")

Es sollte folgende Ausgabe angezeigt werden:

Created secret: projects/<PROJECT_NUM>/secrets/my_secret_value

Secret-Version hinzufügen

Jetzt, da das Secret vorhanden ist, können Sie ihm einen Wert zuweisen, indem Sie eine Version erstellen.

Kopieren Sie den folgenden Code in Ihre IPython-Sitzung:

def add_secret_version(secret_id, payload):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the parent secret.
    parent = f"projects/{PROJECT_ID}/secrets/{secret_id}"

    # Convert the string payload into a bytes. This step can be omitted if you
    # pass in bytes instead of a str for the payload argument.
    payload = payload.encode('UTF-8')

    # Add the secret version.
    response = client.add_secret_version(parent=parent, payload={'data': payload})

    # Print the new secret version name.
    print(f'Added secret version: {response.name}')   

Rufen Sie die Funktion auf, um eine neue Secret-Version hinzuzufügen:

add_secret_version("my_secret_value", "Hello Secret Manager")

Es sollte folgende Ausgabe angezeigt werden:

Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/1

Secrets können mehrere Versionen haben. Rufen Sie die Funktion noch einmal mit einem anderen Wert auf:

add_secret_version("my_secret_value", "Hello Again, Secret Manager")

Es sollte folgende Ausgabe angezeigt werden:

Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/2

Beachten Sie, dass die neue Version unseres Secrets deutlich länger ist als die ursprüngliche. Auf dieses Attribut wird später verwiesen.

7. Auf Secrets zugreifen

Wenn Sie auf eine Secret-Version zugreifen, werden der Secret-Inhalt sowie zusätzliche Metadaten über die Secret-Version zurückgegeben. Wenn Sie auf eine Secret-Version zugreifen, können Sie entweder eine bestimmte Version angeben oder einfach nach der neuesten Version fragen, indem Sie „latest“ angeben.

Secrets sollten geheim gehalten werden. Anmeldedaten für Datenbanken als Secrets speichern und dann zur Authentifizierung verwenden oder Zertifizierungen speichern und verwenden Drucken Sie Ihre Geheimnisse aber nicht direkt aus, da dies den Zweck, sie geheim zu halten, zunichte macht.

Sie führen Operationen für unsere Secrets durch und bewerten ihren Wert, ohne sie direkt auszudrucken. Stattdessen geben Sie einen Hash des Werts des Secrets aus.

Kopieren Sie den folgenden Code in Ihre IPython-Sitzung:

def access_secret_version(secret_id, version_id="latest"):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the secret version.
    name = f"projects/{PROJECT_ID}/secrets/{secret_id}/versions/{version_id}"

    # Access the secret version.
    response = client.access_secret_version(name=name)

    # Return the decoded payload.
    return response.payload.data.decode('UTF-8')
    
import hashlib

def secret_hash(secret_value): 
  # return the sha224 hash of the secret value
  return hashlib.sha224(bytes(secret_value, "utf-8")).hexdigest()

Rufen Sie die Funktion auf, um das Secret als Hash des Werts abzurufen:

secret_hash(access_secret_version("my_secret_value"))

Die Ausgabe sollte einem Hash ähneln (der genaue Wert stimmt möglicherweise nicht mit dieser Ausgabe überein):

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

Da Sie keine Version angegeben haben, wurde der neueste Wert abgerufen.

Rufen Sie zur Bestätigung die Funktion auf und fügen Sie die erwartete Versionsnummer hinzu:

secret_hash(access_secret_version("my_secret_value", version_id=2))

Sie sollten dieselbe Ausgabe sehen wie beim letzten Befehl:

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

Rufen Sie die Funktion erneut auf, aber dieses Mal geben Sie die erste Version an:

secret_hash(access_secret_version("my_secret_value", version_id=1))

Dieses Mal sollte ein anderer Hash angezeigt werden, der auf eine andere Ausgabe hinweist:

9a3fc8b809ddc611c82aee950c636c7557e220893560ec2c1eeeb177

8. Secret Manager mit Cloud Functions verwenden

Sie können Secrets in vielen Teilen von Google Cloud verwenden. In diesem Abschnitt konzentrieren wir uns auf Cloud Functions, das ereignisgesteuerte serverlose Computing von Google.

Wenn Sie Python in Cloud Functions verwenden möchten, lesen Sie das Codelab zu HTTP-Funktionen von Google Cloud in Python.

Schließen Sie IPython durch Aufrufen der Funktion exit:

exit

Sie sollten zu Cloud Shell zurückgeleitet werden:

yourname@cloudshell:~ (<PROJECT_ID>)$

Bevor Sie die Cloud Functions API verwenden können, müssen Sie die API aktivieren. In Cloud Shell können Sie die API mit dem folgenden Befehl aktivieren:

gcloud services enable cloudfunctions.googleapis.com cloudbuild.googleapis.com

Erstellen Sie einen neuen Ordner, um die Funktion zu erstellen, indem Sie leere Dateien erstellen, in die geschrieben wird:

mkdir secret-manager-api-demo
cd secret-manager-api-demo
touch main.py
touch requirements.txt

Öffnen Sie oben rechts in Cloud Shell den Code-Editor:

7651a97c51e11a24.png

Rufen Sie die Datei main.py im Ordner secret-manager-api-demo auf. Hier werden Sie Ihren gesamten Code einfügen.

9. Cloud Functions-Funktion für den Zugriff auf Secrets schreiben

Das Speichern und Abrufen von Secret-Werten über die Befehlszeile oder das IPython-Terminal ist zwar nützlich, es ist jedoch viel nützlicher, wenn Sie innerhalb einer Funktion auf diese Secrets zugreifen können.

Mit der zuvor erstellten Funktion access_secret_version können Sie diese als Grundlage für Ihre Cloud Functions-Funktion verwenden.

Kopieren Sie den folgenden Code in die Datei main.py:

main.py

import os

from google.cloud import secretmanager

project_id = os.environ["PROJECT_ID"]

client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/my_secret_value/versions/latest"
response = client.access_secret_version(name=name)
my_secret_value = response.payload.data.decode("UTF-8")


def secret_hello(request):
    if "Again" in my_secret_value:
        return "We meet again!\n"

    return "Hello there.\n"

Bevor Sie die Funktion bereitstellen können, müssen Sie die Einrichtung der Umgebung abschließen. Dazu müssen Sie die Funktionsabhängigkeit einrichten.

Erstellen Sie eine neue Datei mit dem Namen requirements.txt und fügen Sie das Paket google-cloud-secret-manager hinzu:

requirements.txt

google-cloud-secret-manager==2.10.0

Sie sollten jetzt einen Ordner haben, der nur main.py und requirements.txt enthält.

Zugriff auf Ihr Secret gewähren

Bevor Sie Ihre Funktion bereitstellen können, müssen Sie Cloud Functions Zugriff auf Ihr Secret gewähren.

Wechseln Sie zurück zum Terminal:

c5b686edf94b5222.png

Gewähren Sie dem Cloud Functions-Dienstkonto Zugriff auf Ihr Secret:

export PROJECT_ID=$(gcloud config get-value core/project)

gcloud secrets add-iam-policy-binding my_secret_value \
    --role roles/secretmanager.secretAccessor \
    --member serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com

Es sollte folgende Ausgabe angezeigt werden:

Updated IAM policy for secret [my_secret_value].
bindings:
- members:
  - serviceAccount:<PROJECT_ID>@appspot.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwWiRUt2oB4=
version: 1

10. Cloud Functions-Funktion bereitstellen

Aufgrund der Einrichtung in den vorherigen Abschnitten können Sie die Cloud Functions-Funktion jetzt bereitstellen und testen.

Stellen Sie die Funktion in dem Ordner bereit, der nur die beiden von Ihnen erstellten Dateien enthält:

gcloud functions deploy secret_hello \
    --runtime python39 \
    --set-env-vars PROJECT_ID=${PROJECT_ID} \
    --trigger-http \
    --allow-unauthenticated

Die folgende Ausgabe sollte abgeschnitten werden:

Deploying function (may take a while - up to 2 minutes)...done.

...

entryPoint: secret_hello
httpsTrigger:
  url: https://<REGION>-<PROJECT_ID>.cloudfunctions.net/secret_hello
...
status: ACTIVE
...

Rufen Sie die URL Ihrer Funktion (httpsTrigger.url-Metadaten) mit dem folgenden Befehl ab:

FUNCTION_URL=$(gcloud functions describe secret_hello --format 'value(httpsTrigger.url)')

Testen Sie nun die Funktion, auf die mit dem erwarteten Rückgabewert zugegriffen werden kann, indem Sie Ihre Funktion aufrufen:

curl $FUNCTION_URL

Es sollte folgende Ausgabe angezeigt werden:

We meet again!

Diese Funktion verweist auf die neueste Version des Secrets, für die festgelegt wurde, dass sie den String „Again“ enthält, sodass diese Funktion wie erwartet funktioniert.

11. Glückwunsch!

Sie haben gelernt, wie Sie die Secret Manager API mit Python verwenden.

Bereinigen

So vermeiden Sie, dass Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen in Rechnung gestellt werden:

  • Rufen Sie in der Cloud Console die Seite Ressourcen verwalten auf.
  • Wählen Sie Ihr Projekt in der Projektliste aus und klicken Sie auf Löschen.
  • Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Beenden, um das Projekt zu löschen.

Weitere Informationen

Lizenz

Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.