Использование Secret Manager с Python

1. Обзор

В этой лабораторной работе вы сосредоточитесь на использовании Secret Manager в Python.

Secret Manager позволяет хранить секреты, управлять ими и получать к ним доступ в виде двоичных объектов или текстовых строк. Имея соответствующие разрешения, вы можете просмотреть содержимое секрета.

Secret Manager хорошо подходит для хранения информации о конфигурации, такой как пароли базы данных, ключи API или сертификаты TLS, необходимые приложению во время выполнения.

Что вы узнаете

  • Как использовать Cloud Shell
  • Как установить клиентскую библиотеку Secret Manager для Python
  • Как создавать секреты и получать к ним доступ с помощью клиентской библиотеки Python
  • Как получить доступ к секретам в облачных функциях с помощью клиентской библиотеки Python

Что вам понадобится

  • Облачный проект Google
  • Браузер, например Chrome или Firefox.
  • Знакомство с Python 3.

Опрос

Как вы будете использовать этот урок?

Прочтите только до конца Прочитайте его и выполните упражнения.

Как бы вы оценили свой опыт работы с Python?

Новичок Средний Опытный

Как бы вы оценили свой опыт использования сервисов Google Cloud?

Новичок Средний Опытный

2. Настройка и требования

Самостоятельная настройка среды

  1. Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы можете обновить его в любое время.
  • Идентификатор проекта должен быть уникальным для всех проектов Google Cloud и неизменяемым (нельзя изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно он обозначается как PROJECT_ID ). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Кроме того, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага, и он останется в силе на протяжении всего проекта.
  • К вашему сведению, есть третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
  1. Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Чтобы отключить ресурсы и избежать выставления счетов за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить весь проект. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лаборатории вы будете использовать Google Cloud Shell , среду командной строки, работающую в облаке.

Активировать Cloud Shell

  1. В Cloud Console нажмите «Активировать Cloud Shell». 853e55310c205094.png .

55efc1aaa7a4d3ad.png

Если вы никогда раньше не запускали Cloud Shell, вам будет представлен промежуточный экран (ниже сгиба) с описанием того, что это такое. В этом случае нажмите «Продолжить» (и вы больше никогда его не увидите). Вот как выглядит этот одноразовый экран:

9c92662c6a846a5c.png

Подготовка и подключение к Cloud Shell займет всего несколько минут.

9f0e51b578fecce5.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Большую часть, если не всю, работу в этой лаборатории кода можно выполнить с помощью просто браузера или Chromebook.

После подключения к Cloud Shell вы увидите, что вы уже прошли аутентификацию и что для проекта уже установлен идентификатор вашего проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить, что вы прошли аутентификацию:
gcloud auth list

Вывод команды

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

Вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить его с помощью этой команды:

gcloud config set project <PROJECT_ID>

Вывод команды

Updated property [core/project].

3. Включите API диспетчера секретов.

Прежде чем вы сможете начать использовать API Secret Manager, вы должны включить API. Используя Cloud Shell, вы можете включить API с помощью следующей команды:

gcloud services enable secretmanager.googleapis.com

Вы должны увидеть такой вывод:

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

4. Установка клиентской библиотеки Secret Manager для Python

Установите клиентскую библиотеку Secret Manager :

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

5. Запустите интерактивный Python

В рамках этого руководства вы будете использовать интерактивный интерпретатор Python под названием IPython , который предварительно установлен в Cloud Shell. Запустите сеанс, запустив ipython в Cloud Shell:

ipython

Вы должны увидеть что-то вроде этого:

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. Создание секретов

Секрет содержит одну или несколько секретных версий. Их можно создать с помощью командной строки gcloud , но их также можно создать с помощью Python.

Чтобы использовать секрет, сначала необходимо создать секрет с именем секрета, затем добавить версию секрета, являющуюся значением секрета.

Установите идентификатор проекта в IPython:

PROJECT_ID = "<PROJECT_ID>"

Создать секрет

Скопируйте следующий код в свой сеанс 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}')   

Вызовите функцию, чтобы создать новый секрет с именем my_secret_value :

create_secret("my_secret_value")

Вы должны увидеть следующий вывод:

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

Добавить секретную версию

Теперь, когда секрет существует, вы можете присвоить ему значение , создав версию.

Скопируйте следующий код в свой сеанс 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}')   

Вызовите функцию, чтобы создать новую секретную версию:

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

Вы должны увидеть следующий вывод:

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

Секреты могут иметь несколько версий. Вызовите функцию еще раз с другим значением:

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

Вы должны увидеть следующий вывод:

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

Обратите внимание, что новая версия нашего секрета значительно длиннее исходной. Этот атрибут будет использоваться позже.

7. Доступ к секретам

Доступ к секретной версии возвращает секретное содержимое, а также дополнительные метаданные о секретной версии. Когда вы получаете доступ к секретной версии, вы можете либо указать конкретную версию, либо просто запросить последнюю версию, указав «последняя».

Тайны должны храниться в секрете. Храните учетные данные базы данных как секреты, а затем используйте их для аутентификации или сохраняйте сертификаты и используйте их; но не распечатывайте свои секреты напрямую, так как это противоречит цели сохранения их в секрете.

Вы собираетесь выполнять операции с нашими секретами, оценивая их ценность, не распечатывая их напрямую. Вместо этого вы распечатаете хэш значения секрета.

Скопируйте следующий код в свой сеанс 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()

Вызовите функцию, чтобы получить секрет в виде хэша его значения:

secret_hash(access_secret_version("my_secret_value"))

Вы должны увидеть выходные данные, похожие на хеш (точное значение может не совпадать с этим выходными данными):

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

Поскольку вы не указали версию, было получено последнее значение.

Вызовите функцию, добавив ожидаемый номер версии, чтобы подтвердить:

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

Вы должны увидеть тот же вывод, что и последняя команда:

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

Вызовите функцию еще раз, но на этот раз указав первую версию:

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

На этот раз вы должны увидеть другой хеш, указывающий на другой результат:

9a3fc8b809ddc611c82aee950c636c7557e220893560ec2c1eeeb177

8. Использование Secret Manager с облачными функциями

Вы можете использовать секреты во многих частях Google Cloud. В этом разделе вы сосредоточитесь на облачных функциях, предложении Google для бессерверных вычислений, управляемых событиями.

Если вы заинтересованы в использовании Python в облачных функциях, вы можете следить за HTTP-функциями Google Cloud в Python Codelab .

Закройте IPython, вызвав функцию exit :

exit

Вы должны вернуться в Cloud Shell:

yourname@cloudshell:~ (<PROJECT_ID>)$

Прежде чем вы сможете начать использовать API облачных функций, вы должны включить API. Используя Cloud Shell, вы можете включить API с помощью следующей команды:

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

Создайте новую папку для создания нашей функции, создав пустые файлы для записи:

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

Откройте редактор кода в правом верхнем углу Cloud Shell:

7651a97c51e11a24.png

Перейдите к файлу main.py в папке secret-manager-api-demo . Здесь вы будете размещать весь свой код.

9. Написание облачной функции для доступа к секретам

Хотя сохранение и получение секретных значений из командной строки или терминала IPython полезно, гораздо полезнее иметь возможность доступа к этим секретам внутри функции.

Используя функцию access_secret_version которую вы создали ранее, вы можете использовать ее в качестве основы для своей облачной функции.

Скопируйте следующий код в файл 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"

Прежде чем вы сможете развернуть свою функцию, вам необходимо завершить настройку среды. Для этого необходимо настроить зависимость функции.

Создайте новый файл с именем requirements.txt и добавьте в него пакет google-cloud-secret-manager :

требования.txt

google-cloud-secret-manager==2.10.0

Теперь у вас должна быть папка, содержащая только main.py и requirements.txt .

Разрешение доступа к вашему секрету

Прежде чем вы сможете развернуть свою функцию, вам необходимо предоставить облачным функциям доступ к вашему секрету.

Вернитесь к терминалу:

c5b686edf94b5222.png

Предоставьте доступ к учетной записи службы облачных функций, чтобы получить доступ к вашему секрету:

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

Вы должны увидеть следующий вывод:

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. Развертывание облачной функции

Учитывая настройки, описанные в предыдущих разделах, теперь вы можете развернуть и протестировать свою облачную функцию.

В папке, содержащей только два созданных вами файла, разверните функцию:

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

Вы должны увидеть следующий вывод (усеченный):

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

Получите URL-адрес вашей функции (метаданные httpsTrigger.url ) с помощью следующей команды:

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

Теперь проверьте, что к функции можно получить доступ с ожидаемым возвращаемым значением, вызвав вашу функцию:

curl $FUNCTION_URL

Вы должны увидеть следующий вывод:

We meet again!

Эта функция ссылается на самую последнюю версию секрета, которая содержит строку «Снова», поэтому эта функция работает должным образом.

11. Поздравляем!

Вы узнали, как использовать API Secret Manager с помощью Python!

Очистить

Чтобы избежать списания средств с вашей учетной записи Google Cloud за ресурсы, используемые в этом руководстве:

  • В Cloud Console перейдите на страницу «Управление ресурсами» .
  • В списке проектов выберите свой проект и нажмите «Удалить» .
  • В диалоговом окне введите идентификатор проекта и нажмите «Завершить работу» , чтобы удалить проект.

Узнать больше

Лицензия

Эта работа распространяется под лицензией Creative Commons Attribution 2.0 Generic License.