Editar

Compartir a través de


CI/CD para un front-end de aplicación sin servidor en Azure

Azure Pipelines

La informática sin servidor consiste en eliminar los servidores, la infraestructura y los sistemas operativos, lo que permite a los desarrolladores centrarse en el desarrollo de aplicaciones. Una sólida CI/CD (Integración continua/Entrega continua) de estas aplicaciones permite a las empresas distribuir versiones de software completamente probadas e integradas en cuestión de minutos de desarrollo. Proporciona una red troncal del entorno DevOps moderno.

¿Qué significa realmente CI/CD?

  • La integración continua (CI) permite a los equipos de desarrollo integrar los cambios de código en un repositorio compartido de forma casi instantánea. Esta capacidad, junto con las pruebas y compilaciones automatizadas antes de que se integren los cambios, garantiza que solo el código de aplicación totalmente funcional está disponible para la implementación.
  • La entrega continua (CD) permite que los cambios en el código fuente, la configuración, el contenido y otros artefactos se entreguen a producción y estén listos para implementarse en los usuarios finales, de la manera más rápida y segura posible. El proceso mantiene el código en un estado implementable en todo momento. Un caso especial de esto es la implementación continua, que incluye la implementación real para los usuarios finales.

En este artículo se describe una canalización de CI/CD para el front-end web de una implementación de referencia sin servidor. Esta canalización se desarrolla mediante los servicios de Azure. El front-end web muestra una aplicación web moderna, con JavaScript del lado cliente, varias API del lado servidor reutilizables y marcado precompilado, que también se denomina Jamstack. Puede encontrar el código en este repositorio de GitHub. El archivo Léame describe los pasos para descargar, compilar e implementar la aplicación.

En el siguiente diagrama se describe la canalización de CI/CD que se usa en este front-end de ejemplo:

Canalización de CI/CD en una aplicación sin servidor con los servicios de Azure

En este artículo no se explica qué es la implementación de back-end.

Requisitos previos

Para trabajar con esta aplicación de ejemplo, asegúrese de que dispone de lo siguiente:

  • Una cuenta de GitHub.
  • Una cuenta de Azure. En caso de no tener ninguna, puede probar con una cuenta gratuita de Azure.
  • Una organización de Azure DevOps. Si no tiene una, puede probar con un plan básico, que incluye servicios de DevOps como Azure Pipelines.

Usar un sistema de control de versiones en línea

Los sistemas de control de versiones realizan un seguimiento de los cambios en el código fuente y los controlan. Mantener el código fuente en un sistema de control de versiones en línea permite que varios equipos de desarrollo puedan colaborar. También es más fácil de mantener que un control de versiones tradicional local. Estos sistemas en línea se pueden integrar fácilmente con los principales servicios de CI/CD. Puede crear y mantener el código fuente en varios directorios, junto con archivos de compilación y configuración, en lo que se denomina un repositorio.

Los archivos de proyecto de esta aplicación de ejemplo se guardan en GitHub. Si no tiene una cuenta de GitHub, lea esta documentación para empezar a trabajar con los repositorios de GitHub.

Automatización de la compilación y la implementación

El uso de un servicio de CI/CD, como Azure Pipelines puede servir para automatizar los procesos de compilación e implementación. Puede crear varias fases en la canalización, donde cada una de ellas se ejecuta según el resultado de la anterior. Las fases se pueden ejecutar en un contenedor de Windows o Linux. El script debe asegurarse de que las herramientas y los entornos están configurados correctamente en el contenedor. Azure Pipelines puede ejecutar diversas herramientas de compilación y puede trabajar con bastantes sistemas de control de versiones en línea.

Integrar herramientas de compilación

Las herramientas de compilación modernas pueden simplificar el proceso de compilación y proporcionar funciones como la configuración previa, la minificación de los archivos JavaScript y la generación de sitios estática. Los generadores de sitios estáticos pueden compilar archivos de marcado antes de implementarlos en los servidores de hospedaje, lo que da lugar a una experiencia de usuario rápida. Puede seleccionar entre una variedad de estas herramientas, según el tipo de lenguaje de programación y plataforma de la aplicación, así como las funciones adicionales necesarias. En este artículo se proporciona una lista de las herramientas de compilación populares para una aplicación moderna.

El ejemplo es una aplicación React, creada mediante Gatsby.js, que es un generador de sitios estáticos y un marco de desarrollo de front-end. Estas herramientas se pueden ejecutar localmente durante las fases de desarrollo y pruebas y, después, integrarse con Azure Pipelines para la implementación final.

En el ejemplo se usa el archivo gatsby-ssr.js para la representación y gatsby-config.js para la configuración del sitio. Gatsby convierte todos los archivos JavaScript en el subdirectorio pages de la carpeta src en archivos HTML. Los componentes adicionales van en el subdirectorio components. En el ejemplo también se usa el complemento gatsby-plugin-typescript que permite usar TypeScript para la seguridad de tipos, en lugar de JavaScript.

Para más información sobre cómo configurar un proyecto de Gatsby, vea la documentación oficial de Gatsby.

Automatizar compilaciones

La automatización del proceso de compilación reduce los errores humanos que se pueden introducir en los procesos manuales. El archivo azure-pipelines.yml incluye el script para una automatización en dos fases. El archivo Léame de este proyecto describe los pasos necesarios para configurar la canalización de la automatización mediante Azure Pipelines. En las subsecciones siguientes se muestra cómo se configuran las fases de canalización.

Fase de compilación

Puesto que Azure Pipelines se integra con el repositorio de GitHub, cualquier cambio en el directorio del que se realiza el seguimiento de la rama principal desencadena la primera fase de la canalización, la de compilación:

trigger:
  batch: true
  branches:
    include:
    - main
  paths:
    include:
    - src/ClientApp

En el fragmento de código siguiente se muestra el inicio de la fase de compilación, que inicia un contenedor de Ubuntu para ejecutar esta fase.

    stages:
    - stage: Build
      jobs:
      - job: WebsiteBuild
        displayName: Build Fabrikam Drone Status app
        pool:
          vmImage: 'Ubuntu-16.04'
        continueOnError: false
    steps:

Esto va seguido de tareas y scripts necesarios para compilar correctamente el proyecto. Entre ellas, figuran:

  • Instalar Node.js y configurar variables de entorno;

  • Instalar y ejecutar Gatsby.js que crea el sitio web estático:

        - script: |
            cd src/ClientApp
            npm install
            npx gatsby build
          displayName: 'gatsby build'
    
  • Instalar y ejecutar una herramienta de compresión denominada brotli para comprimir los archivos compilados antes de la implementación:

        - script: |
            cd src/ClientApp/public
            sudo apt-get install brotli --install-suggests --no-install-recommends -q --assume-yes
            for f in $(find . -type f \( -iname '*.html' -o -iname '*.map' -o -iname '*.js' -o -iname '*.json' \)); do brotli $f -Z -j -f -v && mv ${f}.br $f; done
          displayName: 'enable compression at origin level'
    
  • Calcular la versión de la compilación actual para la administración de memoria caché;

  • Publicar los archivos compilados para usarlos en la fase de implementación:

        - task: PublishPipelineArtifact@1
          inputs:
            targetPath: 'src/ClientApp/public'
            artifactName: 'drop'
    

Al completar correctamente la fase de compilación, se anula el entorno de Ubuntu y se desencadena la fase de implementación en la canalización.

Fase de implementación

La fase de implementación se ejecuta en un nuevo contenedor de Ubuntu:

    - stage: Deploy
      jobs:
      - deployment: WebsiteDeploy
        displayName: Deploy Fabrikam Drone Status app
        pool:
          vmImage: 'Ubuntu-16.04'
        environment: 'fabrikamdronestatus-prod'
        strategy:
          runOnce:
            deploy:
              steps:

Esta fase incluye varias tareas y scripts de implementación para:

  • Descargar los artefactos de compilación en el contenedor (lo que sucede automáticamente como consecuencia de usar PublishPipelineArtifact en la fase de compilación);
  • Grabar la versión de lanzamiento de la compilación y actualizar en el repositorio de GitHub;
  • Cargar los archivos del sitio web en Blob Storage, en una nueva carpeta correspondiente a la nueva versión;
  • Cambiar la red CDN para que apunte a esta nueva carpeta.

Los dos últimos pasos juntos replican una eliminación de caché, ya que los servidores perimetrales de la red CDN ya no pueden tener acceso a las carpetas más antiguas. En este fragmento de código se muestra cómo se consigue esto:

       - script: |
              az login --service-principal -u $(azureArmClientId) -p $(azureArmClientSecret) --tenant $(azureArmTenantId)
              # upload content to container versioned folder
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.html" --content-type "text/html"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.js" --content-type "application/javascript"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.js.map" --content-type "application/octet-stream"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.json" --content-type "application/json"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --pattern "*.txt" --content-type "text/plain"
              # target new version
              az cdn endpoint update --resource-group $(azureResourceGroup) --profile-name $(azureCdnName) --name $(azureCdnName) --origin-path '/$(releaseSemVer)'
              AZURE_CDN_ENDPOINT_HOSTNAME=$(az cdn endpoint show --resource-group $(azureResourceGroup) --name $(azureCdnName) --profile-name $(azureCdnName) --query hostName -o tsv)
              echo "Azure CDN endpoint host ${AZURE_CDN_ENDPOINT_HOSTNAME}"
              echo '##vso[task.setvariable variable=azureCndEndpointHost]'$AZURE_CDN_ENDPOINT_HOSTNAME
            displayName: 'upload to Azure Storage static website hosting and purge Azure CDN endpoint'

Implementaciones atómicas

La implementación atómica garantiza que los usuarios de su sitio web o aplicación siempre obtienen el contenido correspondiente a la misma versión.

En la canalización de CI/CD de ejemplo, el contenido del sitio web se implementa en el almacenamiento de blobs, que actúa como el servidor de origen para Azure CDN. Si los archivos se actualizan en la misma carpeta raíz en el BLOB, el sitio web se atenderá de manera incoherente. Este problema se resuelve al cargar en una nueva carpeta con versión, como se muestra en la sección anterior. Los usuarios obtienen todo o nada de la nueva compilación correcta, ya que la red CDN apunta a la nueva carpeta como origen, solo después de que todos los archivos se actualicen correctamente.

Implementación con versión

Las ventajas de este enfoque son las siguientes:

  • Como el nuevo contenido no está disponible para los usuarios hasta que CDN apunta a la nueva carpeta de origen, se produce una implementación atómica.
  • Puede revertir fácilmente a una versión anterior del sitio web si es necesario.
  • Dado que el origen puede hospedar varias versiones del sitio web en paralelo, puede ajustar la implementación mediante técnicas como permitir la vista previa de determinados usuarios antes de obtener una disponibilidad más amplia.

Hospedar y distribuir a través de la nube

Una red de entrega de contenido (CDN) es un conjunto de servidores distribuidos que agilizan la entrega de contenido a los usuarios a través de una gran zona geográfica. Cada usuario obtiene el contenido del servidor más cercano. La red CDN accede a este contenido desde un servidor de origen y lo almacena en la memoria caché para servidores perimetrales en ubicaciones estratégicas. En el ejemplo de CI/CD de este artículo se usa Azure CDN, que apunta al contenido del sitio web hospedado en Azure Blob Storage como el servidor de origen. El almacenamiento de blobs está configurado para el hospedaje de sitios web estáticos. Para obtener una guía rápida sobre cómo usar Azure CDN con Azure Blob Storage, lea Inicio rápido: Integración de una cuenta de Azure Storage en Azure CDN.

Estas son algunas estrategias que pueden mejorar el rendimiento de la red CDN.

Comprimir el contenido

Comprimir los archivos antes de entregarlos mejora la velocidad de transferencia de archivos y aumenta el rendimiento de carga de página para los usuarios finales.

Existen dos formas de hacerlo:

  1. Sobre la marcha en los servidores perimetrales de la red CDN. Esto mejora el consumo de ancho de banda en un porcentaje considerable, lo que hace que el sitio web sea mucho más rápido que sin compresión. Es relativamente fácil habilitar este tipo de compresión en Azure CDN. Puesto que está controlado por la red CDN, no puede elegir ni configurar la herramienta de compresión. Use esta compresión si el rendimiento del sitio web no es algo crítico.

  2. Comprimir previamente antes de llegar a la red CDN, ya sea en el servidor de origen o antes de llegar al origen. La compresión previa mejora aún más el rendimiento en tiempo de ejecución del sitio web, ya que se realiza antes de que lo capture la red CDN. La canalización de CI/CD de ejemplo comprime los archivos compilados en la fase de implementación, mediante brotli, como se muestra en la sección sobre compilación anterior. Estas son las ventajas de usar la compresión previa:

    1. Puede usar cualquier herramienta de compresión con la que esté familiarizado y ajustar aún más la compresión. Las redes CDN pueden tener limitaciones en las herramientas que usan.
    2. Algunas redes CDN limitan los tamaños de archivo que se pueden comprimir sobre la marcha, lo que produce un impacto en el rendimiento de los archivos más grandes. La compresión previa no establece ningún límite en el tamaño del archivo.
    3. Al comprimir previamente en la canalización de implementación, se necesita menos almacenamiento en el origen.
    4. Esto es más rápido y eficaz que la compresión de la red CDN.

Para más información, consulte Mejora del rendimiento comprimiendo archivos en Azure CDN.

Aceleración de sitios dinámicos

El uso de la red CDN es ideal para el contenido estático, que se puede almacenar en caché de forma segura en los servidores perimetrales. Pero los sitios web dinámicos necesitan que el servidor genere contenido en función de la respuesta del usuario. Este tipo de contenido no se puede almacenar en caché en el perímetro, para lo que se necesita una solución integral más compleja que pueda acelerar la entrega de contenido. La aceleración de sitios dinámicos por Azure CDN es una solución de este tipo que mejora el rendimiento de las páginas web dinámicas.

Este ejemplo habilita la aceleración de sitios dinámicos como se muestra en esta sección del archivo Léame.

Administrar caché de sitios web

Las redes CDN usan el almacenamiento en caché para mejorar su rendimiento. La configuración y la administración de esta caché se convierte en una parte integral de la canalización de implementación. En la documentación de Azure CDN se muestran varias maneras de hacerlo. Puede establecer reglas de almacenamiento en caché en la red CDN, así como configurar el período de vida para el contenido en el servidor de origen. El contenido web estático puede almacenarse en caché durante mucho tiempo, ya que es posible que no cambie demasiado con el tiempo. Esto reduce la sobrecarga de tener acceso al servidor de origen único para cada solicitud de usuario. Para más información, consulte Cómo funciona el almacenamiento en caché.

Purga de la memoria caché

La red CDN almacena en caché los archivos del sitio web en los servidores perimetrales hasta que expire el período de vida. Estos se actualizan para una nueva solicitud de cliente, solo después de que expire el período de vida. Es necesario eliminar la memoria caché de la red CDN para garantizar que todos los usuarios obtengan los archivos más recientes del sitio web activo, especialmente si la implementación se produce en la misma carpeta de origen de la red CDN. Azure CDN permite eliminar la memoria caché de Azure Portal.

Un mejor enfoque consiste en invalidar esta caché mediante el uso del control de versiones durante la implementación. Una depuración o expiración de caché explícita normalmente hace que la red CDN recupere las versiones más recientes del contenido web. Aunque, dado que la red CDN siempre señala a la versión más reciente de la implementación, esto mejora el almacenamiento en caché de la siguiente manera:

  1. La red CDN valida index.html con el origen para cada nueva instancia de sitio web.
  2. Excepto en el caso de index.html y 404.html, todos los demás archivos del sitio web se firman y se almacenan en caché durante un año. Esto se basa en la suposición de que los recursos, como las imágenes y los vídeos, no necesitan cambios frecuentes. Si estos archivos se actualizan y se vuelven a generar, los nombres se actualizan con un nuevo GUID de huella digital. Como resultado, se actualiza el archivo index.html con una referencia actualizada al archivo de recursos modificado. Después, la red CDN recupera el archivo index.html actualizado y, dado que no encuentra el archivo de recursos de referencia en su memoria caché, también recupera los archivos de recursos modificados.

Esto garantiza que la red CDN siempre obtiene nuevos archivos actualizados y elimina la necesidad de eliminar la memoria caché para una nueva compilación.

Colaboradores

Microsoft mantiene este artículo. Originalmente lo escribieron los siguientes colaboradores.

Autor principal:

Para ver los perfiles no públicos de LinkedIn, inicie sesión en LinkedIn.

Pasos siguientes