Integrar Azure DevOps

En el capítulo anterior, aprendiste acerca de los eventos de Big Data y su relación con los servicios de Event Hubs y Stream Analytics de Azure. El desarrollo de software es una tarea compleja que comprende múltiples procesos y herramientas, e involucra a personas de diferentes departamentos. Todos ellos deben unirse y trabajar de manera cohesiva. Con tantas variables, los riesgos son altos al entregar a los clientes finales. Una pequeña omisión o mala configuración podría provocar el fallo de la aplicación. Este capítulo trata sobre la adopción e implementación de prácticas que reducen este riesgo considerablemente y aseguran que el software de alta calidad se pueda entregar al cliente una y otra vez.

Antes de entrar en detalles sobre DevOps, aquí tienes una lista de los problemas a los que se
enfrentan las empresas de software y que DevOps aborda:

  • Las organizaciones rígidas que no aceptan cambios
  • Procesos lentos
  • Equipos aislados que trabajan en silos
  • Diseño monolítico e implementaciones a modo de «big bang»
  • Ejecución manual
  • Falta de innovación

En este capítulo, abordaremos los siguientes temas:

  • DevOps
  • Prácticas de DevOps
  • Azure DevOps
  • Preparación de DevOps
  • DevOps para soluciones de PaaS
  • DevOps para soluciones basadas en máquinas virtuales (IaaS)
  • DevOps para soluciones basadas en contenedor (IaaS)
  • Azure DevOps y Jenkins
  • Azure Automation
  • Herramientas de Azure para DevOps

DevOps
Actualmente no hay consenso de todo el sector con respecto a la definición de DevOps.
Las organizaciones han formulado su propia definición de DevOps y han tratado de
implementarla. Tienen su propia perspectiva y piensan que han implementado DevOps
cuando implementan la administración de la automatización y la configuración y utilizan
procesos ágiles.

En función de mi experiencia trabajando en proyectos de DevOps del sector, he definido
DevOps del siguiente modo: DevOps trata del mecanismo de entrega de sistemas
de software. Se trata de unir a las personas, hacer que colaboren y se comuniquen, trabajen
juntas hacia un objetivo y una visión comunes. Se trata de tomar responsabilidad conjunta,
rendición de cuentas y propiedad. Se trata de implementar procesos que fomenten la
colaboración y una mentalidad de servicio. Permite mecanismos de entrega que aportan
agilidad y flexibilidad a la organización. Contrariamente a la creencia popular, DevOps no
se trata de herramientas, tecnología y automatización. Son habilitadores que ayudan con
la colaboración, la implementación de procesos ágiles y la entrega más rápida y mejor
al cliente.
Hay varias definiciones disponibles en Internet para DevOps y no son incorrectas. DevOps
no proporciona un marco o metodología. Es un conjunto de principios y prácticas que,
cuando se emplean dentro de una organización, interacción o proyecto, logran el objetivo
y la visión tanto de DevOps como de la organización. Estos principios y prácticas no exigen
ningún proceso, herramientas, tecnologías ni entornos específicos. DevOps proporciona
la orientación que puede implementarse a través de cualquier herramienta, tecnología
o proceso, aunque parte de la tecnología y los procesos podrían ser más aplicables que
otros para lograr la visión de los principios y prácticas de DevOps.
Aunque las prácticas de DevOps se pueden implementar en cualquier organización que
ofrezca servicios y productos a los clientes, en este libro veremos a DevOps desde la
perspectiva del desarrollo de software y el departamento de operaciones de cualquier
organización.
Entonces, ¿qué es DevOps? DevOps se define como un conjunto de principios y prácticas
que reúnen todos los equipos, incluidos los de desarrolladores y operaciones, desde el inicio
del proyecto para una entrega de extremo a extremo más rápida, veloz y eficiente del valor
al cliente final, una y otra vez, de manera coherente y predecible, reduciendo el tiempo
de comercialización, para obtener así una ventaja competitiva.
La definición anterior de DevOps no indica ni se refiere a ningún proceso, herramienta
o tecnología específicos. No prescribe ninguna metodología ni entorno.
El objetivo de implementar los principios y prácticas de DevOps en cualquier organización
es garantizar que las demandas de las partes interesadas (incluidos los clientes) y las
expectativas se cumplan de manera eficaz y efectiva.

Las demandas y expectativas del cliente se cumplen cuando sucede lo siguiente:

  • El cliente obtiene las características que desea
  • El cliente obtiene las características que desea cuando las desea
  • El cliente obtiene actualizaciones más rápidas de las características
  • La calidad de entrega es alta

Cuando una organización puede cumplir con estas expectativas, los clientes están
satisfechos y se mantienen leales. Esto, a su vez, aumenta la competitividad en el mercado
de la organización, lo que se traduce en una mayor marca y valoración del mercado. Tiene
un impacto directo en los resultados y las ventas de la organización. La organización puede
invertir más en innovación y comentarios de los clientes, provocando cambios continuos en
sus sistemas y servicios para mantener su relevancia.
La implementación de los principios y prácticas de DevOps en cualquier organización está
guiada por el ecosistema circundante. Este ecosistema está compuesto por la industria y los
dominios a los que pertenece la organización.
DevOps se basa en un conjunto de principios y prácticas. Veremos los detalles sobre estos
principios y prácticas más adelante en este capítulo. Los principios básicos de DevOps son:

  • Agilidad: ser ágil aumenta la flexibilidad general ante los cambios y garantiza que la
    adaptabilidad aumente en cada entorno cambiante y sea productivo. Los procesos
    ágiles tienen una duración de trabajo más corta y es fácil encontrar problemas antes
    en el ciclo de vida de desarrollo en lugar de mucho más tarde, por lo que se reduce la
    deuda técnica.
  • Automatización: la adopción de herramientas y automatización aumenta la eficiencia
    general y previsibilidad del proceso y el producto final. Ayuda a hacer las cosas más
    rápido, de una manera más sencilla y económica.
  • Colaboración: la colaboración se refiere a un repositorio común, la rotación de
    responsabilidades de trabajo, el intercambio de datos e información y otros aspectos
    que mejoran la productividad de cada miembro del equipo, lo que apoya la entrega
    general eficaz del producto.
  • Comentarios: se refiere a bucles de comentarios rápidos y tempranos entre varios
    equipos sobre cosas que funcionan y cosas que no funcionan. Ayuda a los equipos
    a priorizar problemas y solucionarlos en versiones posteriores.

Las prácticas principales de DevOps son:

  • Integración continua: se refiere al proceso de validación y verificación de la
    calidad y corrección del código que los desarrolladores insertan en el repositorio.
    Puede ser programada, manual o continua. Continua significa que el proceso
    comprobará varios atributos de calidad cada vez que un desarrollador inserte
    el código, mientras que programada significa que se realizarán las comprobaciones
    en un horario determinado. Manual hace referencia a la ejecución manual por
    parte de un administrador o desarrollador.
  • Administración de la configuración: esta es una faceta importante de DevOps y
    proporciona orientación para configurar la infraestructura y las aplicaciones, ya sea
    mediante la extracción de configuraciones de los servidores de administración de la
    configuración o la introducción de estas configuraciones según una programación.
    La administración de la configuración debe devolver el entorno al estado deseado
    esperado cada vez que se ejecuta.
  • Entrega continua: la entrega continua se refiere al estado de preparación de una
    aplicación para poder implementarse en cualquier entorno existente, así como en
    un nuevo entorno. Generalmente se ejecuta por medio de una definición de versión
    en entornos inferiores como desarrollo y pruebas.
  • Implementación continua: la implementación continua se refiere a la capacidad
    de implementar el entorno y la aplicación en producción automáticamente.
    Generalmente se ejecuta por medio de una definición de versión en el entorno
    de producción.
  • Aprendizaje continuo: se refiere al proceso de comprender los problemas a los
    que se enfrentan las operaciones y los clientes y asegurarse de que se comunican
    a los equipos de desarrollo y pruebas para que puedan solucionar esos problemas
    en versiones posteriores para mejorar el estado general y la facilidad de uso de
    la aplicación.

La esencia de DevOps
DevOps no es un paradigma nuevo, pero está ganando mucha popularidad y relevancia.
Su adopción se encuentra en su nivel más alto y cada vez más empresas están emprendiendo
este proceso. Mencioné a propósito DevOps como un proceso porque hay diferentes niveles
de madurez dentro de DevOps. Si bien el éxito de la implementación y la entrega continuas
se considera el nivel más alto de madurez en este proceso, adoptar el control del código
fuente y el desarrollo ágil de software se considera el primer paso en el proceso de DevOps.

Una de las primeras cosas de las que habla DevOps es romper las barreras entre el
desarrollo y los equipos de operaciones. Aporta una colaboración estrecha entre varios
equipos. Se trata de cambiar la mentalidad de la que el desarrollador es responsable de
escribir solo el código y pasarlo al equipo de operaciones para la implementación una
vez que se haya probado. También se trata de cambiar la mentalidad de que el equipo
de operaciones no tiene ningún papel que desempeñar en las actividades de desarrollo.
El equipo de operaciones debe influir en la planificación del producto y debe ser
consciente de las características que se publicarán como lanzamientos. También deben
proporcionar continuamente comentarios a los desarrolladores sobre los problemas
operativos, de modo que puedan solucionarse en versiones posteriores. Deben influir en
el diseño del sistema para mejorar el funcionamiento operativo del sistema. De manera
similar, los desarrolladores deben ayudar al equipo de operaciones a implementar el
sistema y resolver incidentes cuando surjan.
La definición de DevOps hace referencia a la entrega de extremo a extremo más rápida
y eficiente de los sistemas a los interesados. No habla de lo rápida o eficiente que debería
ser la entrega. Debería ser lo suficientemente rápida para el dominio de la organización,
la industria, la segmentación de clientes y las necesidades. Para algunas organizaciones,
las entregas trimestrales podrían ser suficientemente buenas, mientras que para otras
podrían ser las semanales. Las dos son válidas desde el punto de vista de DevOps y estas
organizaciones pueden implementar procesos y tecnologías relevantes para alcanzar sus
plazos de entrega objetivo. DevOps no exige ningún marco de tiempo específico para la
integración continua/implementación continua (CI/CD). Las organizaciones deben
identificar la mejor implementación de los principios y las prácticas de DevOps en función
de su visión general del proyecto, la interacción y la organización.
La definición también habla de la entrega de un extremo a otro. Esto significa que todo
desde la planificación y la entrega del sistema hasta los servicios y operaciones debe ser
parte de la adopción de DevOps. Los procesos deben permitir una mayor flexibilidad,
modularidad y agilidad en el ciclo de vida del desarrollo de la aplicación. Mientras que
las organizaciones son libres de usar el mejor proceso de ajuste, como Cascada, Ágil,
Scrum u otro, por lo general, las organizaciones tienden a favorecer los procesos ágiles
con la entrega basada en iteraciones. Esto permite una entrega más rápida en unidades
más pequeñas, que son mucho más comprobables y manejables en comparación con una
entrega grande.
DevOps habla repetidamente sobre clientes finales de una manera coherente y predecible.
Esto significa que las organizaciones deben realizar entregas continuamente a los clientes
con funciones más nuevas y actualizadas utilizando la automatización. No podemos lograr
coherencia y previsibilidad sin el uso de la automatización. El trabajo manual debe ser
inexistente para garantizar un alto nivel de coherencia y previsibilidad. La automatización
también debe ser de extremo a extremo, para evitar fallos. Esto también indica que el diseño
del sistema debe ser modular, lo que permite una entrega más rápida en los sistemas que
son fiables, disponibles y escalables. Las pruebas desempeñan un gran papel en la entrega
coherente y predecible.

El resultado final de la implementación de estas prácticas y principios es que la organización
puede satisfacer las expectativas y demandas de los clientes. La organización puede crecer
más rápido que la competencia y aumentar aún más la calidad y la capacidad de sus
productos y servicios a través de la innovación y mejora continuas.
Ahora que ya conoces la idea que hay detrás de DevOps, es el momento de examinar las
prácticas principales de DevOps.
Prácticas de DevOps
DevOps consta de múltiples prácticas, cada una de las cuales proporciona una funcionalidad
distinta al proceso general. En el siguiente diagrama se muestra la relación entre ellas. La
administración de la configuración, así como la integración y la implementación continuas
forman las prácticas centrales que habilitan DevOps. Cuando entregamos servicios de
software que combinan estos tres servicios, logramos una entrega continua. La entrega
continua es la capacidad y el nivel de madurez de una organización que depende de
la madurez de la administración de la configuración, así como de la integración y la
implementación continuas. Los comentarios continuos, en todas las fases, forman el ciclo
de comentarios que proporciona servicios superiores a los clientes. Se ejecuta a través
de todas las prácticas de DevOps. Vamos a profundizar en cada una de estas capacidades
y prácticas de DevOps:

Administración de la configuración
Las aplicaciones y los servicios empresariales necesitan un entorno en el que se puedan
implementar. Normalmente, el entorno es una infraestructura compuesta por varios
servidores, equipos, redes, almacenamiento, contenedores y muchos más servicios que
trabajan conjuntamente de modo que las aplicaciones empresariales se puedan implementar
sobre ellos. Las aplicaciones empresariales se descomponen en varios servicios que se
ejecutan en diferentes servidores, ya sea on-premises o en el cloud. Cada servicio tiene
su propia configuración junto con los requisitos relacionados con la configuración de la
infraestructura. En resumen, tanto la infraestructura como la aplicación son necesarias para
entregar sistemas a los clientes y las dos tienen su propia configuración. Si la configuración
se desplaza, la aplicación podría no funcionar como se esperaba, lo que provocaría
tiempos de inactividad y fallos. Además, como el proceso de administración del ciclo de
vida de la aplicación (ALM) dicta el uso de múltiples etapas y entornos, una aplicación
se implementaría en varios entornos con diferentes configuraciones. La aplicación se
implementaría en el entorno de desarrollo para que los desarrolladores vean el resultado
de su trabajo. Después se implementaría en varios entornos de prueba con diferentes
configuraciones para pruebas funcionales, pruebas de carga y esfuerzo, pruebas de
rendimiento, pruebas de integración y más. También se implementaría en el entorno de
preproducción para realizar pruebas de aceptación del usuario y, finalmente, en un entorno
de producción. Es importante que una aplicación se pueda implementar en varios entornos
sin realizar cambios manuales en su configuración.
La administración de la configuración proporciona un conjunto de procesos y herramientas
y ayuda a garantizar que cada entorno y aplicación tengan su propia configuración. La
administración de la configuración hace un seguimiento de los elementos de configuración
y cualquier cosa que cambie de un entorno a otro debe tratarse como un elemento de
configuración. La administración de la configuración también define las relaciones entre los
elementos de configuración y cómo los cambios en un elemento de configuración afectarán
a los otros elementos de configuración.

Uso de la administración de la configuración
La administración de la configuración ayuda en los siguientes espacios:

  • Infraestructura como código: cuando el proceso de aprovisionamiento de
    infraestructura y su configuración se representa a través del código y el mismo
    código pasa por el proceso del ciclo de vida de la aplicación, se conoce como
    infraestructura como código (IaC). IaC ayuda a automatizar el aprovisionamiento
    y la configuración de la infraestructura. También representa toda la infraestructura
    en el código que se puede almacenar en un repositorio y una versión controlada.
    Esto permite a los usuarios emplear las configuraciones del entorno anteriores
    cuando sea necesario. También permite el aprovisionamiento de un entorno varias
    veces de manera coherente y predecible. Todos los entornos aprovisionados de
    esta manera son coherentes e iguales en todas las etapas de ALM. Hay muchas
    herramientas que ayudan a conseguir la IaC, entre ellas plantillas de ARM, Ansible
    y Terraform.
  • Implementación y configuración de la aplicación: la implementación de una
    aplicación y su configuración es el siguiente paso después del aprovisionamiento de
    la infraestructura. Entre algunos de los ejemplos se incluyen implementar un paquete
    webdeploy en un servidor, implementar esquemas y datos de un SQL Server (bacpac) en
    otro servidor y cambiar la cadena de conexión SQL en el servidor web para representar
    el SQL Server apropiado. La administración de la configuración almacena valores para
    la configuración de la aplicación para cada entorno en el que se implementa.

La configuración aplicada también debe ser supervisada. La configuración esperada y deseada
debe mantenerse constantemente. Cualquier desplazamiento de esta configuración esperada
y deseada haría que la aplicación no estuviera disponible. La administración de la configuración
también es capaz de encontrar el desplazamiento y reconfigurar la aplicación y el entorno a su
estado deseado.
Con la administración de la configuración automatizada implementada, nadie del equipo
tiene que implementar y configurar los entornos y las aplicaciones en producción.
El equipo de operaciones no depende del equipo de desarrollo ni de la documentación
de implementación larga.
Otro aspecto de la administración de la configuración es el control del código fuente. Las
aplicaciones y los servicios empresariales constan de código y otros artefactos. Varios
miembros del equipo trabajan en los mismos archivos. El código fuente debe estar actualizado
siempre y solo debe ser accesible para los miembros del equipo autenticados. El código y
otros artefactos por sí mismos son elementos de configuración. El control de código fuente
ayuda a la colaboración y la comunicación dentro del equipo, ya que todos son conscientes de
lo que está haciendo cada persona y los conflictos se resuelven en una etapa temprana.
La administración de la configuración se puede dividir en dos categorías:

  • Dentro de la máquina virtual
  • Fuera de la máquina virtual

Herramientas de administración de la configuración
Las herramientas disponibles para la administración de la configuración dentro de
la máquina virtual se enumeran a continuación.
Desired State Configuration
Desired State Configuration (DSC) es una nueva plataforma de administración de
configuración de Microsoft, creada como una extensión de PowerShell. DSC se
lanzó originalmente como parte de Windows Management Framework (WMF) 4.0.
Está disponible como parte de WMF 4.0 y 5.0 para todos los sistemas operativos
de Windows Server anteriores a Windows 2008 R2. WMF 5.1 está disponible
«out of the box» en Windows Server 2016/2019 y Windows 10.

Chef, Puppet y Ansible
Además de DSC, hay una gran cantidad de herramientas de administración de configuración,
como Chef, Puppet y Ansible, que admiten Azure. Los detalles sobre estas herramientas no se
incluyen en este libro. Obtén más información sobre ellas aquí: https://docs.microsoft.com/
azure/virtual-machines/windows/infrastructure-automation.
Las herramientas disponibles para la administración de la configuración fuera de una
máquina virtual se mencionan a continuación.
Plantillas de ARM
Las plantillas de ARM son el principal medio de aprovisionamiento de recursos en ARM. Las
plantillas de ARM ofrecen un modelo declarativo a través del cual se especifican los recursos
y su configuración, los scripts y las extensiones. Estas se basan en el formato JavaScript
Object Notation (JSON). Utiliza sintaxis y convenciones JSON para declarar y configurar
recursos. Los archivos JSON son archivos basados en texto, fáciles de usar y fáciles de leer.
Se pueden almacenar en un repositorio de código fuente y tienen control de versiones.
También son un medio para representar la infraestructura como código que se puede usar
para aprovisionar recursos en los grupos de recursos de Azure una y otra vez, de manera
predecible, coherente y uniforme.
Las plantillas se caracterizan por su flexibilidad debido a su diseño e implementación genéricos
y modulares. Las plantillas no ofrecen la posibilidad de aceptar los parámetros de los usuarios,
declarar variables internas, ayudar a definir dependencias entre recursos, vincular los recursos
dentro de un grupo de recursos o entre diferentes grupos de recursos y ejecutar otras plantillas.
Ofrecen, además, funciones y expresiones de tipo de lenguaje de scripting que las convierten
en herramientas dinámicas y personalizables en el entorno de ejecución. En este libro, hay dos
capítulos dedicados a las plantillas de ARM: capítulo 15, Implementaciones entre suscripciones
mediante plantillas de ARM y capítulo 16, Diseño e implementación modulares de plantillas de ARM.
Ahora es momento de centrarse en el siguiente principio importante de DevOps: la
integración continua.
Integración continua
Varios desarrolladores escriben código que finalmente se almacena en un repositorio común.
Normalmente, el código se registra o se inserta en el repositorio cuando los desarrolladores
han terminado de desarrollar sus funciones. Esto puede suceder en un día o puede tardar días
o semanas. Algunos de los desarrolladores podrían estar trabajando en la misma función y
también podrían seguir las mismas prácticas de insertar/registrar el código en días o semanas.
Esto puede crear problemas con la calidad del código. Uno de los principios de DevOps es
fallar rápido. Los desarrolladores deben registrar/insertar su código al repositorio a menudo
y compilar el código para verificar si han introducido errores y si el código es compatible con
el código escrito por sus compañeros. Si un desarrollador no sigue esta práctica, el código en
su máquina crecerá demasiado y será difícil de integrar con el código de otros. Además, si la
compilación falla, es difícil y lleva mucho tiempo solucionar los problemas que surjan.

Integración del código
La integración continua resuelve este tipo de desafíos. La integración continua ayuda en la
compilación y validación del código insertado/registrado por un desarrollador al llevarlo
a cabo a través de una serie de pasos de validación. La integración continua crea un flujo
de proceso que consta de varios pasos. La integración continua se compone de compilación
automatizada continua y pruebas automatizadas continuas. Normalmente, el primer paso es
compilar el código. Después de la compilación exitosa, cada paso es responsable de validar
el código desde una perspectiva específica. Por ejemplo, las pruebas unitarias pueden
ejecutarse en el código compilado y después la cobertura del código puede ejecutarse
para verificar qué rutas de código se ejecutan mediante pruebas unitarias. Podrían revelar
si se escriben pruebas unitarias exhaustivas o si hay margen para agregar más pruebas
unitarias. El resultado final de la integración continua son los paquetes de implementación
que pueden usarse mediante la implementación continua para implementarlos en múltiples
entornos.
Inserción frecuente de código
Se recomienda a los desarrolladores que revisen su código varias veces en un día en lugar
de hacerlo después de días o semanas. La integración continua inicia la ejecución de toda
la canalización tan pronto como se registre o se inserte el código. Si la compilación se
realiza correctamente, las pruebas de código y otras actividades que forman parte de la
canalización se ejecutan sin errores, el código se implementa en un entorno de prueba
y se ejecutan pruebas de integración en él.
Aumento de la productividad
La integración continua aumenta la productividad del desarrollador. No tienen que compilar
manualmente su código, ejecutar varios tipos de pruebas una tras otra y luego crear
paquetes a partir de él. También reduce el riesgo de que se introduzcan errores en el código
y el código no se vuelve obsoleto. Proporciona comentarios tempranos a los desarrolladores
sobre la calidad de su código. En general, la calidad de las entregas es alta y se entregan
más rápido al adoptar prácticas de integración continua. Aquí se muestra una canalización
de integración continua de ejemplo:

Automatización de compilación
La automatización de compilación consta de varias tareas que se ejecutan secuencialmente.
En general, la primera tarea es responsable de obtener el último código fuente del repositorio.
El código fuente puede comprender múltiples proyectos y archivos. Se compilan para
generar artefactos, como ejecutables, bibliotecas de enlaces dinámicos y ensamblados.
La automatización de compilación exitosa refleja que no hay errores de tiempo de
compilación en el código.
Podría haber más pasos para la automatización de compilación, dependiendo de la
naturaleza y el tipo de proyecto.
Automatización de pruebas
La automatización de pruebas consiste en tareas que son responsables de validar diferentes
aspectos del código. Estas tareas están relacionadas con el código de prueba desde una
perspectiva diferente y se ejecutan secuencialmente. Generalmente, el primer paso es
ejecutar una serie de pruebas unitarias en el código. Las pruebas unitarias se refieren
al proceso de probar la denominación más pequeña de una característica validando
su comportamiento de forma aislada de otras características. Puede ser automatizada
o manual; sin embargo, la preferencia es hacia pruebas unitarias automatizadas.
La cobertura de código es otro tipo de prueba automatizada que se puede ejecutar
en el código para averiguar cuánto código se ejecuta al ejecutar las pruebas unitarias.
Normalmente se representa como un porcentaje y se refiere a la cantidad de código
que se puede probar a través de la prueba unitaria. Si la cobertura de código no es
cercana al 100 %, es porque el desarrollador no ha escrito pruebas unitarias para ese
comportamiento o el código no cubierto no es necesario en absoluto.
La ejecución exitosa de la automatización de pruebas, que resulte en un fallo de código
no significativo, debe comenzar a ejecutar las tareas de empaquetado. Podría haber
más pasos para la automatización de pruebas dependiendo de la naturaleza y el tipo
de proyecto.
Empaquetado
El empaquetado se refiere al proceso de generación de artefactos desplegables,
como los paquetes MSI, NuGet y webdeploy y los paquetes de base de datos, la versión
y el almacenamiento en una ubicación para que puedan ser consumidos por otras
canalizaciones y procesos.
Una vez finalizado el proceso de integración continua, se inicia el proceso de
implementación continua, que será el tema central de la siguiente sección.

Implementación continua
En el momento en que el proceso alcanza la implementación continua, la integración
continua ha asegurado que tengamos bits de trabajo completos de una aplicación que
ahora pueden tomarse a través de diferentes actividades de implementación continua.
La implementación continua se refiere a la capacidad de implementar aplicaciones
y servicios empresariales en entornos de preproducción y producción a través de
la automatización. Por ejemplo, la implementación continua podría aprovisionar
y configurar el entorno de preproducción, implementar las aplicaciones y configurarlas.
Después de realizar varias validaciones, como pruebas funcionales y pruebas de
rendimiento en un entorno de preproducción, el entorno de producción se aprovisiona,
se configura y la aplicación se implementa a través de la automatización. No hay
pasos manuales en el proceso de implementación. Cada tarea de implementación está
automatizada. La implementación continua puede aprovisionar el entorno e implementar
la aplicación desde cero, aunque solo puede implementar los cambios incrementales en
un entorno existente si el entorno ya existe.
Todos los entornos se aprovisionan a través de la automatización utilizando la IaC.
Esto garantiza que todos los entornos, ya sean de desarrollo, prueba, preproducción
o producción, sean iguales. De manera similar, la aplicación se implementa a través de la
automatización, lo que garantiza que también se implementa de manera uniforme en todos
los entornos. La configuración en estos entornos podría ser diferente para la aplicación.
La implementación continua generalmente se integra con la integración continua. Cuando
la integración continua ha realizado su trabajo, al generar los paquetes desplegables
finales, la implementación continua se activa y comienza su propia canalización. La
canalización se denomina canalización de versión. La canalización de versión consta de
varios entornos. Cada entorno consiste en tareas responsables del aprovisionamiento del
entorno, la configuración del entorno, la implementación de aplicaciones, la configuración
de aplicaciones, la ejecución de la validación operativa en entornos y la prueba de la
aplicación en múltiples entornos.
Emplear una implementación continua proporciona inmensos beneficios. Existe un alto
nivel de confianza en el proceso de implementación general, que ayuda a las versiones de
producción más rápidas y sin riesgos. Las posibilidades de que algo salga mal disminuyen
drásticamente. El equipo estará menos estresado y la reversión al entorno de trabajo
anterior es posible si hay problemas con la versión actual:

Aunque cada sistema exige su propia configuración de la canalización de versiones,
en el diagrama anterior se muestra un ejemplo de implementación continua. Es importante
tener en cuenta que, en general, el aprovisionamiento y la configuración de múltiples
entornos son parte de la canalización de versión y las aprobaciones deben buscarse antes
de pasar al siguiente entorno. El proceso de aprobación puede ser manual o automatizado,
dependiendo de la madurez de la organización.
A continuación, examinaremos los aspectos relacionados con el entorno de prueba.
Implementación del entorno de prueba
La canalización de versión comienza una vez que la colocación está disponible desde la
integración continua y el primer paso que debe tomar es obtener todos los artefactos
de la colocación. Después de esto, la canalización de versión puede crear un entorno de
prueba completo totalmente nuevo o reutilizar uno existente. De nuevo, esto depende
del tipo de proyecto y la naturaleza de las pruebas planeadas para ejecutarse en este
entorno. El entorno está aprovisionado y configurado. Los artefactos de la aplicación
están implementados y configurados.
Automatización de pruebas
Después de implementar una aplicación, se pueden realizar una serie de pruebas en el
entorno. Una de las pruebas que se ejecutan aquí es una prueba funcional. Las pruebas
funcionales tienen como objetivo principal validar la integridad y funcionalidad de la
aplicación. Estas pruebas están escritas desde los requisitos recopilados del cliente.
Otro conjunto de pruebas que se pueden ejecutar está relacionado con la escalabilidad
y la disponibilidad de la aplicación. Normalmente, esto incluye pruebas de carga, pruebas
de estrés y pruebas de rendimiento. También debe incluir una validación operativa del
entorno de infraestructura.
Implementación del entorno de ensayo
Esto es muy similar a la implementación del entorno de prueba. La única diferencia es
que los valores de configuración para el entorno y la aplicación serían diferentes.
Pruebas de aceptación
Normalmente, las pruebas de aceptación las realizan las partes interesadas de la aplicación
y pueden ser manuales o automatizadas. Este paso es una validación desde el punto de
vista del cliente sobre la corrección y la integridad de la funcionalidad de la aplicación.
Implementación en producción
Una vez que el cliente da su aprobación, se ejecutan los mismos pasos que los de
la implementación del entorno de prueba y ensayo, con la única diferencia de que
los valores de configuración para el entorno y la aplicación son específicos para el
entorno de producción. Se lleva a cabo una validación después de la implementación
para garantizar que la aplicación se ejecuta de acuerdo con las expectativas.

La entrega continua es un principio importante de DevOps y es muy similar a la
implementación continua; sin embargo, hay algunas diferencias. En la siguiente sección,
examinaremos la entrega continua.
Entrega continua
La entrega continua y la implementación continua pueden parecerte similares; sin embargo,
no son lo mismo. Si bien la implementación continua habla sobre la implementación en
varios entornos y, finalmente, en el entorno de producción a través de la automatización,
la entrega continua es la capacidad de generar paquetes de aplicaciones de una manera
que se puedan implementar fácilmente en cualquier entorno. Para generar artefactos que
se puedan implementar fácilmente, se debe usar la integración continua para generar los
artefactos de la aplicación, se debe usar un entorno nuevo o existente para implementar
estos artefactos y realizar pruebas funcionales, pruebas de rendimiento y pruebas de
aceptación del usuario mediante la automatización. Una vez que estas actividades se
ejecutan con éxito y sin errores, el paquete de la aplicación se considera fácilmente
implementable. La entrega continua incluye la integración y la implementación continuas
en un entorno para validaciones finales. Ayuda a obtener comentarios más rápidamente
tanto de las operaciones como del usuario final. Estos comentarios se pueden utilizar para
implementar iteraciones posteriores.
En la siguiente sección, examinaremos el aprendizaje continuo.
Aprendizaje continuo
Con todas las prácticas de DevOps mencionadas anteriormente, es posible crear
aplicaciones empresariales excelentes e implementarlas automáticamente en el entorno
de producción. Sin embargo, los beneficios de DevOps no durarán mucho tiempo si no se
implementan los principios de mejora continua y comentarios. Es de suma importancia
que los comentarios en tiempo real sobre el comportamiento de la aplicación se transmitan
como comentarios al equipo de desarrollo tanto de los usuarios finales como del equipo
de operaciones.
Los comentarios se deben transmitir a los equipos, que proporcionan información
relevante sobre lo que está funcionando bien y lo que no está funcionando bien.
La arquitectura y el diseño de una aplicación deben construirse teniendo en cuenta
la supervisión, la auditoría y la telemetría. El equipo de operaciones debe recopilar
la información de telemetría del entorno de producción, capturar todos los errores
y problemas y transmitirlo todo al equipo de desarrollo para que puedan subsanarse
en las versiones posteriores.

El aprendizaje continuo ayuda a que la aplicación sea robusta y resistente a los fallos. Ayuda
a garantizar que la aplicación cumpla con los requisitos del cliente. En la Figura 13.4 se
muestra el ciclo de comentarios que se debe implementar entre diferentes equipos:

Después de recorrer las prácticas importantes relacionadas con DevOps, es el momento de
adentrarse en las herramientas y servicios que las hacen posibles.
Azure Devops
Veamos otro servicio online de primera línea que permite la integración continua, la
implementación continua y la entrega continua sin problemas: Azure DevOps. De hecho,
sería más apropiado llamarlo un conjunto de servicios disponibles con un solo nombre.
Azure DevOps es un servicio PaaS proporcionado por Microsoft que se aloja en el cloud.
El mismo servicio está disponible como Team Foundation Services (TFS) on-premises.
Todos los ejemplos que aparecen en este libro usan Azure DevOps.
Según Microsoft, Azure DevOps es una plataforma de colaboración basada en el cloud que
ayuda a los equipos a intercambiar código, realizar un seguimiento del trabajo y enviar
software. Azure DevOps es un nuevo nombre; anteriormente, se denominaba Visual Studio
Team Services (VSTS). Azure DevOps es un servicio y una herramienta de desarrollo de
software empresarial que permite a las organizaciones proporcionar instalaciones de
automatización a su proceso integral de administración del ciclo de vida de la aplicación,
desde la planificación hasta la implementación de las aplicaciones, y obtener comentarios
en tiempo real de los sistemas de software. Esto aumenta la madurez y la capacidad de
una organización para entregar sistemas de software de alta calidad a sus clientes.
La entrega exitosa de software implica unir eficientemente numerosos procesos y
actividades. Estos incluyen la ejecución e implementación de diversos procesos ágiles,
el aumento de la colaboración entre equipos, la transición sin problemas y automática
de los artefactos de una fase de ALM a otra fase y las implementaciones en múltiples
entornos. Es importante hacer un seguimiento e informar sobre estas actividades
para medir y mejorar los procesos de entrega. Azure DevOps lo hace sencillo y fácil.
Proporciona un conjunto completo de servicios que permite lo siguiente:

  • Colaboración entre todos los miembros del equipo al proporcionar una interfaz única
    para la gestión completa del ciclo de vida de la aplicación
  • Colaboración entre los equipos de desarrollo utilizando servicios de gestión de código
    fuente
  • Colaboración entre equipos de pruebas utilizando servicios de administración de
    pruebas
  • Validación automática de código y empaquetado a través de la integración continua
    utilizando servicios de administración de compilación
  • Validación automática de la funcionalidad de la aplicación, la implementación y la
    configuración de múltiples entornos a través de la implementación y entrega continua
    utilizando los servicios de administración de versiones
  • Seguimiento y administración de elementos de trabajo mediante servicios de
    administración de trabajo

En la siguiente tabla se muestran todos los servicios disponibles para un proyecto típico
desde la barra de navegación de la izquierda de Azure DevOps:

Una organización en Azure DevOps sirve de límite de seguridad y contenedor lógico que
proporciona todos los servicios necesarios para implementar una estrategia DevOps. Azure
DevOps permite la creación de varios proyectos dentro de una sola organización. De forma
predeterminada, se crea un repositorio con la creación de un proyecto. Sin embargo,
Azure DevOps permite la creación de repositorios adicionales dentro de un solo proyecto.
La relación entre una organización de Azure DevOps, los proyectos y un repositorio se
muestra en la Figura 13.5:

Azure DevOps proporciona dos tipos de repositorios:

  • Git
  • Control de versiones de Team Foundation (TFVC)

También proporciona la flexibilidad de elegir entre el repositorio de control de origen Git
o TFVC. Puede haber una combinación de repositorios TFS y TFVC disponibles dentro de
un solo proyecto.

TFVC
TFVC es la forma tradicional y centralizada de implementar el control de versiones,
donde hay un repositorio central y los desarrolladores trabajan directamente en el modo
conectado para registrar sus cambios. Si el repositorio central está sin conexión o no
está disponible, los desarrolladores no pueden registrar su código y deben esperar a que
esté online y disponible. Otros desarrolladores solo pueden ver el código introducido.
Los desarrolladores pueden agrupar varios cambios en un único conjunto de cambios
para registrar los cambios en el código que se agrupan lógicamente para formar un solo
cambio. TFVC bloquea los archivos de código que están en proceso de edición. Otros
desarrolladores pueden leer un archivo bloqueado, pero no pueden editarlo. Deben
esperar a que se complete la edición anterior y liberar el bloqueo antes de poder editarlo.
El historial de registros y cambios se mantiene en el repositorio central, mientras que los
desarrolladores tienen la copia de trabajo de los archivos pero no el historial.
TFVC funciona muy bien con equipos grandes que trabajan en los mismos proyectos.
Esto permite el control sobre el código fuente en una ubicación central. También funciona
mejor para proyectos de larga duración, ya que el historial se puede administrar en una
ubicación central. TFVC no tiene problemas para trabajar con archivos grandes y binarios.
Git
Por otro lado, Git es una forma moderna y distribuida de implementar el control de
versiones, donde los desarrolladores pueden trabajar en sus propias copias locales de
código e historial en modo sin conexión. Los desarrolladores pueden trabajar sin conexión
en su clon local de código. Cada desarrollador tiene una copia local de código y su historial
completo y trabajan en sus cambios con este repositorio local. Pueden enviar su código al
repositorio local. Se pueden conectar al repositorio central para la sincronización de su
repositorio local según sea necesario. Esto permite que todos los desarrolladores trabajen
en cualquier archivo, ya que estarían trabajando en su copia local. La ramificación en Git no
crea otra copia del código original y es de creación extremadamente rápida.
Git funciona bien con equipos pequeños y grandes. La ramificación y la fusión es algo
sencillo con las opciones avanzadas que presenta Git.
Git es la forma recomendada de usar el control de código fuente debido a la funcionalidad
enriquecida que proporciona. Usaremos Git como el repositorio de nuestra aplicación de
ejemplo en este libro. En la siguiente sección, veremos una descripción detallada de la
implementación de la automatización a través de DevOps.

Preparar DevOps
De aquí en adelante, nos centraremos en la automatización de procesos e implementación
utilizando diferentes patrones en Azure. Se incluyen los siguientes:

  • DevOps para soluciones de IaaS
  • DevOps para soluciones de PaaS
  • DevOps para soluciones basadas en contenedor
    En general, hay servicios compartidos que no son exclusivos de ninguna aplicación. Estos
    servicios los consumen múltiples aplicaciones de diferentes entornos, como desarrollo,
    pruebas y producción. El ciclo de vida de estos servicios compartidos es diferente para
    cada aplicación. Por lo tanto, tienen diferentes repositorios de control de versiones,
    una base de código diferente y administración de compilación y lanzamiento. Tienen
    su propio ciclo de plan, diseño, construcción, prueba y lanzamiento.
    Los recursos que forman parte de este grupo se aprovisionan utilizando plantillas de ARM,
    PowerShell y configuraciones DSC.
    El flujo general para crear estos componentes comunes se muestra aquí:

El proceso de lanzamiento se muestra en la Figura 13.7:

En el proceso de DevOps, es importante comprender y proporcionar los componentes y
servicios comunes antes de iniciar cualquier compromiso, producto o servicio de software.
El primer paso para empezar con Azure DevOps es aprovisionar una organización.
Organizaciones de Azure DevOps
Se necesita un sistema de control de versiones para colaborar en el nivel de código. Azure
DevOps proporciona versiones tanto centralizadas como descentralizadas de los sistemas
de control. Azure DevOps también proporciona servicios de orquestación para construir
y ejecutar canalizaciones de compilación y versión. Es una plataforma madura que organiza
el control de versiones relacionado con DevOps y compila y lanza artefactos relacionados
con elementos de trabajo. Después de aprovisionar una organización en Azure DevOps,
se debe crear un proyecto de Azure DevOps para contener todos los artefactos relacionados
con el proyecto.
Una organización de Azure DevOps se puede aprovisionar si se visita https://dev.azure.com.

Una organización de Azure DevOps es el límite administrativo y de administración de alto
nivel que proporciona seguridad, acceso y colaboración entre los miembros del equipo que
pertenecen a una organización. Puede haber varios proyectos dentro de una organización
y cada proyecto consta de varios equipos.
Aprovisionar Azure Key Vault
No es recomendable almacenar secretos, certificados, credenciales u otra información
confidencial en archivos de configuración de código, bases de datos o cualquier otro
sistema de almacenamiento general. Se recomienda almacenar estos datos importantes
en un almacén diseñado específicamente para almacenar secretos y credenciales. Azure
Key Vault proporciona este servicio. Azure Key Vault está disponible como un recurso
y servicio de Azure. Ahora, pasemos a explorar las opciones de almacenamiento para las
configuraciones.
Aprovisionar un servidor o servicio de administración de la configuración
Un servidor o servicio de administración de la configuración que proporciona
almacenamiento para las configuraciones y que aplica esas configuraciones a diferentes
entornos siempre es una buena estrategia para automatizar implementaciones. DSC en
máquinas virtuales personalizadas y DSC de Azure Automation, Chef, Puppet y Ansible
son algunas de las opciones y se pueden usar en Azure sin problemas tanto para entornos
de Windows como de Linux. Este libro utiliza DSC como herramienta de administración
de la configuración para todos los propósitos y proporciona un servidor de extracción
que contiene todos los documentos de configuración (archivos MOF) para la aplicación
de ejemplo. También mantiene la base de datos de todas las máquinas virtuales y
contenedores que están configurados y registrados con el servidor de extracción para
extraer los documentos de configuración. El administrador de configuración local en estos
contenedores y máquinas virtuales de destino verifica periódicamente la disponibilidad
de nuevas configuraciones, así como las desviaciones en la configuración actual e informa
de ello al servidor de extracción. También tiene capacidades de generación de informes
incorporadas que proporcionan información sobre los nodos que cumplen con los
requisitos, al igual que sobre los que no los cumplen, en una máquina virtual. Un servidor
de extracción es una aplicación web general que aloja el punto de conexión del servidor
de extracción de DSC. En el siguiente tema, analizaremos una técnica para supervisar los
procesos en tiempo real con Log Analytics.

Log Analytics
Log Analytics es un servicio de auditoría y supervisión proporcionado por Azure para
obtener información en tiempo real sobre todos los cambios, desviaciones y eventos que
ocurren dentro de máquinas virtuales y contenedores. Proporciona un espacio de trabajo
centralizado y un panel de control para los administradores de TI para ver, buscar y realizar
búsquedas detalladas sobre todos los cambios, desviaciones y eventos que ocurren en
estas máquinas virtuales. También proporciona agentes que se implementan en máquinas
virtuales y contenedores de destino. Una vez implementados, estos agentes comienzan
a enviar todos los cambios, eventos y desviaciones al espacio de trabajo centralizado.
Echemos un vistazo a las opciones de almacenamiento para implementar varias
aplicaciones.
Cuentas de Azure Storage
Azure Storage es un servicio proporcionado por Azure para almacenar archivos como blobs.
Todos los scripts y el código para automatizar el aprovisionamiento, la implementación
y la configuración de la infraestructura y la aplicación de ejemplo se almacenan en un
repositorio Git de Azure DevOps y se empaquetan y se implementan en una cuenta de
Azure Storage. Azure proporciona recursos de extensión de script de PowerShell que
pueden descargar automáticamente los scripts de DSC y PowerShell y ejecutarlos en
máquinas virtuales durante la ejecución de las plantillas de ARM. Este almacenamiento
actúa como un almacenamiento común en todas las implementaciones para múltiples
aplicaciones. El almacenamiento de scripts y plantillas en una cuenta de almacenamiento
garantiza que se puedan utilizar en todos los proyectos, independientemente de los
proyectos de Azure DevOps. Vamos a seguir explorando la importancia de las imágenes
en la siguiente sección.
Imágenes de Docker y OS
Las imágenes de la máquina virtual y del contenedor deben construirse como parte de la
canalización de compilación y versión de servicios comunes. Se pueden usar herramientas
como Packer y Docker para generar estas imágenes.
Herramientas de administración
Todas las herramientas de administración, como Kubernetes, DC/OS, Docker Swarm
e ITIL deben aprovisionarse antes de compilar e implementar la solución.
Finalizaremos esta sección sobre la preparación de DevOps con herramientas de
administración. Hay varias opciones para cada actividad dentro de un ecosistema
de DevOps y debemos habilitarlas como parte del proceso de DevOps: no debe ser
una idea de última hora, sino más bien una parte de la planificación de DevOps.

DevOps para soluciones de PaaS
La arquitectura típica de los servicios de aplicación de PaaS de Azure se basa en la
Figura 13.8:

La arquitectura muestra algunos de los componentes importantes, como Azure SQL,
cuentas de almacenamiento y el sistema de control de versiones, que participan en
la arquitectura de la solución de cloud basada en Azure App Service. Estos artefactos
deben crearse mediante plantillas de ARM. Estas plantillas de ARM deben formar parte
de la estrategia general de administración de la configuración. Puede tener sus propias
canalizaciones de administración de compilación y versión similares a las que se muestran
en la Figura 13.9:

Ahora que hemos explorado las diversas opciones de origen de implementación, vamos
a profundizar en cómo implementar soluciones de cloud en Azure.
Azure App Service
Azure App Services proporciona servicios de hosting administrado para soluciones
de cloud. Es una plataforma totalmente administrada que aprovisiona e implementa
soluciones de cloud. Azure App Service quita la carga de crear y administrar una
infraestructura y proporciona contratos de nivel de servicio (SLA) mínimos para
hospedar tus soluciones de cloud.
Ranuras de implementación
Azure App Service proporciona ranuras de implementación que facilitan y simplifican la
implementación. Hay múltiples ranuras y el intercambio entre ellas se hace en un nivel de
DNS. Significa que aquello que esté en la ranura de producción se puede intercambiar por
una ranura de ensayo simplemente cambiando las entradas DNS. Esto ayuda a implementar
la solución de cloud personalizada para el ensayo y, después de todas las comprobaciones
y pruebas, se pueden cambiar a producción si se encuentran satisfactorias. Sin embargo,
en caso de cualquier problema en la producción después del intercambio, los buenos valores
anteriores del entorno de producción se pueden restablecer mediante el intercambio.
Vamos a seguir con la descripción de la oferta de base de datos de Azure y algunas de sus
características clave.

Azure SQL
Azure SQL es un servicio PaaS SQL proporcionado por Azure para hospedar bases de datos.
Azure proporciona una plataforma segura para hospedar bases de datos y toma toda la
propiedad para administrar la disponibilidad, fiabilidad y escalabilidad del servicio. Con
Azure SQL, no es necesario aprovisionar máquinas virtuales personalizadas, implementar
un SQL Server y configurarlo. En su lugar, el equipo de Azure hace esto en segundo plano
y lo administra en tu nombre. También proporciona un servicio de firewall que permite
la seguridad. Solo una dirección IP permitida por el firewall puede conectar el servidor y
acceder a la base de datos. Las máquinas virtuales aprovisionadas para alojar aplicaciones
web tienen distintas direcciones IP públicas asignadas y se agregan dinámicamente a las
reglas de firewall de Azure SQL. Azure SQL Server y su base de datos se crean al ejecutar
la plantilla de ARM. A continuación, vamos a abordar las canalizaciones de compilación
y versión.
Canalizaciones de compilación y versión
En esta sección, se crea una nueva canalización de compilación que compila y valida una
aplicación MVC ASP.NET y, a continuación, genera paquetes para la implementación.
Después de la generación de paquetes, una definición de versión garantiza que la
implementación en el primer entorno se produzca en un App Service y Azure SQL
como parte de la implementación continua.
Hay dos maneras de crear canalizaciones de compilación y versión:

  1. Usando el editor clásico
  2. Usando archivos YAML

Los archivos YAML proporcionan más flexibilidad para crear canalizaciones de compilación
y versión.
La estructura del proyecto de la aplicación de ejemplo se muestra en la Figura 13.10:

En este proyecto hay una aplicación MVC ASP.NET, la aplicación principal, y consta de
páginas de la aplicación. Los paquetes de Web Deploy se generarán fuera de este proyecto
desde las canalizaciones de compilación y, finalmente, estarán en Web Apps. Hay otros
proyectos que también forman parte de la solución, como se menciona a continuación:

  • Proyecto de prueba unitaria: código para la prueba unitaria de la aplicación MVC ASP.
    NET. Los ensamblados de este proyecto se generarán y ejecutarán en la ejecución de
    la compilación.
  • Proyecto de bases de datos SQL: código relacionado con el esquema, la estructura
    y los datos maestros de la base de datos SQL. Los archivos DacPac se generarán
    a partir de este proyecto mediante la definición de compilación.
  • Proyecto de grupo de recursos de Azure: plantillas de ARM y código de parámetros
    para aprovisionar todo el entorno de Azure en el que se crean la aplicación MVC ASP.
    NET y a las tablas SQL.

La canalización de compilación se muestra en la Figura 13.11:

La configuración de cada tarea se muestra en la tabla 13.2:

La canalización de compilación está configurada para ejecutarse automáticamente como
parte de la integración continua, como se muestra en la Figura 13.12:

La definición de versión consta de varios entornos, como desarrollo, pruebas, pruebas de
integración del sistema (SIT), pruebas de aceptación de usuarios (UAT), preproducción
y producción. Las tareas son bastante similares en cada entorno, con la incorporación de
tareas específicas para el entorno determinado. Por ejemplo, un entorno de prueba tiene
tareas adicionales relacionadas con la interfaz de usuario y las pruebas funcionales y de
integración, en comparación con un entorno de desarrollo.

La definición de versión para dicha aplicación se muestra en la Figura 13.13:

Las tareas de versión para un único entorno se muestran en la Figura 13.14:

La configuración para cada una de las tareas se enumera aquí:

En esta sección has visto formas de configurar canalizaciones de compilación y versión
en Azure DevOps. De la siguiente sección en adelante, nos centraremos en diferentes
arquitecturas, como IaaS, contenedores y diferentes escenarios.

DevOps para IaaS
IaaS implica la gestión y administración de la infraestructura de base y las aplicaciones
juntas y hay varios recursos y componentes que deben aprovisionarse, configurarse
e implementarse en múltiples entornos. Es importante entender la arquitectura antes
de continuar.
La arquitectura típica para una solución basada en máquinas virtuales de IaaS se muestra aquí:

Cada uno de los componentes enumerados en la arquitectura se comenta a partir de la
siguiente sección.
Máquinas virtuales de Azure
Las máquinas virtuales de Azure que hospedan aplicaciones web, servidores de aplicaciones,
bases de datos y otros servicios se aprovisionan utilizando plantillas de ARM. Se adjuntan
a una red virtual y tienen una dirección IP privada de la misma red. La IP pública para
máquinas virtuales es opcional, ya que están conectadas a un equilibrador de carga público.
Los agentes Operational Insights se instalan en máquinas virtuales para supervisar las
máquinas virtuales. Los scripts de PowerShell también se ejecutan en estas máquinas
virtuales, descargadas de una cuenta de almacenamiento disponible en otro grupo de
recursos para abrir puertos de firewall relevantes, descargar paquetes apropiados e instalar
certificados locales para asegurar el acceso a través de PowerShell. La aplicación web está
configurada para ejecutarse en el puerto provisto en estas máquinas virtuales. El número de
puerto para la aplicación web y toda su configuración se obtiene del servidor de extracción
DSC y se asigna dinámicamente.

Equilibradores de carga públicos de Azure
Se adjunta un equilibrador de carga público a algunas de las máquinas virtuales para
enviarles solicitudes de forma round robin. Normalmente, esto es necesario para
las aplicaciones web front-end y las API. Se puede asignar una dirección IP pública
y un nombre DNS al equilibrador de carga para que pueda atender las solicitudes
de Internet. Acepta solicitudes web HTTP en diferentes puertos y los enruta a las
máquinas virtuales. También investiga determinados puertos en protocolos HTTP
con algunas rutas de aplicación proporcionadas. Asimismo, se pueden aplicar reglas
de traducción de direcciones de red (NAT) para que puedan utilizarse para iniciar
sesión en las máquinas virtuales mediante escritorios remotos.
Un recurso alternativo al equilibrador de carga público de Azure es Azure Application
Gateway. Las puertas de enlace de aplicaciones son equilibradores de carga de capa 7
y proporcionan características como terminación SSL, afinidad de sesión y enrutamiento
basado en URL. Vamos a analizar la canalización de compilación en la siguiente sección.
La canalización de compilación
A continuación, se muestra una canalización de compilación típica para la solución
basada en máquinas virtuales de IaaS. Una canalización de versión se inicia cuando
un desarrollador inserta su código en el repositorio. La canalización de compilación
se inicia automáticamente como parte de la integración continua. Compila y genera
el código, ejecuta pruebas unitarias en él, verifica la calidad del código y genera
documentación a partir de los comentarios del código. Implementa los nuevos
binarios en el entorno de desarrollo (ten en cuenta que el entorno de desarrollo no
se ha creado recientemente), cambia la configuración, ejecuta pruebas de integración
y genera etiquetas de compilación para una fácil identificación. A continuación, coloca
los artefactos generados en una ubicación a la que puede acceder la canalización de
versión. Si hay problemas durante la ejecución de cualquier paso en esta canalización,
se comunica al desarrollador como parte de los comentarios de la canalización de
compilación de manera que pueda volver a trabajar y enviar sus cambios. La canalización
de compilación debería fallar o pasar en función de la gravedad de los problemas
encontrados y que varía de una organización a otra. En la Figura 13.16 se muestra una
canalización de compilación típica:

Al igual que con la canalización de compilación, vamos a conocer la implementación de una
canalización de versión.
La canalización de versión
A continuación, se muestra una canalización de versión típica para la implementación
basada en máquinas virtuales de IaaS. Una canalización de versión comienza después
de la finalización de la canalización de compilación. El primer paso para la canalización
de compilación es reunir los artefactos generados por la canalización de compilación.
Generalmente son ensamblados desplegables, binarios y documentos de configuración.
La canalización de versión ejecuta y crea o actualiza el primer entorno, que generalmente
es un entorno de prueba. Utiliza las plantillas de ARM para aprovisionar todos los servicios
y recursos de IaaS y PaaS en Azure y también los configura. También ayudan en la ejecución
de scripts y la configuración de DSC después de que las máquinas virtuales se creen como
pasos posteriores a la creación. Esto ayuda a configurar el entorno dentro de la máquina
virtual y el sistema operativo. En esta etapa, se implementan y configuran los binarios de la
aplicación desde la compilación. Se realizan diferentes pruebas automatizadas para verificar
la solución y, si resulta satisfactoria, la canalización desplaza la implementación al siguiente
entorno después de obtener las aprobaciones necesarias. Los mismos pasos se ejecutan de
nuevo en el entorno siguiente, incluido el entorno de producción. Por último, las pruebas de
validación operativa se ejecutan en producción para garantizar que la aplicación funciona
como se esperaba y que no hay desviaciones.

En esta etapa, si hay algún problema o error, se debe corregir y se debe repetir todo el
ciclo. Sin embargo, si no ocurre esto dentro de un periodo de tiempo estipulado, la última
instantánea conocida debe restaurarse en el entorno de producción para minimizar el
tiempo de inactividad. En la Figura 13.17 se muestra una canalización de versión típica:

Esta sección concluye el proceso de DevOps para soluciones de IaaS y el siguiente capítulo
se centrará en los contenedores en máquinas virtuales. Ten en cuenta que los contenedores
también pueden ejecutarse en PaaS como App Service y Azure Functions.

DevOps con contenedores
En la arquitectura típica, los entornos de ejecución de contenedor se implementan en
máquinas virtuales y los contenedores se ejecutan dentro de ellas. La arquitectura típica
para las soluciones basadas en contenedores de IaaS se muestra aquí:

Estos contenedores se administran mediante orquestadores de contenedor como Kubernetes.
Log Analytics proporciona servicios de supervisión y todos los secretos y claves se almacenan en
Azure Key Vault. También hay un servidor de extracción, que podría estar en una máquina virtual
o Azure Automation, que proporciona información de configuración a las máquinas virtuales.
Contenedores
Los contenedores son una solución perteneciente a la tecnología de la virtualización. Sin
embargo, estos no virtualizan un servidor físico. Por el contrario, los contenedores son
una virtualización en el nivel del sistema operativo. Esto quiere decir que los contenedores
comparten el kernel del sistema operativo proporcionado por su host entre sí y con el
host. Al ejecutar varios contenedores en un host (físico o virtual) se comparte el kernel
del sistema operativo del host. Existe un solo kernel de sistema operativo proporcionado
por el host y utilizado por todos los contenedores que se ejecutan sobre él.
Los contenedores también se encuentran totalmente aislados del host y otros contenedores,
como una máquina virtual. Los contenedores usan espacios de nombres del sistema operativo,
grupos de control en Linux, para proporcionar la percepción de un nuevo entorno de sistema
operativo y utilizan técnicas de virtualización del sistema operativo específicas en Windows.
Cada contenedor obtiene su propia copia de los recursos del sistema operativo.

Docker
Docker proporciona funciones de administración para los contenedores. Se compone de
dos archivos ejecutables:

  • Demonio de Docker
  • Cliente de Docker

El demonio de Docker es el caballo de batalla para la administración de los contenedores.
Se trata de un servicio de administración encargado de administrar todas las actividades
en el host relacionadas con los contenedores. El cliente de Docker interactúa con el demonio
de Docker y es responsable de capturar las entradas y enviarlas al demonio de Docker.
El demonio de Docker proporciona el entorno de ejecución, bibliotecas, controladores de
gráficos, los motores para crear, administrar y supervisar los contenedores y las imágenes
en el servidor host. También puede crear imágenes personalizadas que se utilizan en la
creación y el envío de aplicaciones a múltiples entornos.
Dockerfile
Dockerfile es el módulo principal para crear imágenes de contenedor. Es un archivo
legible por humanos basado en texto simple sin ninguna extensión e incluso se llama
Dockerfile. Aunque existe un mecanismo para nombrarlo de manera diferente,
generalmente se denomina Dockerfile. DockerFile contiene instrucciones para crear
una imagen personalizada utilizando una imagen base. Estas instrucciones las ejecuta
secuencialmente de arriba a abajo el demonio de Docker. Las instrucciones hacen
referencia al comando y sus parámetros, como COPY, ADD, RUN y ENTRYPOINT. Dockerfile
habilita las prácticas de IaC al convertir la implementación y la configuración de la
aplicación en instrucciones que se pueden versionar y almacenar en un repositorio
de código fuente. Echemos un vistazo a los pasos de compilación en la siguiente sección.
La canalización de compilación
No hay diferencia, desde la perspectiva de compilación, entre el contenedor y una solución
basada en máquina virtual. El paso de compilación no cambia. A continuación, se muestra
una canalización de versión típica para la implementación basada en contenedores de IaaS.
La canalización de versión
La única diferencia entre una canalización de versión típica para la implementación basada
en contenedores de IaaS y la canalización de versión es la administración de la imagen
del contenedor y la creación de contenedores utilizando Dockerfile y Docker Compose.
Las utilidades avanzadas de administración de contenedores, como Docker Swarm, DC/OS
y Kubernetes, también se pueden implementar y configurar como parte de la administración
de la versión. Sin embargo, hay que tener en cuenta que estas herramientas de administración
de contenedores deben formar parte de la canalización de versión de servicios compartidos,
como se explicó anteriormente. En la Figura 13.19 se muestra una canalización de versión
típica para una solución basada en contenedor:

La sección siguiente se centra en la integración con otros conjuntos de herramientas,
como Jenkins.
Azure DevOps y Jenkins
Azure DevOps es un orquestador de plataforma abierta que se integra con otras herramientas
del orquestador sin problemas. Proporciona toda la infraestructura necesaria, así como
características que se integran bien con Jenkins. Las organizaciones con canalizaciones
de CI/CD bien establecidas creadas en Jenkins pueden reutilizarlas con las características
avanzadas pero sencillas de Azure DevOps para organizarlas.
Jenkins se puede usar como repositorio y puede ejecutar canalizaciones de CI/CD en Azure
DevOps, a la vez que también es posible tener un repositorio en Azure DevOps y ejecutar
canalizaciones de CI/CD en Jenkins.

La configuración de Jenkins se puede agregar en Azure DevOps como enlaces de servicio y,
siempre que se confirme cualquier cambio de código en el repositorio de Azure DevOps,
puede desencadenar canalizaciones en Jenkins. En la Figura 13.20 se muestra la configuración
de Jenkins desde la sección de configuración del enlace de servicio de Azure DevOps:

Hay varios desencadenadores que ejecutan las canalizaciones en Jenkins. Uno de ellos es
el código insertado, como se muestra en la Figura 13.21:

También es posible hacer la implementación en la máquina virtual de Azure y ejecutar
canalizaciones de versión de Azure DevOps, como se explica aquí: https://docs.microsoft.
com/azure/virtual-machines/linux/tutorial-build-deploy-jenkins.
Jenkins ya debe implementarse antes de utilizarse en cualquier escenario. El proceso de
implementación en Linux se puede encontrar en https://docs.microsoft.com/azure/
virtual-machines/linux/tutorial-jenkins-github-docker-cicd.
La siguiente sección estará más centrada en las herramientas y servicios relacionados con
la administración de la configuración. Azure Automation proporciona servicios relacionados
con DSC, como el servidor de extracción.
Azure Automation
Azure Automation es la plataforma de Microsoft para todas las implementaciones de
automatización con respecto al cloud, en implementaciones on-premises e híbridas. Azure
Automation es una plataforma de automatización madura que proporciona capacidades
enriquecidas en los siguientes términos:

  • Definir activos, como variables, conexiones, credenciales, certificados y módulos
  • Implementar runbooks utilizando Python, scripts de PowerShell y flujos de trabajo
    de PowerShell
  • Proporcionar interfaces de usuario para crear runbooks
  • Administrar el ciclo de vida completo del runbook, incluyendo compilación, prueba
    y publicación
  • Programar runbooks
  • La capacidad para ejecutar runbooks en cualquier lugar: en el cloud u on-premises
  • DSC como plataforma de administración de la configuración
  • Administrar y configurar entornos: Windows y Linux, aplicaciones e implementación
  • La posibilidad de extender Azure Automation mediante la importación de módulos
    personalizados

Azure Automation proporciona un servidor de extracción de DSC que ayuda a crear un
servidor de administración de la configuración centralizado que consiste en configuraciones
para nodos/máquinas virtuales y sus componentes.
Implementa el patrón de tipo hub y spoke donde los nodos pueden conectarse al servidor de
extracción de DSC y descargar las configuraciones asignadas a ellos y reconfigurarse para
reflejar su estado deseado. Los agentes de DSC corrigen cualquier cambio o desviación dentro
de estos nodos la próxima vez que se ejecutan. Esto garantiza que los administradores no
tengan que supervisar activamente el entorno para encontrar cualquier desviación.

DSC proporciona un lenguaje declarativo en el cual se definen la intención y la configuración,
pero no cómo ejecutar y aplicar esas configuraciones. Estas configuraciones se basan en el
lenguaje de PowerShell y facilitan el proceso de administración de la configuración.
En esta sección, analizaremos una implementación simple del uso de DSC de Azure Automation
para configurar una máquina virtual para instalar y configurar el servidor web (IIS) y crear un
archivo index.htm que informe a los usuarios de que el sitio web está en mantenimiento.
A continuación, aprenderás a aprovisionar una cuenta de Azure Automation.
Aprovisionar una cuenta de Azure Automation
Crea una nueva cuenta de Azure Automation desde Azure Portal o PowerShell en un grupo
de recursos nuevo o existente. En la Figura 13.22 puedes observar que Azure Automation
proporciona elementos de menú para DSC:

Esta solución ofrece las siguientes prestaciones:

  • Nodos de DSC: enumeran todas las máquinas virtuales y contenedores que están
    alistados con el servidor de extracción de DSC de Azure Automation actual. Estas
    máquinas virtuales y contenedores se administran utilizando configuraciones del
    servidor de extracción de DSC actual.
  • Configuraciones de DSC: enumeran todas las configuraciones sin procesar de
    PowerShell importadas y cargadas en el servidor de extracción de DSC. Tienen un
    formato legible por humanos y no tienen un estado compilado.
  • Configuraciones de nodos de DSC: enumeran todas las compilaciones de configuraciones
    de DSC disponibles en el servidor de extracción que se asignarán a los nodos: máquinas
    virtuales y contenedores. Una configuración de DSC produce archivos MOF después de
    las compilaciones y, finalmente, se utilizan para configurar los nodos.

Después de aprovisionar una cuenta de Azure Automation, podemos crear una
configuración de DSC de ejemplo, c omo se muestra en la siguiente sección.
Crear una configuración de DSC
El siguiente paso es escribir una c onfiguración de DSC utilizando cualquier e ditor
de PowerShell para reflejar la intención de la configuración. Para este ejemplo,
se crea una configuración individual, ConfigureSiteOnIIS. Importa el módulo
de DSC base, PSDesiredStateConfiguration, que consta de recursos utilizados
en la configuración. También declara un nodo de ser vidor web. Después de cargar
y compilar esta configuración, generará una configuración de DSC denominada
ConfigureSiteOnIISwebserver. Esta configuración puede aplicarse a los nodos.
La configuración consta de unos pocos recursos. Estos recursos configuran el nodo
de destino. Los recursos instalan un servidor web, ASP.NET, y un marco de trabajo y crean
un archivo index.htm dentro del directorio inetpub\wwwroot con contenido para mostrar
que el sitio está en mantenimiento. Para obtener más información sobre la escritura de la
configuración de DSC, consulta https://docs.microsoft.com/powershell/scripting/dsc/
getting-started/wingettingstarted?view=powershell-7.
En la siguiente lista de código se muestra la configuración completa descrita en el párrafo
anterior. Esta configuración se cargará en la cuenta de Azure Automation:

Después de crear una configuración de DSC de ejemplo, debe importarse dentro de Azure
Automation, como se muestra en la siguiente sección.
Importar la configuración de DSC
La configuración de DSC aún es desconocida para Azure Automation. Está disponible en
algunos equipos locales. Debe cargarse en las configuraciones DSC de Azure Automation.
Azure Automation proporciona el cmdlet Import-AzureRMAutomationDscConfiguration
para importar la configuración a Azure Automation:
Import-AzureRmAutomationDscConfiguration -SourcePath «C:\DSC\AA\DSCfiles\
ConfigureSiteOnIIS.ps1″ -ResourceGroupName «omsauto» -AutomationAccountName
«datacenterautomation» -Published -Verbose
Los comandos importarán la configuración dentro de Azure Automation. Después de la
importación, la configuración de DSC debe compilarse para que pueda asignarse a los
servidores para las comprobaciones de cumplimiento y la autocorrección.

Compilar la configuración de DSC
Una vez que la configuración de DSC esté disponible en Azure Automation, se puede
solicitar que se compile. Azure Automation proporciona otro cmdlet para esto. Utiliza
el cmdlet Start-AzureRmAutomationDscCompilationJob para compilar la configuración
importada. El nombre de la configuración debe coincidir con el nombre de la configuración
cargada. La compilación crea un archivo MOF con el nombre de la configuración y el
nombre del nodo, que en este caso es el servidor web ConfigureSiteOnIIS. La ejecución
del comando se muestra aquí:
Start-AzureRmAutomationDscCompilationJob -ConfigurationName ConfigureSiteOnIIS
-ResourceGroupName «omsauto» -AutomationAccountName «datacenterautomation»
-Verbose
Ahora has realizado la configuración de nodos de DSC. En la siguiente sección, aprenderás
a asignar configuraciones a nodos.
Asignar configuraciones a los nodos
Las configuraciones de DSC compiladas se pueden aplicar a los nodos. Utiliza
Register-AzureRmAutomationDscNode para asignar la configuración a un nodo. El
parámetro NodeConfigurationName identifica el nombre de configuración que debe
aplicarse al nodo. Este es un cmdlet potente que también puede configurar el agente de
DSC, que es localconfigurationmanager, en los nodos antes de que puedan descargar
configuraciones y aplicarlas. Hay varios parámetros localconfigurationmanager que se
pueden configurar. Los detalles sobre los mismos están disponibles en https://devblogs.
microsoft.com/powershell/understanding-meta-configuration-in-windows-powershelldesired-
state-configuration.
Vamos a ver la configuración siguiente:
Register-AzureRmAutomationDscNode -ResourceGroupName «omsauto»
-AutomationAccountName «datacenterautomation» -AzureVMName testtwo
-ConfigurationMode ApplyAndAutocorrect -ActionAfterReboot ContinueConfiguration
-AllowModuleOverwrite $true -AzureVMResourceGroup testone -AzureVMLocation
«West Central US» -NodeConfigurationName «ConfigureSiteOnIIS.WebServer»
-Verbose
Ahora, podemos probar si la configuración se ha aplicado a los servidores si navegamos por
el sitio web recién implementado mediante un navegador. Una vez que la prueba se haya
completado correctamente, pasaremos a validar las conexiones.

Validación
Si corresponde, los grupos de seguridad de la red y los firewalls se abren y habilitan para el
puerto 80 y se asigna una IP pública a la máquina virtual. Se puede navegar por el sitio web
predeterminado usando la dirección IP. De lo contrario, inicia sesión en la máquina virtual
que se utiliza para aplicar la configuración de DSC y dirígete a http://localhost.
Debe mostrar la siguiente página:

Este es el poder de la administración de la configuración: sin escribir ningún código
significativo, la creación de una configuración una vez puede aplicarse varias veces a los
mismos y múltiples servidores y tienes la seguridad de que se ejecutarán en el estado
deseado sin ninguna intervención manual. En la siguiente sección, echaremos un vistazo
a las diversas herramientas disponibles para Azure DevOps.
Herramientas para DevOps
Como se ha mencionado anteriormente, Azure es una plataforma enriquecida y madura que
admite lo siguiente:

  • Varias opciones de lenguajes
  • Varias opciones de sistemas operativos
  • Varias opciones de herramientas y utilidades
  • Varios patrones para implementar soluciones (como máquinas virtuales, servicios de
    aplicaciones, contenedores y microservicios)

Con tantas opciones y elecciones, Azure ofrece lo siguiente:

  • Cloud abierto: está abierto para productos, herramientas y servicios de código
    abierto, de Microsoft y de terceros.
  • Cloud flexible: es lo suficientemente fácil para que usuarios finales y desarrolladores
    lo utilicen con sus competencias y conocimientos existentes.
  • Administración unificada: proporciona funciones de supervisión y administración sin
    problemas.

Todos los servicios y capacidades mencionados aquí son importantes para la implementación
exitosa de DevOps. En la Figura 13.24 se muestran las herramientas y utilidades de código
abierto que se pueden usar para diferentes fases de la administración del ciclo de vida de la
aplicación y en las DevOps en general:

En la Figura 13.24 se muestran las herramientas y utilidades de Microsoft que se pueden usar
para diferentes fases de la administración del ciclo de vida de la aplicación y en las DevOps
en general. Una vez más, esta es solo una pequeña representación de todas las herramientas
y utilidades, ya que hay muchas más opciones disponibles, como las siguientes:

  • Orquestación de compilación de Azure DevOps para construir una canalización de
    compilación
  • Microsoft Test Manager y Pester para la realización de pruebas
  • Plantillas de DSC, PowerShell y ARM para la implementación o administración de la
    configuración
  • Log Analytics, Application Insights y System Center Operations Manager (SCOM)
    para alertas y supervisión
  • Azure DevOps y System Center Service Manager para procesos de administración:

Hay muchas herramientas disponibles para cada una de las prácticas de DevOps y, en esta
sección, has visto algunas de las herramientas y el modo de configurarlas.
Resumen
DevOps está ganando mucha tracción e impulso en la industria. La mayoría de las
organizaciones se han dado cuenta de sus beneficios y tienen la intención de implementar
DevOps. Esto está sucediendo mientras la mayoría se están trasladando al cloud. Azure,
como plataforma de cloud, presta servicios de DevOps enriquecidos y maduros, lo que
facilita que las organizaciones implementen DevOps.
En este capítulo, hemos hablado de DevOps junto con sus prácticas básicas, como
la administración de la configuración, la integración y la entrega continuas y la
implementación. También hemos hablado sobre diferentes soluciones de cloud basadas
en PaaS, IaaS de máquinas virtuales e IaaS de contenedores, junto con sus respectivos
recursos de Azure, las canalizaciones de compilación y versión.
La administración de la configuración también se ha explicado en el capítulo, junto con los
servicios de DSC de Azure Automation y el uso de servidores de extracción para configurar
máquinas virtuales automáticamente. Finalmente, hemos tratado la apertura y flexibilidad
de Azure con respecto a las opciones de lenguajes, herramientas y sistemas operativos.
En el siguiente capítulo, analizaremos los detalles de Kubernetes y sus componentes e
interacciones, además de las consideraciones de diseño e implementación de aplicaciones
en Kubernetes.