Saltar al contenido principal

Deploy de cloud functions

En esta sección vamos a deployar en GCP, la cloud function desarrollada en la sección anterior
mediante gitlab-ci.

Gitlab CI​

Buildear función en local.​

npm run build

Esto genera una carpeta dist la cual contiene el artifact utilizado para deployar la función.

Nota: En el hipotetico caso que aparezca el siguiente error al buildear.

This file is being treated as an ES module because it has a '.js' file extension and '/home/julian/sils/keeper/cf/delete-infractions/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

Debem quitar la propiedad type: "module" de package.json.

Crear yml de gitlab CI​

touch .gitlab-ci.yml

En el archivo creado copiar y pegar el siguiente contenido:

image: node:20

stages:
- build

build:
stage: build
script:
- npm ci
- npm run build
- ls -la
artifacts:
paths:
- dist
expire_in: 30 mins
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
rules:
- if: ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_BRANCH == "master")

Crear runner de gitlab.​

Para que se ejecute el pipeline en gitlab es necesario registrar un runner en la instancia.

Conectarse por ssh a gitlab​

gcloud compute ssh --zone "us-central1-a" "gitlab" --project "sils-keeper-infra"

Una vez conectado necesitamos un token generado en el proyecto de gitlab, para esto necesitamos tener
el código subido a un repositorio en gitlab.sils.tech.

En la pagina principal del repositorio ingresar a Settings --> CI/CD --> Runners y buscar el panel
donde figura el registration token.

Registration token

Registrar el runner​

Ahora en la instancia de gitlab que nos conectamos anteriormente por ssh ingresamos el siguiente comando:

sudo gitlab-runner register

A continuación nos pide una serie de datos:

  • URL: https://gitlab.sils.tech/
  • El registration token que figura en el repo.
  • Una descripción del runner (puede dejarse vacio)
  • Una descripción del runner (puede dejarse vacio)
  • Tags que identifiquen al runner
  • Notas de mantenimiento
  • Executor: Elegir docker
  • Imagen de docker: ruby:2.7

Verificar los runners​

sudo gitlab-runner verifiy

Despues de ejecutar ese comando volvemos a la pantalla de Settings de gitlab y en runners deberiamos
ver el runner recien creado.

alt text

Le damos en edit y deberiamos tenerlo configurado de la siguiente manera:

alt text

Ejecutar pipeline​

A continuación ejecutamos el pipeline configurado en el yaml que subimos previamente, esto lo podemos
hacer pusheando cambios a master(o al branch origen donde esten trabajando) o directamente acceder a la
sección CI/CD --> Pipelines --> Run Pipeline.
La primera vez que se ejecuta un pipeline con un runner nuevo suele llevar un tiempo para ejecutarse, paciencia...

Al terminar el pipeline deberian tener una salida similar a esta.

$ ls -la
total 572
drwxrwxrwx 7 root root 4096 Mar 28 14:22 .
drwxrwxrwx 4 root root 4096 Mar 27 19:18 ..
-rw-rw-rw- 1 root root 14 Mar 27 19:18 .dockerignore
-rw-rw-rw- 1 root root 59 Mar 27 19:18 .eslintignore
-rw-rw-rw- 1 root root 338 Mar 27 19:18 .eslintrc
-rw-rw-rw- 1 root root 551 Mar 27 19:18 .gcloudignore
drwxrwxrwx 6 root root 4096 Mar 28 14:21 .git
-rw-rw-rw- 1 root root 214 Mar 28 14:21 .gitignore
-rw-rw-rw- 1 root root 276 Mar 27 19:18 .gitlab-ci.yml
-rw-rw-rw- 1 root root 4443 Mar 27 19:18 Jenkinsfile
-rw-rw-rw- 1 root root 172 Mar 27 19:18 babel.config.js
drwxr-xr-x 3 root root 4096 Mar 28 14:22 dist
-rw-rw-rw- 1 root root 761 Mar 27 19:18 index.js
-rw-rw-rw- 1 root root 740 Mar 27 19:18 jest.config.js
drwxr-xr-x 699 root root 20480 Mar 28 14:22 node_modules
-rw-rw-rw- 1 root root 483471 Mar 28 14:21 package-lock.json
-rw-rw-rw- 1 root root 1482 Mar 27 19:18 package.json
-rw-rw-rw- 1 root root 333 Mar 27 19:18 sonar-project.properties
drwxrwxrwx 2 root root 4096 Mar 27 19:18 src
drwxrwxrwx 2 root root 4096 Mar 27 19:18 test
Uploading artifacts for successful job
00:02
Uploading artifacts...
dist: found 9 matching artifact files and directories
Uploading artifacts as "archive" to coordinator... 201 Created id=16826 responseStatus=201 Created token=64_K5FbL
Cleaning up project directory and file based variables
00:00
Job succeeded

Crear step de deploy y environment dev​

Ahora el siguiente paso ya es crear el ambiente dev de la función y a su vez el job de
deploy de la misma.

Crear nueva rama dev​

Desde la rama master ejecutar:

git checkout -b dev
git push origin dev

Una vez pusheada la rama dev al repositorio remoto, entrar a Settings --> Repository --> Branch defaults
y en esa sección definir a la rama dev como la por defecto (No olviden guardar los cambios).
Ahora en la misma sección ir a Protected Branches y crear una regla Protected para la rama dev
en la que solo Maintainers puedan pushear a la branch y Maintainers + Developers puedan mergear.

Setear variables de entorno.​

Vamos a comenzar a generar los archivos de variables de entorno, entrar a Settings --> CI/CD --> Variables.
Presionar el boton Add variable y se abrira un modal como el siguiente.

alt text

En value copiar el service account de GCP del proyecto sils-des (Pediselos a estos).

Para la variable PROJECT_ID ingresar el proyecto de GCP correspondiente, en este caso seria sils-des.

Agregar step deploy:dev​

En el archivo .gitlab-ci.yml pegar el siguiente contenido:

image: node:20-alpine

stages:
- build
- deploy

build:dev:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist
expire_in: 30 mins
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
rules:
- if: ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "dev" || $CI_COMMIT_BRANCH == "dev")

deploy:dev:
stage: deploy
image: google/cloud-sdk:482.0.0-alpine
only:
- dev
dependencies:
- build:dev
script:
- gcloud auth activate-service-account --key-file=$SERVICE_ACCOUNT_DEV
- gcloud config set project $PROJECT_ID
environment: dev

Agregar comando de gcp para deployar la cf.​

Si los jobs que subimos anteriormente pasaron ok, ahora debemos agregar el ultimo comando del job que es el deploy de la función en Google Cloud.

gcloud functions deploy myFunction --timeout 10s --memory 128MB --runtime nodejs18 --trigger-http --project ${GCP_PROJECT} --vpc-connector projects/${GCP_PROJECT}/locations/${GCP_ZONE}/connectors/${VPC_CONNECTOR} --env-vars-file ${ENV_FILE} --source=dist/

Necesitamos agregar las siguientes variables en el repo de gitlab(dejamos las de sils-des como ejemplo):

  • GCP_PROJECT=sils-des
  • GCP_ZONE=us-central1
  • VPC_CONNECTOR=sils-des-connector
  • ENV_FILE ---> Archivo .env necesario para el funcionamiento de la cf.

Si el deploy en gitlab pasa con exito deberian ver la función en estado activo en la consola de GCP

Troubleshooting​

The npm ci command can only install with an existing package-lock.json​

En el caso de tener un error referido a que falta el package-lock.json, el problema está
en que el package-lock.json está siendo ignorado por el .gitignore.