Lab práctico · Semana 1: Fundamentos de Google Cloud: jerarquía, facturación, IAM y herramientas

gcloud, APIs, cuentas de servicio e impersonación

⏱ 60-90 minDificultad: básicaApartados: 3.15.2

Qué vas a construir

Vas a trabajar como lo haría un arquitecto desde el primer día: una configuración de gcloud para el curso, APIs habilitadas a mano, una cuenta de servicio con un rol mínimo, una prueba real de mínimo privilegio suplantando (impersonando) esa cuenta y la lectura de los logs de auditoría que dejan tus acciones.

flowchart LR
  YO["Tú: Owner del proyecto"] -->|"roles/iam.serviceAccountTokenCreator sobre la cuenta"| SA["Cuenta de servicio lector-sa"]
  SA -->|"roles/compute.viewer en el proyecto"| P["Proyecto pca-lab-02"]
  P --> LOG["Cloud Audit Logs"]

Antes de empezar

  • Lab 01 hecho: cuenta de prueba activa y presupuesto creado.
  • Abre Cloud Shell. Todo se hace ahí.

Variables que usarás:

export PROJECT_ID="pca-lab-02-$RANDOM"
export REGION="europe-southwest1"
export ZONE="europe-southwest1-a"
export BILLING_ID="$(gcloud billing accounts list --format='value(ACCOUNT_ID)' --limit=1)"
echo "$PROJECT_ID $BILLING_ID"

Si Cloud Shell se reinicia, las variables se pierden: vuelve a exportarlas (con el mismo PROJECT_ID, no uno nuevo).

Paso 1: Crea el proyecto y una configuración de gcloud

Qué y por qué: las configuraciones con nombre guardan proyecto, región y zona. Así no repites flags y cambias de contexto con un comando, algo muy útil cuando trabajas con varios proyectos o clientes.

gcloud projects create "$PROJECT_ID" --name="pca-lab-02"
gcloud billing projects link "$PROJECT_ID" --billing-account="$BILLING_ID"

gcloud config configurations create curso-pca
gcloud config set account "$(gcloud auth list --filter=status:ACTIVE --format='value(account)')"
gcloud config set project "$PROJECT_ID"
gcloud config set compute/region "$REGION"
gcloud config set compute/zone "$ZONE"

gcloud config configurations list
gcloud config list

Verás curso-pca marcada como activa. Para volver a la anterior: gcloud config configurations activate default.

Paso 2: Habilita APIs

Qué y por qué: cada servicio tiene su API y hay que habilitarla en cada proyecto. Habilitarla no cuesta nada.

gcloud services list --enabled
gcloud compute instances list

El segundo comando probablemente falle o te pregunte si quieres habilitar compute.googleapis.com: es el error típico de «API not enabled». Contesta N y habilítala tú:

gcloud services enable compute.googleapis.com iam.googleapis.com iamcredentials.googleapis.com
gcloud services list --enabled --filter="name:(compute OR iam)"
gcloud compute instances list

Ahora el listado funciona (vacío). iamcredentials.googleapis.com es la API que emite las credenciales de corta duración de la impersonación.

Por consola: APIs y servicios → Biblioteca, busca «Compute Engine API» y pulsa Habilitar.

Paso 3: Crea una cuenta de servicio con un rol mínimo

Qué y por qué: una cuenta de servicio por función, con el rol predefinido más pequeño que sirva. Aquí simulas una aplicación de inventario que solo necesita leer recursos de Compute Engine.

gcloud iam service-accounts create lector-sa \
  --display-name="Lector de inventario de Compute"
export SA="lector-sa@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member="serviceAccount:${SA}" \
  --role="roles/compute.viewer" \
  --condition=None

Fíjate: no creas ninguna clave JSON. No hace falta.

Paso 4: Permítete suplantar la cuenta de servicio

Qué y por qué: para probar con los permisos exactos de la aplicación sin descargar claves, te concedes roles/iam.serviceAccountTokenCreator sobre la cuenta de servicio (no sobre el proyecto: mínimo privilegio también para ti).

export YO="$(gcloud config get-value account)"
gcloud iam service-accounts add-iam-policy-binding "$SA" \
  --member="user:${YO}" \
  --role="roles/iam.serviceAccountTokenCreator"

gcloud iam service-accounts get-iam-policy "$SA"

Los cambios de IAM pueden tardar unos minutos en propagarse. Si el paso siguiente falla con un error de permisos al generar el token, espera un par de minutos y repite.

Paso 5: Prueba el mínimo privilegio

Qué y por qué: compruebas que la cuenta puede hacer lo que necesita y no puede hacer nada más.

Lo que sí debe poder hacer (leer):

gcloud compute zones list --filter="region:${REGION}" \
  --impersonate-service-account="$SA"
gcloud compute instances list --impersonate-service-account="$SA"

Verás un aviso de que estás usando impersonación y los resultados.

Lo que no debe poder hacer (crear recursos o leer otros servicios):

gcloud compute networks create red-prohibida --subnet-mode=auto \
  --impersonate-service-account="$SA"

gcloud storage buckets list --impersonate-service-account="$SA"

Ambos deben fallar con un error 403 / PERMISSION_DENIED que indica el permiso que falta (por ejemplo, compute.networks.create). Es exactamente lo que quieres ver.

Alternativa: activar la impersonación para toda la configuración y desactivarla después.

gcloud config set auth/impersonate_service_account "$SA"
gcloud compute instances list
gcloud config unset auth/impersonate_service_account

Paso 6: Mira los logs de auditoría

Qué y por qué: los Admin Activity audit logs registran siempre, gratis y durante 400 días, quién cambió qué configuración. Es tu evidencia en una auditoría.

Por consola: Logging → Explorador de registros y pega esta consulta:

logName:"cloudaudit.googleapis.com%2Factivity"
protoPayload.methodName=("google.iam.admin.v1.CreateServiceAccount" OR "SetIamPolicy")

Abre una entrada y localiza protoPayload.authenticationInfo.principalEmail (quién), protoPayload.methodName (qué) y resource (sobre qué).

Por gcloud:

gcloud logging read \
  'logName:"cloudaudit.googleapis.com%2Factivity" AND protoPayload.methodName:"SetIamPolicy"' \
  --freshness=1h --limit=5 \
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.methodName)"

Explora también las entradas en las que aparece la cuenta de servicio:

gcloud logging read "protoPayload.authenticationInfo.principalEmail=\"${SA}\"" \
  --freshness=1h --limit=10 \
  --format="table(timestamp, logName, protoPayload.methodName, protoPayload.status.code)"

Las lecturas que hiciste con la cuenta no aparecerán como Admin Activity, porque no modifican nada; quedarían en los Data Access audit logs, que están desactivados por defecto (salvo BigQuery). Si ves alguna entrada con status.code distinto de cero, corresponde a una operación que no se completó. Cuando un principal actúa suplantando una cuenta, los logs recogen ambas identidades en authenticationInfo.

Paso 7 (opcional): Un rol personalizado

Qué y por qué: cuando ningún predefinido encaja, defines tú los permisos. Se crean en proyecto u organización, nunca en carpeta.

gcloud iam roles create lectorInstancias --project="$PROJECT_ID" \
  --title="Lector de instancias" \
  --permissions="compute.instances.list,compute.instances.get,compute.zones.list" \
  --stage=GA
gcloud iam roles describe lectorInstancias --project="$PROJECT_ID"

Comprueba que funciona

  • gcloud config configurations list muestra curso-pca activa con tu proyecto.
  • Con --impersonate-service-account puedes listar zonas e instancias.
  • Crear una red o listar buckets con la cuenta falla con PERMISSION_DENIED.
  • En el explorador de registros ves las entradas SetIamPolicy hechas por tu usuario.

Limpieza

Borrar el proyecto elimina la cuenta de servicio, los permisos y el rol personalizado:

gcloud config configurations activate default
gcloud projects delete "$PROJECT_ID"
gcloud config configurations delete curso-pca

Preguntas para pensar como arquitecto

1. Un desarrollador pide una clave JSON de la cuenta de servicio de producción «para reproducir un fallo». ¿Qué le propones?

Concederle, de forma temporal (con una condición IAM de caducidad si es posible), roles/iam.serviceAccountTokenCreator sobre esa cuenta, o mejor sobre una cuenta equivalente de un entorno de pruebas, y que use --impersonate-service-account. Las credenciales son de corta duración, no se pueden filtrar como un fichero y los logs registran quién suplantó a quién.

2. ¿Qué diferencia hay entre conceder a alguien roles/iam.serviceAccountUser y roles/iam.serviceAccountTokenCreator sobre una cuenta de servicio?

serviceAccountUser le permite asignar la cuenta a recursos (crear una VM o un servicio de Cloud Run que se ejecute como ella). serviceAccountTokenCreator le permite obtener tokens de la cuenta y actuar directamente como ella. Ambos son sensibles: quien los tiene puede usar todos los permisos de la cuenta.

3. Un auditor necesita saber quién leyó ciertos datos de Cloud Storage el mes pasado, pero no hay registros. ¿Por qué y cómo lo evitas?

Las lecturas de datos se registran en los Data Access audit logs, que están desactivados por defecto para la mayoría de servicios (BigQuery es la excepción). Hay que activarlos explícitamente (idealmente a nivel de organización o carpeta para los servicios con datos sensibles) y definir su retención, teniendo en cuenta que generan volumen y coste.

4. ¿Por qué usar configuraciones de gcloud en lugar de pasar siempre –project?

Reducen errores (ejecutar un comando en el proyecto equivocado) y agilizan el cambio de contexto entre proyectos, cuentas o clientes. Aun así, en scripts y automatizaciones es buena práctica indicar el proyecto de forma explícita.


Volver al módulo