¿Has trabajado alguna vez con Google Cloud? ¿Has intentado desplegar tu aplicación desde una pipeline mediante una imagen de Docker? Esta es la situación a la que nos hemos enfrentado mi compañero Mario Pinto y un servidor, Cristian Suárez. Digo enfrentado porque hemos llegado a un punto de conflicto en el que no teníamos claro cómo hacer para inyectar el fichero de configuración de Google Cloud. Un fichero firestore.json el cual no está subido en el repositorio por motivos de seguridad.
Con esto nos vimos ante dos posibles soluciones:
Hemos optado por la segunda. Esta opción era más rápida, sencilla y no dependía de un servicio de terceros. Todo apuntaba a que era la opción correcta en este momento. Para poder implementar esto hemos tenido que modificar un poco la imagen de Docker y la pipeline. Te contamos a continuación cómo lo hemos hecho.
El siguiente fichero firestore.json
es el que queríamos copiar, te lo dejamos como ejemplo sin los valores reales:
{
"type": "service_account",
"project_id": <project_id>,
"private_key_id": <private_key_id>,
"private_key": "-----BEGIN PRIVATE KEY-----<secret>\\n-----END PRIVATE KEY-----\\n",
"client_email": "email@<project-id>.iam.gserviceaccount.com",
"client_id": <client_id>,
"auth_uri": "<https://accounts.google.com/o/oauth2/auth>",
"token_uri": "<https://oauth2.googleapis.com/token>",
"auth_provider_x509_cert_url": "<https://www.googleapis.com/oauth2/v1/certs>",
"client_x509_cert_url": "<https://www.googleapis.com/robot/v1/metadata/x509/><client_email>",
"universe_domain": "googleapis.com"
}
Como puedes ver este fichero, es lo suficientemente complejo como para que al añadirlo en una variable de entorno genere más de un problema. Para solucionar esto lo que hacemos es guardar en base64 en la variable de entorno. Para generar este contenido ejecutamos el siguiente comando:
cat credentials.json | base64
El resultado de este comando lo usaremos como valor de nuestra variable de entorno. En este caso en Github como un secret.
⚠️
OJO, este resultado lo debemos guardar como una única línea de texto. Debemos eliminar todos los saltos de línea que nos haya generado el comando.
El siguiente paso es poder leer esta variable en el propio fichero de Dockerfile. Hemos optado por hacerlo en el entrypoint de la aplicación, de esta forma el contenido del fichero no está en la imagen creada, se crea en el mismo momento que arrancamos el contenedor.
Para hacer esta lectura y transformación desde el base64 añadimos esta línea echo $CREDENTIALS_JSON| base64 -d > credendials.json
. Lo que deja el fichero de la siguiente forma:
# INSTRUCTIONS
ENV FIRESTORE_CREDENTIALS=""
## MORE INSTRUCTIONS
ENTRYPOINT ["/bin/sh", "-c", "echo $CREDENTIALS_JSON| base64 -d > credentials.json && <another instruction>"]
Esto no es todo, nos queda el último paso: leer la variable desde la pipeline. Para ello basta con añadir un parámetro en el comando de run de docker para inyectar esta variable mediante la opción --set-env-vars
, dejando la pipeline similar a lo siguiente:
name: Deploy to Google Cloud Run
on:
push:
branches: [ "main" ]
jobs:
build-test-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
## other irrelevant steps
- name: Deploy to Google Cloud Run
run: |
gcloud run deploy ${{ secrets.GCP_SERVICE_NAME }} \
#Another credentials \
--set-env-vars FIRESTORE_CREDENTIALS=${{ secrets.FIRESTORE_CREDENTIALS }}
Con esta solución podemos evitar la necesidad de dependencias externas como pueden ser algún tipo de almacenamiento como S3 o algún vault. Una solución segura y relativamente sencilla para implementar.
Tener un fichero incluido en el proyecto con todas las credenciales, tal como sugiere Google, no es solo una mala práctica, es que encima requiere de un nuevo desarrollo cuando un cambio de configuración es requerido (un nuevo commit y despliegue), esto rompe con muchas de las reglas de 12factor app.
¿Lo habías hecho así antes? ¿Crees que sería mejor hacerlo de otra forma?
¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.
Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?
Pero espera 🖐 que tenemos un conflicto interno. A nosotros las newsletter nos parecen 💩👎👹 Por eso hemos creado la LEAN LISTA, la primera lista zen, disfrutona y que suena a rock y reggaeton del sector de la programación. Todos hemos recibido newsletters por encima de nuestras posibilidades 😅 por eso este es el compromiso de la Lean Lista