Gestiona tus configuraciones de NGINX con GitHub

NGINX | 04 de diciembre de 2023

Los ajustes, las opciones y las configuraciones de software adoptan muchas formas diferentes. En un extremo del espectro se encuentran las interfaces gráficas elegantes y ágiles, diseñadas para ser intuitivas y, al mismo tiempo, evitar estados no válidos. En el otro extremo: los archivos de texto. Aunque tanto los ingenieros como los equipos de DevOps elogian los archivos de texto por su claridad, su potencial de automatización y sus requisitos mínimos de uso (seguramente tienes unas cuantas ventanas de terminal abiertas, ¿verdad?), configurar software con ellos conlleva claras contrapartidas. Por ejemplo, intenta encontrar a un usuario de Linux que no haya conseguido bloquear un paquete de software por configurar incorrectamente un archivo de texto.

Como única solución de software todo en uno que integra proxy, balanceador de carga, servidor web y puerta de enlace de API, NGINX es un componente clave de la infraestructura moderna de Internet. Una infraestructura que, en la mayoría de los casos, se basa en sistemas operativos sustentados por el kernel de Linux. Para adaptarse a este ecosistema y a los profesionales que lo mantienen, NGINX depende en gran medida de configuraciones basadas en texto.

El módulo F5 NGINX Instance Manager lleva mucho tiempo siendo la solución de referencia para orquestar configuraciones relacionadas con NGINX. Ofrece funciones avanzadas para gestionar configuraciones de forma remota y por lotes mediante su intuitiva interfaz de usuario y su API, además de documentación de apoyo y mecanismos de protección. Sin embargo, los archivos de configuración individuales de NGINX se parecen mucho al código, y los equipos de software ya cuentan con una herramienta extraordinaria para gestionarlo: Git. Git ofrece a los equipos de desarrollo y operaciones multitud de funciones orientadas a gestionar flujos de trabajo con archivos de texto.

La nueva integración de Instance Manager con Git y otros sistemas externos permite utilizar funciones como el control de versiones, la contribución descentralizada, los flujos de trabajo de aprobación y la coordinación de equipos. Plataformas como GitHub y GitLab amplían este conjunto de funciones con integración y despliegue continuos (CI/CD), colaboración, seguimiento de incidencias y otras prestaciones útiles a través de una interfaz de usuario web.

En esta entrada del blog mostramos cómo se puede utilizar GitHub para gestionar las configuraciones de NGINX y enviarlas automáticamente a las instancias cada vez que se realiza un cambio.

API de Instance Manager

Instance Manager ofrece un amplio conjunto de API REST que complementan su interfaz de usuario web. Una ventaja clave de la API es su capacidad para actualizar los archivos de configuración de las instancias del plano de datos gestionadas. Recientemente, ampliamos esta funcionalidad para permitir vincular las actualizaciones de configuración a una versión específica del archivo. Cuando se gestionan en un repositorio Git, las configuraciones se pueden etiquetar con un hash de commit de Git. Además, implementamos un nuevo estado en Instance Manager para las configuraciones gestionadas externamente que advierte a quienes intenten editar los archivos de que las configuraciones están bajo gestión externa.

GitHub Actions

GitHub permite a los desarrolladores crear canalizaciones de despliegue personalizadas en sus repositorios mediante una función denominada «Actions». El usuario puede optar por definir sus propias acciones o ejecutar scripts existentes mediante una definición YAML. Estas canalizaciones pueden activarse de diversas formas, por ejemplo, cuando se actualiza un repositorio con un commit o al fusionar una solicitud de incorporación de cambios.

En el ejemplo de este blog, utilizamos GitHub Actions listas para usar y comandos de Linux. Aprenderá a utilizarlos para actualizar los archivos de configuración de NGINX gestionados mediante GitHub en sus instancias de NGINX a través de la API de Instance Manager. Para empezar, siga estos pasos de la documentación de GitHub para crear un nuevo archivo YAML que ejecute Actions en su repositorio.

Configurar los secretos de Actions

Instance Manager admite varias formas de autenticación. En el ejemplo, utilizamos el método de autenticación básica, aunque recomendamos configurar la autenticación OIDC en entornos de producción.

En lugar de almacenar las credenciales de Instance Manager en el repositorio, GitHub permite definir secretos como variables del repositorio. El entorno de Actions puede acceder a estas variables, pero permanecen ocultas en los registros. Sigue estos pasos para almacenar como secretos las claves de nombre de usuario y contraseña de Instance Manager y poder utilizarlas para autenticar tus llamadas a la API.

Aquí, hemos asignado a estas variables los valores NMS_USERNAME y NMS_PASSWORD.

Captura de pantalla de una plataforma tecnológica que muestra las opciones de secretos del repositorio

Configurar variables de Actions

Del mismo modo, en lugar de definir variables constantes en el archivo YAML, puede resultar útil extraerlas para gestionarlas desde la interfaz de usuario de GitHub. En la página Variables encontrará instrucciones para definir variables que se apliquen a todas las acciones del repositorio. En el ejemplo, aprovechamos esta posibilidad para definir el FQDN o la dirección IP de Instance Manager (NMS_HOSTNAME), el identificador del sistema en el que se ejecuta NGINX (SYSTEM_ID) y el identificador de la instancia específica de NGINX que se va a actualizar (INSTANCE_ID).

Captura de pantalla de una plataforma tecnológica que muestra las opciones de variables del repositorio

Nota: Hemos definido estas variables para simplificar nuestro ejemplo, pero puede optar por gestionar de otras formas la información de identificación de Instance Manager, System y NGINX. Por ejemplo, puede crear en su repositorio directorios que contengan configuraciones específicas para distintas instancias y asignarles como nombre los ID de sistema o de instancia. A continuación, podría modificar su script YAML o de Action para que lea los nombres de los directorios y actualice los archivos de configuración de la instancia correspondiente.

Anatomía de la llamada a la API REST de Instance Manager para actualizar las configuraciones de NGINX

La llamada a la API REST de Instance Manager para la actualización de la configuración requiere varios componentes clave para funcionar. El archivo YAML deberá definir cada uno de estos parámetros e incluirlos en la llamada a la API con el formato adecuado.

En el ejemplo, utilizamos la llamada a la API para actualizar una única instancia. Sin embargo, también es posible configurar un grupo de instancias en Instance Manager. De este modo, puede actualizar todas las instancias de un grupo cada vez que se envíe una nueva configuración desde GitHub. Para obtener más información, consulte nuestra guía práctica sobre la publicación de configuraciones.

A continuación se desglosa la llamada a la API REST de actualización de la configuración de Instance Manager:

https://{INSTANCE MANAGER HOSTNAME}/api/platform/v1/systems/{SYSTEM ID}/instances/{INSTANCE ID}/config' 
--header "accept: application/json" 
--header "Authorization: Basic {LOGIN CREDENTIALS}" 
--header 'Content-Type: application/json'
--data '{
    "configFiles": '{
        "rootDir": "/etc/nginx",
        "files": [{
            "contents": "{NGINX CONFIGURATION FILE}",
            "name": "{PATH TO CONFIGURATION FILE ON SYSTEM}"
        }]
    },
    "externalIdType": "{SOURCE OF CONFIGS}",
    "externalId": "{COMMIT HASH}",
    "updateTime": "{TIMESTAMP}"
}'}'

Parámetros del URI

  • Identificador del sistema: Una clave única que identifica el sistema en el que se ejecuta NGINX. En nuestro ejemplo, estos datos se definen en la interfaz Variables de GitHub Actions.
  • Identificador de instancia de NGINX – Una clave única que identifica una instancia específica de NGINX en el sistema. En nuestro ejemplo, estos datos se definen en la interfaz Variables de GitHub Actions.

Parámetros de cabecera

  • Autorización: El método de autorización y las credenciales codificadas en Base64 que Instance Manager utiliza para autenticar la llamada a la API. En el ejemplo, utilizará la autenticación básica con los datos de las credenciales procedentes de los secretos configurados en el repositorio.

Parámetros de datos JSON

  • configFiles – El contenido codificado en Base64 de los archivos de configuración que se están actualizando, junto con sus ubicaciones en el sistema donde se ejecuta NGINX. También deberá proporcionar la ruta al directorio raíz de sus archivos de configuración de NGINX, que suele configurarse como: /etc/nginx.
  • externalIdType – Una etiqueta que identifica el origen del archivo de configuración para Instance Manager. Los valores posibles son git u other. En nuestro ejemplo, asignamos directamente a este parámetro el valor git.
  • externalId – El algoritmo hash seguro (SHA) de la confirmación de Git que identifica el cambio en los archivos de configuración.
  • updateTime – Una cadena que contiene la fecha y hora actuales en el formato %Y-%m-%dT%H:%M:%SZ.

Codificación Base64

Para cumplir con la especificación de la API de Instance Manager, debes transformar determinados datos codificándolos en formato Base64. Aunque las acciones de GitHub existentes no ofrecen una forma nativa de hacerlo, podemos recurrir a herramientas de Linux accesibles desde nuestro YAML.

Credenciales de Instance Manager

Empiece haciendo referencia a las credenciales de inicio de sesión de Instance Manager que se definieron anteriormente como secretos y concaténelas. A continuación, convierta la cadena a Base64, muéstrela mediante echo como una variable de Linux (NMS_LOGIN) y añada el resultado a una variable de entorno predefinida (GITHUB_ENV), a la que puede acceder el ejecutor de Actions.

run: echo "NMS_LOGIN=`echo -n "${{ secrets.NMS_USERNAME }}:${{ secrets.NMS_PASSWORD }}" | base64`" >> $GITHUB_ENV

Marca de tiempo

La API de Instance Manager requiere que se envíe una marca de tiempo con un formato específico en determinadas cargas útiles de la API. Puede generar la marca de tiempo con ese formato mediante el comando date de Linux. Al igual que en el ejemplo anterior, añada la cadena generada como una variable al entorno de Linux.

run: echo "NMS_TIMESTAMP=`date -u +"%Y-%m-%dT%H:%M:%SZ"`" >> $GITHUB_ENV

Configuraciones de NGINX

A continuación, añade al repositorio las configuraciones de NGINX que quieras gestionar. Hay muchas formas de añadir archivos a un repositorio de GitHub. Para obtener más información, consulta esta guía de la documentación de GitHub. Para seguir nuestro ejemplo, puedes crear en tu repositorio de GitHub una estructura de directorios que reproduzca la de la instancia.

La siguiente entrada YAML lee el archivo de configuración de su repositorio, codifica su contenido en Base64 y añade el resultado a una variable de entorno, como antes.

run: echo "NGINX_CONF_CONFIG_FILE=`cat nginx-server/etc/nginx/nginx.conf | base64 -w 0`" >> $GITHUB_ENV

En nuestro ejemplo, repetimos este proceso para cada archivo de configuración de nuestro repositorio de GitHub.

Integración de todos los elementos

Por último, puede utilizar la implementación de referencia de ejemplo de GitHub para reunir todo lo aprendido en un archivo YAML funcional. Tal como se define en el archivo, todos los scripts de GitHub Actions asociados se ejecutarán cada vez que un usuario actualice el repositorio mediante un commit o una solicitud de incorporación de cambios. La última entrada del archivo YAML ejecutará un comando curl que realizará la llamada a la API correspondiente e incluirá los datos necesarios para que Instance Manager actualice todos los archivos de configuración relacionados.

Nota: Usa la entrada de ejecución multilínea (run: |) en tu archivo YAML para ejecutar el comando curl, ya que esto indica al intérprete de YAML que trate los dos puntos «:» como texto en la parte de la entrada correspondiente a los parámetros.

name: Managing NGINX configs with GitHub and GitHub Actions 
# Controls when the workflow will run 
on: 
  # Triggers the workflow on push or pull request events but only for the "main" branch 
  push: 
    branches: [ "main" ] 
  pull_request: 
    branches: [ "main" ] 
  
  # Allows you to run this workflow manually from the Actions tab 
  workflow_dispatch: 

# A workflow run is made up of one or more jobs that can run sequentially or in parallel 
jobs: 
  # This workflow contains a single job called "build" 
  build: 
    # The type of runner that the job will run on 
    runs-on: ubuntu-latest 

    # Steps represent a sequence of tasks that will be executed as part of the job 
    steps: 
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 
      - uses: actions/checkout@v4 

      - name: Set environment variable for NMS API login credentials 
        run: echo "NMS_LOGIN=`echo -n "${{ secrets.NMS_USERNAME }}:${{ secrets.NMS_PASSWORD }}" | base64`" >> $GITHUB_ENV 

      - name: Set environment variable for NMS API timestamp 
        run: echo "NMS_TIMESTAMP=`date -u +"%Y-%m-%dT%H:%M:%SZ"`" >> $GITHUB_ENV 

      - name: Set environment variable for base64 encoded config file 
        run: echo "NGINX_CONF_CONFIG_FILE=`cat app-sfo-01/etc/nginx/nginx.conf | base64 -w 0`" >> $GITHUB_ENV 

      - name: Set environment variable for base64 encoded config file 
        run: echo "MIME_TYPES_CONFIG_FILE=`cat app-sfo-01/etc/nginx/mime.types | base64 -w 0`" >> $GITHUB_ENV 

      - name: Set environment variable for base64 encoded config file 
        run: echo "DEFAULT_CONF_CONFIG_FILE=`cat app-sfo-01/etc/nginx/conf.d/default.conf | base64 -w 0`" >> $GITHUB_ENV 

      - name: Set environment variable for base64 encoded config file 
        run: echo "SSL_CONF_CONFIG_FILE=`cat app-sfo-01/etc/nginx/conf.d/ssl.conf | base64 -w 0`" >> $GITHUB_ENV 

      - name: API call to Instance Manager 
        run: | 
          curl --location 'https://${{ vars.NMS_HOSTNAME }}/api/platform/v1/systems/${{ vars.SYSTEM_ID }}/instances/${{ vars.INSTANCE_ID }}/config' --header "accept: application/json" --header "Authorization: Basic ${{ env.NMS_LOGIN }}" --header 'Content-Type: application/json' --data '{"configFiles": {"rootDir": "/etc/nginx","files": [{"contents": "${{ env.NGINX_CONF_CONFIG_FILE }}","name": "/etc/nginx/nginx.conf"},{"contents": "${{ env.MIME_TYPES_CONFIG_FILE }}","name": "/etc/nginx/mime.types"},{"contents": "${{ env.DEFAULT_CONF_CONFIG_FILE }}","name": "/etc/nginx/conf.d/default.conf"},{"contents": "${{ env.SSL_CONF_CONFIG_FILE }}","name": "/etc/nginx/conf.d/ssl.conf"}]},"externalIdType": "git","externalId": "${{ github.sha }}","updateTime": "${{ env.NMS_TIMESTAMP }}"}' 

Implementación de referencia de NGINX

La ejecución de una llamada a la API de actualización de la configuración después de que se haya modificado un archivo puede realizarse de distintas formas. Aunque GitHub Actions es el método más práctico para quienes utilizan GitHub, no funciona con GitLab ni con implementaciones independientes de Git. Para dar respuesta a estos casos de uso, hemos desarrollado un script de shell complementario como implementación de referencia que puede ejecutarse desde la línea de comandos o invocarse desde scripts personalizados.

En conclusión, nuestra nueva extensión para la API de Instance Manager ofrece una potente herramienta para gestionar actualizaciones de configuración, reversiones e historiales de versiones de una forma moderna y descentralizada. La integración de la extensión con una plataforma externa de gestión de archivos de texto y código como GitHub permite incorporar funciones adicionales de flujo de trabajo, CI/CD, colaboración y seguimiento de incidencias mediante una interfaz de usuario web intuitiva.

¡Nos encantaría conocer tu opinión! Pruébalo y cuéntanos qué te parece en los comentarios o únete a nuestro canal de Slack de la comunidad de NGINX.


Compartir
Etiquetas: F5 NGINX, Tech

Artículos relacionados del blog

Únete a F5 NGINX en AppWorld 2024
NGINX | 04/01/2024

Únete a F5 NGINX en AppWorld 2024

Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
NGINX | 26/09/2023

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source

La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.

Exposición de APIs en Kubernetes
NGINX | 10/03/2022

Exposición de APIs en Kubernetes

La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
NGINX | 23/08/2021

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto

Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.

Presentamos NGINX Plus R22
NGINX | 09/06/2020

Presentamos NGINX Plus R22

NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.

Presentamos NGINX Plus R17
NGINX | 11/12/2018

Presentamos NGINX Plus R17

NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.