¡Añade aislamiento a tus despliegues con Environments!

Regresando, en plena cuarentena, a las arenas del CI/CD para hablar algo que curiosamente ayuda a lograr cierto aislamiento a tus recursos en la nube al momento de desplegar: Los Environments en Azure Pipelines, así que vamos a ello.

Repasemos un poco, cuando hemos tenido pipelines usando Designer Mode, hemos definido el despliegue (en este ejemplo hacia un Web App) mas o menos así:

Y en el caso de Multi-stage pipelines, el paso de despliegue se define así:

Si nos fijamos en ambos casos, veremos que corresponde al Pipeline definir el recurso “destino” donde haremos nuestro despliegue:Subscripción, Grupo de Recursos y Recurso (en este caso una WebApp), o sea que toda la responsabilidad recae sobre el pipeline y quienes tienen acceso a desarrollar sobre el.

Si, es cierto que podemos establecer una cierta seguridad si, cuando enlazamos nuestro Team Project contra los recursos de Azure, lo hacemos contra Grupos de Recursos acotados y no contra toda una Subscripción, algo de eso lo vimos anteriormente, pero lo que vamos a ver proporciona una abstracción adicional y funcionalidades que nos ayudaran al seguimiento de nuestros procesos de despliegue.

Conociendo a los Environments

Las nuevas capacidades llegan de la mano con los “Environments” de Azure Pipelines, que fueron introducidos el año pasado como parte del lanzamiento de los multi-stage Pipelines, y según Microsoft se definen como… una colección de recursos que pueden ser objeto de destino de implementaciones de un despliegue. Los Environments pueden incluir clústeres de Kubernetes, aplicaciones web de Azure, máquinas virtuales y bases de datos.”,  la definición queda clara, pero es bueno precisar que esa “colección” deberíamos entenderla como una abstracción que nos permite gestionar acceso a esos recursos y hacerle seguimiento “por fuera” del Pipeline, como veremos luego.

Antes de meternos en temas avanzados, cabe mencionar que además de representar recursos de despliegue “reales” también los Environments actúan como referencia “lógica” a las ejecuciones que pasan por determinados stages en nuestros pipelines, para entenderlo veamos el gráfico anterior con mas detalle:

Como se puede ver, ahí he declarado un Environment llamado ‘staging-environment’ para este pipeline, pero pese a todo he declarado (líneas abajo) explícitamente el recurso (Web App) contra el que hare el despliegue ¿No es eso una contradicción? Pues no, ya que al momento actual las Web Apps no pueden ser registradas como Environments, puesto que esta capacidad solo esta habilitada (de momento) a los clusters de Kubernetes o Maquinas Virtuales, pero aun asi, nos pueden ser de utilidad para ver el histórico de despliegues de manera aislada, y no al nivel de todo el pipeline, veámoslo en la sección correspondiente:

Ahí podemos ver diversos Environments que definí en los pipelines de este Team Project, por lo visto todos se desplegaron bien, menos uno, vamos a verlo, pero antes cabe indicar que esa columna de “Last activity” no indica la fecha de ultima ejecución, sino a la ultima fecha en que modificamos la configuración/definición del Environment de alguna manera. Bueno, hagamos clic dev-environment y empecemos a explorar:


Aprovechemos para entender la pantalla y la nomenclatura usada:

  • Lo que figura en negrita como “Actualizando comentario” representa el commit ‘vigente’ (o que disparo el trigger) al momento de la ejecución del Pipeline.
  • La expresión “#20200310.1 on MiniYAMLDeploy” representa el ID de la ejecución del pipeline llamado MiniYAMLDeploy.
  • El azure_web_app_dev representa al “job” (perteneciente al pipeline MiniYAMLDeploy) donde se realizo la invocación al Environment en cuestión.

Hacemos clic y continuamos explorando:

Que no nos engañe la simpleza de esta pantalla, es un punto de acceso a diversas áreas de nuestro trabajo con Azure DevOps, empezare comentando sobre el ultimo: Workitems, básicamente nos permite ver las relaciones que ha tenido esta ejecución con algún Workitem definido en Azure Boards, como en este ejemplo no hemos usado Boards, seguiremos de largo.

Jobs, es algo mas interesante, pues nos permite tracear hacia la ejecución del pipeline con problemas:

Listo, pero claro, uno podría decir que podríamos llegar a lo mismo navegando desde los pipelines, y estaría en lo cierto, pero hay ocasiones en que preferiríamos hacer el seguimiento desde el recurso, teniendo en cuenta que no siempre los despliegues se ejecutan en todos los recursos destino de un pipeline definido, sigamos ahora con Changes:

Esto nos permite visualizar los cambios de código involucrados en esta ejecución:

Environments: tu mecanismo para separar responsabilidades

Bueno, ya hemos visto la parte básica del seguimiento que podemos hacer con los Environments, pero aun no hemos explorado todo su poder, el cual (de momento) solo se consigue con Kubernetes y Máquinas Virtuales, así que continuemos.

Con lo visto, ya nos queda claro que podemos hacer un seguimiento a los recursos “destino” de nuestro despliegue, pero aparte de eso podemos establecer cierto control granular sobre a que Team Projects se les da permiso de despliegue sobre que recursos, y si se exigirá ciertos controles sobre el flujo de despliegue, ya sean manuales o automáticos.

Veámoslo así, Juan, del área de Operaciones, es tiene el control sobre las subscripciones de Azure, los servidores de producción, y los cluster de Kubernetes de toda la organización, llega Ana arquitecta a la que se le ha encargado que lidere un proyecto donde se desplegaran contenedores a Kubernetes. Por razones de seguridad se ha dispuesto que solo los responsables de Operaciones tengan control total sobre los entornos de trabajo, especialmente si se trata de equipos nuevos. ¿Cómo lograr que el equipo de Ana pueda desarrollar practicas CI/CD con estas restricciones?

Juan, que además es responsable de la cuenta de Azure DevOps, simplemente agregara al Team Project, unos Environments que representraran el enlace contra los namespace de Kubernetes contra los que se quiere desplegar:

Nótese que dice Kubernetes, no AKS, y esto es porque también esta preparado para conectarse a clusters de Kubernetes no necesariamente de Microsoft (lo cual abre posibilidades de que nuestro despliegue sea también contra EKS o GCK), así:

Solo que, en este caso, iremos por AKS, para lo cual tendremos que confirmar una identidad que tenga accesos a una Subscripción de Azure, para luego elegir el cluster que queremos vincular a nuestro Team Project:

Aceptamos y procedemos a la creación del Environment, cabe recordar que esta operación de creación la puede hacer Juan, pero no Ana, y esto debido a que Juan cuenta con los permisos de acceso a la Subscripción de Azure y los clusters de Kubernetes, algo que Ana no tiene, siendo que ella, como ya comentamos, para trabajar hará uso del Environment EjemploEnv01, sin necesidad de acceder directamente al cluster destino (en este caso aksdemokeda).

Y listo, ya tenemos nuestro Environment creado:

Si, similar a lo que habíamos visto en el otro Team Project con dev-environment, pero con una característica diferente, estamos directamente en la columna Resources (que no estaba en el otro caso), lo cual nos indica que ahora si estamos teniendo contacto con un recurso real de destino, así que revisemos:

Bueno, lo esperado, un indicativo de que aun no hemos hecho ningún despliegue contra este Environment, pero notemos algo interesante, un enlace que dice aksdemokeda (cluster), el cual nos permite acceder al portal de Azure para administrar el recurso “real”, muy práctico, si, solo que debemos recordar que eso solo lo podrá hacer Juan, mas no Ana.

Ok, ya tenemos un Envinroment ¿ahora como lo podemos usar en un despliegue?

De manera corta, lo que podemos hacer es empezar a usarlos en los stages de nuestros pipelines, en este caso mostrare un fragmento de pipeline que despliega un contenedor en el ACR hacia nuestro flamante Environment:

No nos detendremos en explicar este fragmento, pero baste saber que ahí le estamos pasando todo lo que necesita para hacer el despliegue en el cluster: gestión de secretos, ruta del ACR, parámetros de configuración del pod, etc pero para referenciar el destino y sus permisos solo necesitamos indicar environment: ‘paradev’ en la definición del job.

Agregando controles a los pasos del despliegue

Supongamos que la cosa se pone complicada, y se decide que Javier, el Product Owner del proyecto sea quien apruebe el pase al entorno, entonces… ¿cómo logramos que solo sea Javier quien pueda dar la aprobación al pase?

Aquí entra en acción la opción de definir Aprobadores en nuestro ciclo del pipeline, algo que ya estaba disponible en el modo Designer, solo que ahí esa definición de hacia a nivel de Pipeline, y no a nivel de recurso destino, así que veamos como habilitarla:

Le damos a Approvals and cheks y veremos lo siguiente:

Como podemos ver, en adición a los aprovals, se nos ofrece la opción de usar un Azure Function como mecanismo de control de despliegues, de manera similar al modo Designer, asì como un validador de artefactos, lo cual es totalmente nuevo, pero … aún hay más:

Como se puede ver, todo el flujo de control de un pase ha pasado a estar en manos de los Environments, pero como hemos dicho veremos lo de los Aprovals, (queda en manos del curioso lector revisar las otras opciones):

Nada del otro mundo, elegimos el Aproval, le dejamos instrucciones y desmarcamos la opción de que uno se pueda autoaprobar los despliegues que uno lance, ah! y claro, fijamos por cuanto tiempo vamos a esperar para que el Aproval se digne a brindarnos su atención :D. En este caso si este entorno al que hemos agregado un aproval es el de Producción veriamos algo similar a esto, un flujo detenido a la espera de una aprobación por parte de Javier:

Ok, eso de los controles y aprobadores suenan bien, pero ¿porque ponerlos a nivel de Environments? Muy simple, recordemos que es Juan y no Ana quien define quien puede ser aprobador y los controles necesarios para el pase, de esta manera podemos evitar que un miembro del equipo de Ana efectué un despliegue contra cierto entorno mediante la modificación del YAML del Pipeline, al hacer esto logramos que por más que se modifique el YAML, al no cumplirse las condiciones vigentes sobre el Environment (como la necesidad de que Javier apruebe que el paquete se despliegue sobre x recurso), el pipeline se detendrá.

¡Revisando el estado de tus recursos sin salir de Azure Pipelines!

Ahora bien, eso no es todo lo que podemos lograr con un Environment, ya para terminar veremos que esto permite tener cierto nivel de revisión (pero no de manipulación) sobre el cluster contra el que hemos desplegado nuestra aplicación, para esto veremos que es lo que paso cuando desplegamos un experimento sobre el Environment EjemploEnv01 que creamos en mi cluster aksdemokeda:

Procedemos a explorar el recurso y lo primero que veremos serán los Workloads:

Como podemos ver si bien aparentemente el despliegue se efectuó correctamente, no hay ningún pod en ejecución, así que veremos qué pasa con los servicios:

Todo bien, pero ya sabíamos que algo iba mal… así que profundizando la exploración encontré los mensajes de error de mis pods, con información emitida desde el propio cluster (si, hay acceso a los Logs de K8s), con lo cual ya tengo mas pistas para resolver mi error, y eso… sin ser necesario tener acceso de seguridad pleno sobre el cluster, solo lo necesario para poder trabajar.

Bueno, espero que esto haya sido de utilidad para conocer el potencial que tienen los Environments dentro de Azure Pipelines, lo que se viene es muy interesante pues en los próximos meses sera posible usar otro tipo de destinos dándole mas poder a estas opciones, como siempre si tienes alguna duda no dejes de poner un comentario.

Agregue un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *

Time limit is exhausted. Please reload the CAPTCHA.