En este tutorial se explica cómo crear una aplicación segura de dos servicios que se ejecute en Cloud Run. Esta aplicación es un editor de Markdown que incluye un servicio público de frontend que cualquier persona puede usar para escribir texto en Markdown y un servicio privado de backend que convierte texto en Markdown a HTML.
El servicio de backend es privado y utiliza la función integrada de Cloud Run autenticación de servicio a servicio basada en IAM, que limita quién puede llamar al servicio. Ambos servicios se han creado siguiendo el principio de mínimos accesos, de modo que no tienen acceso al resto de Google Cloud , salvo cuando sea necesario.
Limitaciones u objetivos no incluidos en este tutorial
En este tutorial no se muestra la autenticación de usuarios finales, que usa Identity Platform o Firebase Authentication para generar tokens de ID de usuario y verificar manualmente las identidades de los usuarios. Para obtener más información sobre la autenticación de usuarios finales, consulta el tutorial de Cloud Run sobre la autenticación de usuarios finales.
En este tutorial no se muestra cómo combinar la autenticación basada en IAM y los métodos de token de ID, ya que no se admite.
Configurar los valores predeterminados de gcloud
Para configurar gcloud con los valores predeterminados de tu servicio de Cloud Run, sigue estos pasos:
Configura tu proyecto predeterminado:
gcloud config set project PROJECT_ID
Sustituye PROJECT_ID por el nombre del proyecto que has creado para este tutorial.
Configura gcloud para la región que hayas elegido:
gcloud config set run/region REGION
Sustituye REGION por la región de Cloud Run compatible que quieras.
Ubicaciones de Cloud Run
Cloud Run es regional, lo que significa que la infraestructura que ejecuta tus servicios de Cloud Run se encuentra en una región específica y Google la gestiona para que esté disponible de forma redundante en todas las zonas de esa región.
Cumplir tus requisitos de latencia, disponibilidad o durabilidad son factores primordiales para seleccionar la región en la que se ejecutan tus servicios de Cloud Run.
Por lo general, puedes seleccionar la región más cercana a tus usuarios, pero debes tener en cuenta la ubicación de los otros Google Cloudproductos que utiliza tu servicio de Cloud Run.
Usar Google Cloud productos juntos en varias ubicaciones puede afectar a la latencia y al coste de tu servicio.
Cloud Run está disponible en las siguientes regiones:
Con sujeción a los precios del nivel 1
asia-east1
(Taiwán)asia-northeast1
(Tokio)asia-northeast2
(Osaka)asia-south1
(Bombay, la India)europe-north1
(Finlandia)CO2 bajo
europe-north2
(Estocolmo)CO2 bajo
europe-southwest1
(Madrid)CO2 bajo
europe-west1
(Bélgica)CO2 bajo
europe-west4
(Países Bajos)CO2 bajo
europe-west8
(Milán)europe-west9
(París)CO2 bajo
me-west1
(Tel Aviv)northamerica-south1
(México)us-central1
(Iowa)CO2 bajo
us-east1
(Carolina del Sur)us-east4
(Norte de Virginia)us-east5
(Columbus)us-south1
(Dallas)CO2 bajo
us-west1
(Oregón)CO2 bajo
Con sujeción a los precios del nivel 2
africa-south1
(Johannesburgo)asia-east2
(Hong Kong)asia-northeast3
(Seúl, Corea del Sur)asia-southeast1
(Singapur)asia-southeast2
(Yakarta)asia-south2
(Delhi, la India)australia-southeast1
(Sídney)australia-southeast2
(Melbourne)europe-central2
Varsovia (Polonia)europe-west10
(Berlín)europe-west12
(Turín)europe-west2
(Londres, Reino Unido)CO2 bajo
europe-west3
(Fráncfort, Alemania)europe-west6
(Zúrich, Suiza)Bajas emisiones de CO2
me-central1
(Doha)me-central2
(Dammam)northamerica-northeast1
(Montreal)CO2 bajo
northamerica-northeast2
(Toronto)CO2 bajo
southamerica-east1
(São Paulo, Brasil)CO2 bajo
southamerica-west1
(Santiago, Chile)CO2 bajo
us-west2
(Los Ángeles)us-west3
(Salt Lake City)us-west4
(Las Vegas)
Si ya has creado un servicio de Cloud Run, puedes ver la región en el panel de control de Cloud Run de la Google Cloud consola.
Obtener el código de ejemplo
Para obtener el código de muestra que vas a usar, sigue estos pasos:
Clona el repositorio de la aplicación de ejemplo en tu Cloud Shell o en tu máquina local:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Python
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Go
git clone https://github.com/GoogleCloudPlatform/golang-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Java
git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
C#
git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Cambia al directorio que contiene el código de ejemplo de Cloud Run:
Node.js
cd nodejs-docs-samples/run/markdown-preview/
Python
cd python-docs-samples/run/markdown-preview/
Go
cd golang-samples/run/markdown-preview/
Java
cd java-docs-samples/run/markdown-preview/
C#
cd dotnet-docs-samples/run/markdown-preview/
Revisar el servicio de renderización de Markdown privado
Desde el punto de vista del frontend, hay una especificación de API sencilla para el servicio de Markdown:
- Un endpoint en
/
- Espera solicitudes POST
- El cuerpo de la solicitud POST es texto en formato Markdown.
Puede revisar todo el código para comprobar si hay algún problema de seguridad o simplemente para obtener más información sobre él explorando el directorio ./renderer/
. Ten en cuenta que en el tutorial no se explica el código de transformación de Markdown.
Envío del servicio de renderizado de Markdown privado
Para enviar tu código, compílalo con Cloud Build, súbelo a Artifact Registry y despliégalo en Cloud Run:
Cambia al directorio
renderer
:Node.js
cd renderer/
Python
cd renderer/
Go
cd renderer/
Java
cd renderer/
C#
cd Samples.Run.MarkdownPreview.Renderer/
Crea un Artifact Registry:
gcloud artifacts repositories create REPOSITORY \ --repository-format docker \ --location REGION
Sustituye:
- REPOSITORY con un nombre único para el repositorio. Los nombres de los repositorios deben ser únicos en cada ubicación de repositorio de un proyecto.
- REGION con la Google Cloud región que se va a usar en el repositorio de Artifact Registry.
Ejecuta el siguiente comando para compilar el contenedor y publicarlo en Artifact Registry.
Node.js
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
renderer
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede reutilizar si se quiere.
Python
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
renderer
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede reutilizar si se quiere.
Go
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
renderer
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede volver a usar si quieres.
Java
En este ejemplo se usa Jib para crear imágenes de Docker con herramientas comunes de Java. Jib optimiza las compilaciones de contenedores sin necesidad de usar un Dockerfile ni de tener Docker instalado. Más información sobre cómo crear contenedores Java con Jib
Usa el asistente de credenciales de gcloud para autorizar a Docker a enviar contenido a tu Artifact Registry.
gcloud auth configure-docker
Usa el complemento Jib Maven para compilar y enviar el contenedor a Artifact Registry.
mvn compile jib:build -Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
renderer
es el nombre que quieres dar a tu servicio.Si todo va bien, verás el mensaje BUILD SUCCESS. La imagen se almacena en Artifact Registry y se puede volver a usar si se quiere.
C#
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
renderer
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede volver a usar si quieres.
Implementar como servicio privado con acceso restringido.
Cloud Run ofrece funciones de control de acceso y de identidad de servicio listas para usar. El control de acceso proporciona una capa de autenticación que impide que los usuarios y otros servicios invoquen el servicio. La identidad de servicio permite restringir el acceso de tu servicio a otros recursosGoogle Cloud creando una cuenta de servicio específica con permisos limitados.
Crea una cuenta de servicio que actúe como "identidad de proceso" del servicio de renderización. De forma predeterminada, no tiene más privilegios que la pertenencia al proyecto.
Línea de comandos
gcloud iam service-accounts create renderer-identity
Terraform
Para saber cómo aplicar o quitar una configuración de Terraform, consulta Comandos básicos de Terraform.
El servicio de renderización de Markdown no se integra directamente con ningún otro elemento de Google Cloud. No necesita ningún otro permiso.
Despliega con la cuenta de servicio
renderer-identity
y deniega el acceso no autenticado.Línea de comandos
gcloud run deploy renderer \ --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer \ --service-account renderer-identity \ --no-allow-unauthenticated
Cloud Run puede usar el nombre abreviado de la cuenta de servicio en lugar de la dirección de correo completa si la cuenta de servicio forma parte del mismo proyecto.
Terraform
Para saber cómo aplicar o quitar una configuración de Terraform, consulta Comandos básicos de Terraform.
Probar el servicio privado de renderización de Markdown
Los servicios privados no se pueden cargar directamente en un navegador web. En su lugar, usa curl
o una herramienta de CLI de solicitudes HTTP similar que permita insertar un encabezado Authorization
.
Para enviar texto en negrita al servicio y ver cómo convierte los asteriscos de Markdown en etiquetas <strong>
de HTML, sigue estos pasos:
Obtén la URL del resultado de la implementación.
Usa
gcloud
para obtener un token de identidad especial solo para desarrollo con fines de autenticación:TOKEN=$(gcloud auth print-identity-token)
Crea una solicitud curl que transfiera el texto sin formato de Markdown como parámetro de cadena de consulta con escape de URL:
curl -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: text/plain' \ -d '**Hello Bold Text**' \ SERVICE_URL
Sustituye SERVICE_URL por la URL que se te proporcione después de implementar el servicio de renderización de Markdown.
La respuesta debe ser un fragmento HTML:
<strong>Hello Bold Text</strong>
Revisar la integración entre los servicios de edición y renderización
El servicio de editor proporciona una interfaz de usuario sencilla para introducir texto y un espacio para ver la vista previa del HTML. Antes de continuar, revisa el código que has obtenido anteriormente abriendo el directorio ./editor/
.
A continuación, consulta las siguientes secciones de código que integran de forma segura los dos servicios.
Node.js
El módulo render.js
crea solicitudes autenticadas al servicio de renderizador privado. Usa el servidor de metadatos Google Cloud en el entorno de Cloud Run para crear un token de identidad y añadirlo a la solicitud HTTP como parte de un encabezado Authorization
.
En otros entornos, render.js
usa las credenciales predeterminadas de la aplicación para solicitar un token a los servidores de Google.
Analiza el Markdown de JSON y envíalo al servicio Renderer para que se transforme en HTML.
Python
El método new_request
crea solicitudes autenticadas a servicios privados.
Usa el servidor de metadatos en el entorno de Cloud Run para crear un token de identidad y añadirlo a la solicitud HTTP como parte de un encabezado Authorization
. Google Cloud
En otros entornos, new_request
solicita un token de identidad a los servidores de Google autenticándose con credenciales predeterminadas de la aplicación.
Analiza el Markdown de JSON y envíalo al servicio Renderer para que se transforme en HTML.
Go
RenderService
crea solicitudes autenticadas a servicios privados. Utiliza el servidor de metadatos Google Cloud en el entorno de Cloud Run para crear un token de identidad y añadirlo a la solicitud HTTP como parte de un encabezado Authorization
.
En otros entornos, RenderService
solicita un token de identidad a los servidores de Google autenticándose con credenciales predeterminadas de la aplicación.
La solicitud se envía al servicio Renderer después de añadir el texto de Markdown que se va a transformar en HTML. Los errores de respuesta se gestionan para diferenciar los problemas de comunicación de la funcionalidad de renderización.
Java
makeAuthenticatedRequest
crea solicitudes autenticadas a servicios privados. Usa el Google Cloud servidor de metadatos del entorno de Cloud Run para crear un token de identidad y añadirlo a la solicitud HTTP como parte de un encabezado Authorization
.
En otros entornos, makeAuthenticatedRequest
solicita un token de identidad
a los servidores de Google autenticándose con las credenciales de aplicación predeterminadas.
Analiza el Markdown de JSON y envíalo al servicio Renderer para que se transforme en HTML.
C#
GetAuthenticatedPostResponse
crea solicitudes autenticadas a servicios privados. Usa el Google Cloud servidor de metadatos del entorno de Cloud Run para crear un token de identidad y añadirlo a la solicitud HTTP como parte de un encabezado Authorization
.
En otros entornos, GetAuthenticatedPostResponse
solicita un token de identidad
a los servidores de Google autenticándose con las credenciales de aplicación predeterminadas.
Analiza el Markdown de JSON y envíalo al servicio Renderer para que se transforme en HTML.
Lanzamiento del servicio de editor público
Para compilar e implementar tu código, sigue estos pasos:
Cambia al directorio
editor
:Node.js
cd ../editor
Python
cd ../editor
Go
cd ../editor
Java
cd ../editor
C#
cd ../Samples.Run.MarkdownPreview.Editor/
Ejecuta el siguiente comando para compilar el contenedor y publicarlo en Artifact Registry.
Node.js
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
editor
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Container Registry y se puede volver a usar si quieres.
Python
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
editor
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede volver a usar si quieres.
Go
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
editor
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede volver a usar si quieres.
Java
En este ejemplo se usa Jib para crear imágenes de Docker con herramientas comunes de Java. Jib optimiza las compilaciones de contenedores sin necesidad de usar un Dockerfile ni de tener Docker instalado. Más información sobre cómo crear contenedores Java con Jibmvn compile jib:build -Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
editor
es el nombre que quieres dar a tu servicio.Si todo va bien, verás el mensaje BUILD SUCCESS. La imagen se almacena en Artifact Registry y se puede reutilizar si se quiere.
C#
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
editor
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Artifact Registry y se puede volver a usar si quieres.
Implementar como servicio privado con acceso especial al servicio de renderización.
Crea una cuenta de servicio que actúe como "identidad de cálculo" del servicio privado. De forma predeterminada, no tiene más privilegios que la pertenencia al proyecto.
Línea de comandos
gcloud iam service-accounts create editor-identity
Terraform
Para saber cómo aplicar o quitar una configuración de Terraform, consulta Comandos básicos de Terraform.
El servicio Editor no necesita interactuar con nada más en Google Cloud que con el servicio de renderización de Markdown.
Concede acceso a la identidad de cálculo
editor-identity
para invocar el servicio de renderización de Markdown. Cualquier servicio que utilice esto como identidad de cálculo tendrá este privilegio.Línea de comandos
gcloud run services add-iam-policy-binding renderer \ --member serviceAccount:editor-identity@PROJECT_ID.iam.gserviceaccount.com \ --role roles/run.invoker
Terraform
Para saber cómo aplicar o quitar una configuración de Terraform, consulta Comandos básicos de Terraform.
Como se le ha asignado el rol de invocador en el contexto del servicio de renderización, este es el único servicio privado de Cloud Run que puede invocar el editor.
Implementa con la cuenta de servicio
editor-identity
y permite el acceso público sin autenticación.Línea de comandos
gcloud run deploy editor --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor \ --service-account editor-identity \ --set-env-vars EDITOR_UPSTREAM_RENDER_URL=SERVICE_URL \ --allow-unauthenticated
Sustituye:
- PROJECT_ID con el ID de tu proyecto
- SERVICE_URL con la URL proporcionada después de implementar el servicio de renderización de Markdown.
Terraform
Para saber cómo aplicar o quitar una configuración de Terraform, consulta Comandos básicos de Terraform.
Implementa el servicio del editor:
Concede permiso a
allUsers
para invocar el servicio:
Información sobre el tráfico HTTPS
Para renderizar el markdown con estos servicios, se realizan tres solicitudes HTTP.
editor-identity
invoca el servicio
de renderización. Tanto editor-identity
como renderer-identity
tienen permisos limitados, por lo que cualquier vulnerabilidad de seguridad o inyección de código tiene un acceso limitado a otros recursos de Google Cloud .
Probar la función
Para probar la aplicación completa de dos servicios, haz lo siguiente:
En tu navegador, ve a la URL que se ha proporcionado en el paso de implementación anterior.
Prueba a editar el texto de Markdown de la izquierda y haz clic en el botón para ver la vista previa a la derecha.
Debería tener este aspecto:
Si decides seguir desarrollando estos servicios, recuerda que tienen acceso restringido a la gestión de identidades y accesos (IAM) al resto de Google Cloud y que tendrás que asignarles roles de IAM adicionales para acceder a muchos otros servicios.