Cómo automatizar un script de R en Google Cloud

Share on linkedin
Share on twitter
Share on email

Automatizar un script te abre mil puertas. En este post expliqué cómo programar un script de R en tu ordenador. Eso está muy bien y es muy útil, pero tiene limitaciones, como por ejemplo tener el ordenador encendido para que se ejecute el script.

Por suerte, disponemos servicios en la nube que nos permiten automatizar el script en la nube, de tal manera que nos despreocupemos por completo de la automatización. Al fin y al cabo, automatizar va de eso, ¿no?

Por eso, hoy vamos a ver cómo puedes automatizar tu script de R en Google Cloud. ¿Te suena bien? ¡Pues vamos a ello!

Comenzando en Google Cloud

Antes de nada, debemos tener una cuenta en Google Cloud. Si no la tienes, puedes crearla aquí. Cuando lo hagas verás que te pide que introduzcas una tarjeta. Dicen que no cobran sin tu permiso, pero por si no te fias, te recomiendo crearte una tarjeta virtual con un saldo bajo (debe ser de al menos 1€) para así asegurarte que no hay problema.

Para poder automatizar nuestros scripts de R en Google Cloud usaremos tres servicios: Cloud Build y Cloud Schedule y App Engine.

Cloud Build + App Engine: trabajando con Docker y yaml

Cloud Build te permitirá subir tu código en R mediante un fichero yaml, mientras que App Engine es la herramienta que se encarga de ejecutar dicho código. Un fichero yaml es un texto con una secuencia de pasos que el servidor de Google deberá ejecutar. Generalmente estos ficheros se crean mediante imágenes Docker.

Un Docker es un contenedor que puede ser interpretados por cualquier servidor con docker, independientemente de su sistema operativo. Vamos, que un Docker que contenga un script de R, este script podrá ser ejecutado independientemente de que esté R instalado en el servidor. Si esto te suena bien, pero no sabes cómo hacerlo, no te preocupes, lo explico más adelante.

Como todo en la nube pagas por el uso. Por suerte, Google Cloud usado a pequeña escala es muy barato: un minuto de compilación del build cuesta 0,003 USD siendo los 120 primeros minutos de cada día gratuitos. Vamos, a menos que quieras automatizar un script muy largo o que el script se ejecute cada minuto, seguramente no tengas casi ni que pagar. En cualquier caso, aquí puedes ver los precios.

Cloud Scheduler: automatizando el Docker

Mediante Cloud Scheduler podremos automatizar la ejecución de nuestra imagen de Cloud Build. Básicamente con este servicio creas un cronjob pero, en vez de en tu mac, en el servidor. Por si eso de cronjob te suena a chino… la sección de Mac de este post te aclarará las dudas.

En cuanto a precios, tampoco es nada caro y seguramente el servicio gratuito te sirva. Y es que en Cloud Scheduler cuesta 0,1USD por tarea, siendo las 3 primeras tareas de tu cuenta gratuitas. Ojo porque esto tiene dos matices que son importantes:

  • Se cobra por tarea, no por ejecución. Vamos, que si yo creo una tarea que se ejecuta cada día del mes, la tarea me costará 0,10USD, no 3USD.
  • Las tareas gratuitas son a nivel de cuenta, no a nivel de proyecto. Si tienes distintos proyectos que usen Cloud Scheduler y en total suman más de 3 tareas, te cobrarán 0,10USD por cada tarea a partir de la tercerta.

En cualquier caso, te dejo la página de precios.

Ahora que ya sabemos qué herramientas vamos a usar y qué hacen cada… ¡vamos con ello!

Cómo automatizar un script de R en Google Cloud

Paso 1. Habilitar las APIs de Cloud Build y Cloud Scheduler

Lo primero que debemos hacer es habilitar las APIs tanto de Cloud Build como de Cloud Scheduler (App Engine viene activado por defecto). Para ello, debemos seguir los siguientes pasos:

  1. Ir a la librería de APIs,ya sea mediante el enlace o dentro de “Apis y Servicios” haciendo clic en “Biblioteca”.
  2. Buscamos la API que queramos activar, ya sea la de Cloud Build o Cloud Scheduler.
  3. Accedemos y habilitamos la API haciendo clic en “Habilitar”.
Cómo habilitar una API en Google Cloud

Una vez habilitadas las dos APIs nos aparecerán en el menú lateral. Las podremos fijar para que sea más sencillo acceder a ellas.

Paso 2. Descargar el auth de los servicios y datos necesarios

Auth de los servicios

Si quieres utilizar estos servicios desde R, deberemos indicar a R que somos poseedores de esa cuenta de Google Cloud. Para ello, deberemos crear y descargar unas credenciales en formato JSON que el paquete googleAuthR utilizará para realizar todas las operaciones (subir imagen, crear Task, etc.).

Por otro lado, para crear estas credenciales, debemos ir a la página de claves de cuentas de servicio de Google Cloud. Una vez ahí realizamos lo siguiente:

  1. Hacemos clic sobre “Nueva cuenta de servicio”, si es que no tenemos una creada.
  2. Le asignamos un nombre. Esto nos generará nuestro ID, por lo que te recomiendo que te sirva para identificar en qué estás usándolo.
  3. Asignamos los roles. Los roles necesarios son los siguientes: Cuenta de servicio de versiones de Cloud, Administrador de Cloud Scheduler, Usuario de cuenta de servicio, Administrador de Cloud Run, Administrador de Storage. Es importante asegurarse de que tiene todos los roles, ya que sino, no funcionará.

Una vez creemos el auth, se guardará automáticamente un fichero json en el ordenador. Deberemos llevarlo a la ruta de nuestro proyecto.

Cómo crear una cuenta de servicio en Google Cloud

Resto de variables

Además de descargar el fihero json, debemos incluir ciertas variables en un fichero .Renviron, de tal manera que R pueda acceder a ellas sin ser “expuesto” en el código. Dichas variables son:

  • Id del proyecto: lo encuentras al hacer clic sobre el nombre del proyecto. Aparecerá una ventana con el id de producto a la derecha.
  • Region: localización donde quieres que se suba el cloud buil. Debe coincidir con la región en la que configures App Engine. En mi caso, al estar en Europa uso europe-west1.
  • Correo electrónico de cuenta del servicio de Cloud Build: este correo lo podrás encontrar en el la página de configuración de Cloud Build.
  • Auth: ruta del fichero que nos hemos descargado en el paso anterior.
GCE_AUTH_FILE="ruta_fichero_auth.json"
GCE_DEFAULT_PROJECT_ID="nombre_proyecto"
GCS_DEFAULT_BUCKET="my-bucket"
CR_REGION="europe-west1"
CR_BUILD_EMAIL=cloudrunner@nombre_servicio.iam.gserviceaccount.com

Paso 3: crea y subir una imagen Docker a Cloud Build

Para realizar todo este proceso usaremos dos paquetes. El paquete googleCloudRunner nos permitirá interactuar con Cloud Build y Cloud Scheduler y, además, nos permitirá crear el archivo yaml. Por otro lado, el paquete googleAuthR nos permitirá autentificarnos en Google Cloud. Ambos paquetes están desarrollados por Markd Edmonson.

Nota: la instalación de googleCloudRunneros recomiendo la hagáis desde Github para aseguraros que tenéis la última versión (la versión CRAN está un poco desfasada).

#remotes::install_github("MarkEdmondson1234/googleCloudRunner")
#install.packages("googleAuthR")
library(googleCloudRunner)
library(googleAuthR)

Una vez hayamos cargado las librerías, tendremos que autentificarnos en Google Cloud. Para eso, pasaremos el auth en formato JSON que nos hemos descargado en el paso 2 a la función gar_auth_service().

gar_auth_service("clave.json")

Una vez hecho esto, crearemos el objeto yaml. Básicamente, este objeto es el que indica a Cloud Build qué es lo que tiene que hacer. El objeto yaml no dejan de ser secuencias que Cloud Build sigue. Por eso, para crearlo podremos pasar distintos pasos que deberá realizar.

En nuestro caso usaremos un paso: cr_buildstep_r. Esta función nos permitirá crear el objeto yaml a partir de un fichero R. Si el fichero en local, hay que fijar el parámetro r_source en local.

Sin embargo, hay muchas otras funciones, como cr_buildstep_docker, que permite crear un yaml directamente desde un Docker o cr_buildstep, que te permite crear tu propio paso personalizado.

Una vez tengamos nuestro fichero yaml, lo podemos guardar en local con la función cr_build_write(). De esta forma podremos ir haciendo un control de versiones de nuestros deployments.

my_yaml <- cr_build_yaml(
  steps = c(
    cr_buildstep_r("Automatizar.R",r_source = "local")
  )
)
cr_build_write(my_yaml, file = "cloudbuild.yaml")
## i 2020-05-03 18:04:02 > Writing to  cloudbuild.yaml
## NULL

Por último, debemos subir el fichero yaml a Cloud Build. Al habernos autentificado no requerirá que le pasemos nada. Cuando se suba, podremos comprobar el estado del Cloud Build en la sección de historial de Cloud Build.

Sin embargo, si será necesario que tengamos activado App Engine. Es obligatorio que la ubicación de App Engine sea la misma que donde subamos nuestoro fichero a Cloud Build, ya que la ubicación de App Engnine no se puede cambiar. Por eso, si estáis en Europa, como he comentado antes, os recomiendo fijar la localización en europe-west1.

Fijar la ubicación de App Engine

Fijar la ubicación de App Engine

Una vez hayamos configurado App Engine y Cloud Build, podremos subir nuestro objeto sin probelma. Para ello, usaremos la función cr_build() donde indicaremos el yaml que queremos montar. En mi caso, el yaml que he guardado en local.

itworks <- cr_build("cloudbuild.yaml", launch_browser = FALSE)
## i 2020-05-03 18:04:04 > Cloud Build started - logs: 
##  https://console.cloud.google.com/cloud-build/builds/a74e1552-b075-493f-a08d-15c9f02a625d?project=764933295953

Si la subida ha sido correcta, veremos como todo aparece con checks verdes. Si, por el contrario, ha habido algún problema, saldrá una cruz roja en el paso que haya fallado. Los errores pueden ser diversos, por lo que recomiendo revisar los logs (consola de la derecha) y revisar cuál ha sido el error para poder debugear.

En cualquier caso, si nuestro yaml tiene varios pasos (en mi caso solo tiene uno), a la izquierda aparecerá en rojo el paso que no ha funcionado. Este paso se corresponde con el paso del cr_buildstep, lo que nos facilitará el debugging.

Ejemplo de una subida correcta a Cloud Build

Ejemplo de una subida correcta a Cloud Build

Paso 4: Automatizar Cloud Build con Cloud Scheduler

Ya tenemos nuestro Cloud Buil funcionando. ¡Genial! Ahora solo toca automatizar su ejecución. Para ello, usaremos la función cr_schedule().

En esta función debemos indicar el nombre de la tarea y cada cuánto se ejecuta. Este último punto es muy importante, ya que la frequencia se indica con el formato string cron de Unix, que no es muy intuitivo.

La frequencia la indicaremos mediante 5 parámetros diferentes, separados por un espacio y que se refieren a lo siguiente: minuto, hora, día del mes, mes, día de la semana. Todos ellos se indican de forma numérica, por lo que tienen un valor mínimo y máximo. Lógicamente, el mes 13 no existe, por lo que el mes solo puede ir de 1 a 12. Lo mismo con los días de la semana que irá de 1 a 7, etc. Además, usaremos el símbolo * si queremos indicar que ese campo no se considere.

Vamos, que si queremos ejecutar una tarea todos los lunes a las 10:30 de la mañana el comando será 30 10 * * 1. Si por el contrario queremos ejecutarlo el día 28 de cada mes sera: 30 10 28 * *. En nuestro caso lo programaremos cada 5 minutos.

cr_schedule("* * * * *", name="nombre_tarea",
            httpTarget = cr_build_schedule_http(itworks))
## ==CloudScheduleJob==
## name:  projects/XXXXXXXXXXXXXXXXXXXXX/locations/europe-west1/jobs/nombre_tarea 
## state:  ENABLED 
## httpTarget.uri:  https://cloudbuild.googleapis.com/v1/projects/XXXXXXXXXXXXXXXXXXXXX/builds 
## httpTarget.httpMethod:  POST 
## userUpdateTime:  2020-05-03T16:04:04Z 
## schedule:  * * * * * 
## timezone:  Europe/Paris

Una vez programado, en la consola de Cloud Scheduler podremos ver la tarea que se ha creado. Ahí podremos indicar que el proceso se ejecute, se pare, etc. Para ver cuándo se ha ejecutado el proceso, tendremos que verlo desde el historial de Cloud Build. Si se han ejecutado de forma correcta, veremos cada ejecución con un tick verde.

Resumen ejecuciones de nuestro código R automatizado en Google Cloud

¡Hecho! Con esto ya hemos aprendido a automatizar nuestro script de R en Google Cloud.

Resumen de cómo automatizar un script de R en Google Cloud

Como puedes ver, ya hemos aprendido a automatizar un script de en Google Cloud. Sin duda alguna, esta automatización es mucho más compleja que una automatización en local. A nivel de dinero, depende qué automaticemos, puede que tengamos la suerte de caer en el umbral gratuito de Google. Sino… pues tocará desembolsar unos euros.

En cualquier caso, esta forma de automatizar el script es sin duda mucho más escalable y fiable, por lo que te recomendaría lo probaras. Además, permite ganar conocimiento de todos los servicios que ofrece Google Cloud (que no son pocos) y de cómo interactúan entre ellos.

Y es que, tenemos que ser conscientes de que, si queremos escalar nuestros proyectos de datos, necesitamos una arquitectura que soporte todo nuestro trabajo. Sin duda alguna, en ese sentido, saber cómo automatizar los scripts de R en Google Cloud es un gran plus, que puede hacerte llevar tus proyectos (y despreocupación), al próximo nivel.

Espero te haya gustado y… ¡nos vemos en la próxima!