1. Descripción general
En este codelab, te enfocarás en el uso de Secret Manager en Python.
Secret Manager te permite almacenar, administrar y acceder a los secretos como BLOB binarios o cadenas de texto. Con los permisos adecuados, puedes ver el contenido del secreto.
Secret Manager funciona bien para almacenar información de configuración, como contraseñas de bases de datos, claves de API o certificados TLS que necesita una aplicación en el entorno de ejecución.
Qué aprenderás
- Cómo usar Cloud Shell
- Cómo instalar la biblioteca cliente de Secret Manager para Python
- Cómo crear secretos y acceder a ellos con la biblioteca cliente de Python
- Cómo acceder a los secretos en Cloud Functions con la biblioteca cliente de Python
Requisitos
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Configuración y requisitos
Configuración del entorno de autoaprendizaje
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.
- El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla en cualquier momento.
- El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. por lo general, no te importa qué es. En la mayoría de los codelabs, deberás hacer referencia al ID del proyecto (por lo general, se identifica como
PROJECT_ID
). Si no te gusta el ID generado, puedes generar otro aleatorio. También puedes probar el tuyo propio y ver si está disponible. No se puede cambiar después de este paso y se mantendrá mientras dure el proyecto. - Para tu información, hay un tercer valor, un número de proyecto que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Para cerrar recursos y evitar que se te facture más allá de este instructivo, puedes borrar los recursos que creaste o borrar todo el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.
Inicia Cloud Shell
Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.
Activar Cloud Shell
- En la consola de Cloud, haz clic en Activar Cloud Shell.
Si nunca iniciaste Cloud Shell, aparecerá una pantalla intermedia (mitad inferior de la página) que describe en qué consiste. Si ese es el caso, haz clic en Continuar (y no volverás a verlo). Así es como se ve la pantalla única:
El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.
Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitas. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer simplemente con un navegador o tu Chromebook.
Una vez conectado a Cloud Shell, debería ver que ya se autenticó y que el proyecto ya se configuró con tu ID del proyecto.
- En Cloud Shell, ejecuta el siguiente comando para confirmar que está autenticado:
gcloud auth list
Resultado del comando
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Ejecuta el siguiente comando en Cloud Shell para confirmar que el comando de gcloud conoce tu proyecto:
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
De lo contrario, puedes configurarlo con el siguiente comando:
gcloud config set project <PROJECT_ID>
Resultado del comando
Updated property [core/project].
3. Habilita la API de Secret Manager
Antes de comenzar a usar la API de Secret Manager, debes habilitarla. En Cloud Shell, puedes habilitar la API con el siguiente comando:
gcloud services enable secretmanager.googleapis.com
Debería ver un resultado como este:
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
4. Instala la biblioteca cliente de Secret Manager para Python
Instala la biblioteca cliente de Secret Manager:
pip3 install --user google-cloud-secret-manager==2.10.0
5. Iniciar Python interactivo
Como parte de este instructivo, usarás un intérprete de Python interactivo llamado IPython, que está preinstalado en Cloud Shell. Para iniciar una sesión, ejecuta ipython
en Cloud Shell:
ipython
Debería ver algo como esto:
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. Crea secretos
Un secreto contiene una o más versiones de secretos. Se pueden crear con la línea de comandos de gcloud
, pero también con Python.
Para usar un secreto, primero debes crearlo con el nombre del secreto y, luego, agregarle una versión, que será su valor.
Establece el ID del proyecto en IPython:
PROJECT_ID = "<PROJECT_ID>"
Crea un secreto
Copia el siguiente código en tu sesión de 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}')
Llama a la función para crear un secreto nuevo llamado my_secret_value
:
create_secret("my_secret_value")
Deberías ver el siguiente resultado:
Created secret: projects/<PROJECT_NUM>/secrets/my_secret_value
Agrega una versión del Secret
Ahora que el secreto existe, puedes asignarle un valor creando una versión.
Copia el siguiente código en tu sesión de 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}')
Llama a la función para crear una nueva versión del secreto:
add_secret_version("my_secret_value", "Hello Secret Manager")
Deberías ver el siguiente resultado:
Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/1
Los Secrets pueden tener varias versiones. Vuelve a llamar a la función con un valor diferente:
add_secret_version("my_secret_value", "Hello Again, Secret Manager")
Deberías ver el siguiente resultado:
Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/2
Observa que la nueva versión de nuestro secreto es significativamente más larga que la original. Más adelante, se hará referencia a este atributo.
7. Acceso a Secrets
El acceso a una versión del secreto muestra su contenido, así como metadatos adicionales sobre la versión del secreto. Cuando accedes a una versión del secreto, puedes especificar una versión específica o solo solicitar la última versión especificando “más reciente”.
Los secretos deben ser secretos. Almacenar las credenciales de la base de datos como Secrets y, luego, usarlas para autenticar, o almacenar las certificaciones y usarlas pero no imprimas directamente tus secretos, ya que esto va en contra del objetivo de mantenerlos en secreto.
Realizarás operaciones en nuestros secretos y evaluarás su valor sin imprimirlos directamente. En su lugar, imprimirás un hash del valor del secreto.
Copia el siguiente código en tu sesión de 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()
Llama a la función para recuperar el secreto como un hash de su valor:
secret_hash(access_secret_version("my_secret_value"))
Deberías ver un resultado similar a un hash (es posible que el valor exacto no coincida con este resultado):
83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11
Como no especificaste una versión, se recuperó el valor más reciente.
Llama a la función y agrega el número de versión esperado para confirmar:
secret_hash(access_secret_version("my_secret_value", version_id=2))
Deberías ver el mismo resultado que el último comando:
83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11
Vuelve a llamar a la función, pero esta vez especifica la primera versión:
secret_hash(access_secret_version("my_secret_value", version_id=1))
Esta vez, deberías ver un hash diferente, lo que indica un resultado diferente:
9a3fc8b809ddc611c82aee950c636c7557e220893560ec2c1eeeb177
8. Usa Secret Manager con Cloud Functions
Puedes usar Secrets en muchas partes de Google Cloud. En esta sección, te enfocarás en Cloud Functions, la oferta de computación sin servidores controlada por eventos de Google.
Si te interesa usar Python en Cloud Functions, puedes seguir el Codelab de HTTP de Google Cloud Functions en Python.
Cierra IPython; para ello, llama a la función exit
:
exit
Deberías regresar a Cloud Shell:
yourname@cloudshell:~ (<PROJECT_ID>)$
Antes de comenzar a usar la API de Cloud Functions, debes habilitarla. En Cloud Shell, puedes habilitar la API con el siguiente comando:
gcloud services enable cloudfunctions.googleapis.com cloudbuild.googleapis.com
Crea una carpeta nueva para compilar la función y crea archivos vacíos en los que escribir:
mkdir secret-manager-api-demo cd secret-manager-api-demo touch main.py touch requirements.txt
Abre el editor de código desde la parte superior derecha de Cloud Shell:
Navega al archivo main.py
dentro de la carpeta secret-manager-api-demo
. Aquí es donde colocarás todo tu código.
9. Escribe una Cloud Function para acceder a los secretos
Si bien almacenar y recuperar valores de secretos desde la línea de comandos o la terminal de IPython es útil, lo es mucho más poder acceder a estos secretos dentro de una función.
Con la función access_secret_version
que creaste antes, puedes usarla como base para tu Cloud Function.
Copia el siguiente código en el archivo 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"
Antes de que puedas implementar tu función, debes finalizar la configuración del entorno. Esto requiere que configures tu dependencia de función.
Crea un archivo nuevo llamado requirements.txt
y agrégale el paquete google-cloud-secret-manager
:
requirements.txt
google-cloud-secret-manager==2.10.0
Ahora, deberías tener una carpeta que contenga solo un main.py
y un requirements.txt
.
Cómo permitir el acceso a tu secreto
Antes de que puedas implementar tu función, debes permitir que Cloud Functions acceda a tu secreto.
Vuelve a la terminal:
Otorga acceso a la cuenta de servicio de Cloud Functions para acceder a tu secreto:
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
Deberías ver el siguiente resultado:
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. Implementa tu Cloud Function
Dada la configuración que realizaste en las secciones anteriores, ahora puedes implementar y probar tu Cloud Function.
Dentro de la carpeta que contiene solo los dos archivos que creaste, implementa la función:
gcloud functions deploy secret_hello \ --runtime python39 \ --set-env-vars PROJECT_ID=${PROJECT_ID} \ --trigger-http \ --allow-unauthenticated
Deberías ver el siguiente resultado (truncado):
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 ...
Recupera la URL de tu función (metadatos httpsTrigger.url
) con el siguiente comando:
FUNCTION_URL=$(gcloud functions describe secret_hello --format 'value(httpsTrigger.url)')
Ahora, llama a tu función para probar que se pueda acceder a la función con el valor de retorno esperado:
curl $FUNCTION_URL
Deberías ver el siguiente resultado:
We meet again!
Esta función hace referencia a la versión más reciente del secreto, que se configuró para contener la cadena "Vuelve a", por lo que la función está funcionando según lo esperado.
11. ¡Felicitaciones!
Aprendiste a usar la API de Secret Manager con Python.
Limpia
Para evitar que se generen cargos en tu cuenta de Google Cloud por los recursos que usaste en este instructivo, sigue estos pasos:
- En la consola de Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, selecciona el tuyo y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrarlo.
Más información
- Secret Manager: https://cloud.google.com/secret-manager/
- Python en Google Cloud: https://cloud.google.com/python/
- Bibliotecas cliente de Cloud para Python: https://googlecloudplatform.github.io/google-cloud-python/
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.