Używanie usługi Secret Manager z Pythonem

1. Omówienie

Z tego ćwiczenia w Codelabs dowiesz się, jak używać usługi Secret Manager w Pythonie.

Usługa Secret Manager umożliwia przechowywanie obiektów tajnych, zarządzanie nimi i dostęp do nich w postaci binarnych obiektów blob lub ciągów tekstowych. Mając odpowiednie uprawnienia, możesz wyświetlić zawartość obiektu tajnego.

Usługa Secret Manager dobrze nadaje się do przechowywania informacji konfiguracyjnych, takich jak hasła do baz danych, klucze interfejsu API czy certyfikaty TLS wymagane przez aplikację w czasie działania.

Czego się nauczysz

  • Jak korzystać z Cloud Shell
  • Jak zainstalować bibliotekę klienta usługi Secret Manager dla Pythona
  • Jak tworzyć obiekty tajne i uzyskiwać do nich dostęp za pomocą biblioteki klienta w Pythonie
  • Jak uzyskiwać dostęp do obiektów tajnych w Cloud Functions przy użyciu biblioteki klienta w języku Python

Czego potrzebujesz

  • Projekt Google Cloud
  • przeglądarkę, np. Chrome lub Firefox;
  • Znajomość języka Python 3

Ankieta

Jak wykorzystasz ten samouczek?

Tylko do przeczytania Przeczytaj go i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenia z językiem Python?

Początkujący Poziom średnio zaawansowany Biegły

Jak oceniasz korzystanie z usług Google Cloud?

Początkujący Poziom średnio zaawansowany Biegły
.

2. Konfiguracja i wymagania

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Nazwa projektu jest wyświetlaną nazwą uczestników tego projektu. To ciąg znaków, który nie jest używany przez interfejsy API Google. W każdej chwili możesz ją zmienić.
  • Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i nie można go zmienić (nie można go zmienić po ustawieniu). Cloud Console automatycznie wygeneruje unikalny ciąg znaków. zwykle nieważne, co ona jest. W większości ćwiczeń z programowania konieczne jest odwołanie się do identyfikatora projektu (zwykle nazywa się on PROJECT_ID). Jeśli nie podoba Ci się wygenerowany identyfikator, możesz wygenerować kolejny losowy. Możesz też spróbować własnych sił i sprawdzić, czy jest dostępna. Potem nie będzie można go zmienić. Pozostanie ono przez czas trwania projektu.
  • Dostępna jest trzecia wartość, numer projektu, z którego korzystają niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Cloud/interfejsów API. Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Aby wyłączyć zasoby, aby nie naliczać opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub cały projekt. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

Uruchamianie Cloud Shell

Google Cloud można obsługiwać zdalnie z laptopa, ale w ramach tego ćwiczenia z programowania wykorzystasz Google Cloud Shell – środowisko wiersza poleceń działające w chmurze.

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Jeśli dopiero zaczynasz korzystać z Cloud Shell, wyświetli się ekran pośredni (w części strony widocznej po przewinięciu) z opisem tej funkcji. W takim przypadku kliknij Dalej (nie zobaczysz go więcej). Tak wygląda ten jednorazowy ekran:

9c92662c6a846a5c.png

Uzyskanie dostępu do Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

9f0e51b578fecce5.png

Ta maszyna wirtualna ma wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnianie. Większość czynności z tego ćwiczenia z programowania można wykonać w przeglądarce lub na Chromebooku.

Po nawiązaniu połączenia z Cloud Shell powinno pojawić się informacja, że użytkownik jest już uwierzytelniony i że projekt jest już ustawiony na identyfikator Twojego projektu.

  1. Uruchom to polecenie w Cloud Shell, aby potwierdzić, że jesteś uwierzytelniony:
gcloud auth list

Dane wyjściowe polecenia

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Uruchom to polecenie w Cloud Shell, aby sprawdzić, czy polecenie gcloud zna Twój projekt:
gcloud config list project

Dane wyjściowe polecenia

[core]
project = <PROJECT_ID>

Jeśli tak nie jest, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Dane wyjściowe polecenia

Updated property [core/project].

3. Włączanie interfejsu Secret Manager API

Zanim zaczniesz korzystać z interfejsu Secret Manager API, musisz go włączyć. W Cloud Shell możesz włączyć interfejs API za pomocą tego polecenia:

gcloud services enable secretmanager.googleapis.com

Zostaną wyświetlone następujące dane wyjściowe:

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

4. Instalowanie biblioteki klienta usługi Secret Manager dla Pythona

Zainstaluj bibliotekę klienta usługi Secret Manager:

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

5. Uruchom interaktywnego Pythona

W tym samouczku będziesz używać interaktywnego interpretera Pythona o nazwie IPython, który jest wstępnie zainstalowany w Cloud Shell. Rozpocznij sesję od uruchomienia ipython w Cloud Shell:

ipython

Powinien pojawić się ekran podobny do tego:

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. Tworzenie obiektów tajnych

Obiekt tajny zawiera co najmniej 1 wersję obiektu tajnego. Można je tworzyć za pomocą wiersza poleceń gcloud lub Pythona.

Aby użyć obiektu tajnego, najpierw musisz go utworzyć z nazwą obiektu, a następnie dodać jego wersję, będącą jego wartością.

Ustaw identyfikator projektu w IPython:

PROJECT_ID = "<PROJECT_ID>"

Tworzenie obiektu tajnego

Skopiuj ten kod do sesji IPython:

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}')   

Wywołaj funkcję, aby utworzyć nowy obiekt tajny o nazwie my_secret_value:

create_secret("my_secret_value")

Powinny się wyświetlić te dane wyjściowe:

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

Dodawanie wersji obiektu tajnego

Gdy obiekt tajny już istnieje, możesz przypisać mu wartość, tworząc wersję.

Skopiuj ten kod do sesji IPython:

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}')   

Wywołaj tę funkcję, aby utworzyć nową wersję obiektu tajnego:

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

Powinny się wyświetlić te dane wyjściowe:

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

Obiekty tajne mogą mieć wiele wersji. Wywołaj tę funkcję ponownie z inną wartością:

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

Powinny się wyświetlić te dane wyjściowe:

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

Zwróć uwagę, że nowa wersja naszego obiektu tajnego jest znacznie dłuższa niż pierwotna. Odniesiemy się do tego atrybutu później.

7. Dostęp do obiektów tajnych

Dostęp do wersji obiektu tajnego zwraca jego zawartość oraz dodatkowe metadane dotyczące jego wersji. Uzyskując dostęp do wersji obiektu tajnego, możesz podać konkretną wersję lub poprosić o najnowszą wersję, podając wartość „latest”.

Obiekty tajne nie należy ujawniać. przechowywać dane logowania do bazy danych jako obiekty tajne, a potem używać ich do uwierzytelniania lub przechowywania certyfikatów i ich używać; ale nie drukuj bezpośrednio swoich tajemnic, bo nie da się w ten sposób zachować ich w tajemnicy.

Wykonasz operacje na obiektach tajnych, oceniając ich wartość bez bezpośredniego drukowania. Zamiast tego wydrukujesz szyfrowanie wartości obiektu tajnego.

Skopiuj ten kod do sesji IPython:

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()

Wywołaj funkcję, aby pobrać obiekt tajny jako hasz jego wartości:

secret_hash(access_secret_version("my_secret_value"))

Powinny wyświetlić się dane wyjściowe podobne do tych (dokładna wartość może się różnić od tej):

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

Ponieważ nie została przez Ciebie określona wersja, pobrana została najnowsza wartość.

Wywołaj funkcję, dodając oczekiwany numer wersji, aby potwierdzić:

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

Dane wyjściowe powinny być takie same jak w przypadku ostatniego polecenia:

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

Wywołaj tę funkcję ponownie, ale tym razem określając pierwszą wersję:

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

Tym razem powinna być widoczna inna wartość hash, która wskazuje na inny wynik:

9a3fc8b809ddc611c82aee950c636c7557e220893560ec2c1eeeb177

8. Używanie usługi Secret Manager z Cloud Functions

Obiektów tajnych możesz używać w wielu częściach Google Cloud. W tej sekcji skupimy się na Cloud Functions, czyli bezserwerowej ofercie obliczeniowej Google opartej na zdarzeniach.

Jeśli chcesz używać Pythona w Cloud Functions, zapoznaj się z instrukcjami HTTP Google Cloud Functions w Pythonie z programowania (w języku angielskim).

Zamknij IPython, wywołując funkcję exit:

exit

Powinien nastąpić powrót do Cloud Shell:

yourname@cloudshell:~ (<PROJECT_ID>)$

Zanim zaczniesz korzystać z interfejsu Cloud Functions API, musisz go włączyć. W Cloud Shell możesz włączyć interfejs API za pomocą tego polecenia:

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

Utwórz nowy folder, aby utworzyć naszą funkcję, czyli puste pliki, w których będą zapisywane:

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

Otwórz edytor kodu w prawym górnym rogu Cloud Shell:

7651a97c51e11a24.png

Przejdź do pliku main.py w folderze secret-manager-api-demo. W tym miejscu umieścisz cały kod.

9. Tworzenie funkcji w Cloud Functions umożliwiającej dostęp do obiektów tajnych

Przechowywanie i pobieranie wartości obiektów tajnych z wiersza poleceń lub terminala IPython jest przydatne, ale znacznie bardziej przydatne jest możliwość uzyskiwania dostępu do tych obiektów tajnych z poziomu funkcji.

Korzystając z utworzonej wcześniej funkcji access_secret_version, możesz jej użyć jako podstawy dla swojej funkcji w Cloud Functions.

Skopiuj ten kod do pliku 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"

Przed wdrożeniem funkcji musisz dokończyć konfigurowanie środowiska. Wymaga to skonfigurowania zależności funkcji.

Utwórz nowy plik o nazwie requirements.txt i dodaj do niego pakiet google-cloud-secret-manager:

requirements.txt

google-cloud-secret-manager==2.10.0

Powinien być teraz utworzyć folder zawierający tylko main.py i requirements.txt.

Zezwalanie na dostęp do obiektu tajnego

Zanim wdrożysz funkcję, musisz zezwolić usłudze Cloud Functions na dostęp do obiektu tajnego.

Wróć do terminala:

c5b686edf94b5222.png

Przyznaj dostęp do konta usługi Cloud Functions, aby uzyskać dostęp do obiektu tajnego:

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

Powinny się wyświetlić te dane wyjściowe:

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. Wdrażanie funkcji w Cloud Functions

Po konfiguracji z poprzednich sekcji możesz teraz wdrożyć i przetestować swoją funkcję w Cloud Functions.

W folderze zawierającym tylko 2 utworzone pliki wdróż tę funkcję:

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

Powinny się wyświetlić następujące dane wyjściowe (obcięte):

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
...

Pobierz adres URL funkcji (metadane httpsTrigger.url) za pomocą tego polecenia:

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

Teraz przetestuj, czy dostęp do funkcji można uzyskać z oczekiwaną wartością zwrotną, wywołując swoją funkcję:

curl $FUNCTION_URL

Powinny się wyświetlić te dane wyjściowe:

We meet again!

Ta funkcja odwołuje się do najnowszej wersji obiektu tajnego, która zgodnie z ustawieniami zawiera ciąg „Ponownie”, dlatego działa zgodnie z oczekiwaniami.

11. Gratulacje!

Już wiesz, jak korzystać z interfejsu Secret Manager API w języku Python.

Czyszczenie danych

Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby zużyte w tym samouczku:

  • W konsoli Cloud otwórz stronę Zarządzanie zasobami.
  • Na liście projektów wybierz swój projekt i kliknij Usuń.
  • W oknie wpisz identyfikator projektu i kliknij Wyłącz, aby usunąć projekt.

Więcej informacji

Licencja

To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.