The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
Edit this Page

Automatice el despliegue de Quarkus con Ansible

Vamos a ver cómo construir y desplegar una aplicación Quarkus utilizando Ansible. Veremos cómo podemos automatizar todo el proceso, desde la obtención del código hasta la compilación de la aplicación usando Maven y luego su despliegue e inicio del servicio, como un servicio systemd, en el sistema destino usando Ansible y su colección para Quarkus.

La primera parte, la comprobación del código de la aplicación, compilación y empaquetado en el Ansible (donde se ejecuta Ansible). Utilizaremos la aplicación de ejemplo getting-started proporcionada en su directorio Quarkus QuickStarts como base para este tutorial. También aprovecharemos la colección de Quarkus para Ansible, una extensión para Ansible que alivia el boilerplate requerido y para construir y desplegar rápidamente una aplicación de Quarkus usando Ansible.

Requisitos previos

To complete this guide, you need:

  • Roughly 10 minutes

  • An IDE

  • JDK 17+ installed with JAVA_HOME configured appropriately

  • Optionally Mandrel or GraalVM installed and configured appropriately if you want to build a native executable (or Docker if you use a native container build)

Necesitarás instalar Ansible en tu estación de trabajo. Una vez hecho esto, puedes instalar esta extensión para Ansible dedicada a Quarkus con el siguiente comando:

$ ansible-galaxy collection install middleware_automation.quarkus
La colección de Ansible que acabamos de instalar sólo es compatible con RHEL, Fedora y otras distribuciones de Linux que utilicen RPM. Ansible las define como "familia RedHat". Utilizar el contenido en otras plataformas (Windows, Debian, Ubuntu, …​), aunque no es imposible, requerirá algunos ajustes.

Archivo de inventario

Si no está familiarizado con Ansible, tenga en cuenta que es necesario proporcionar el inventario para que el comando anterior se ejecute correctamente. Se trata de un simple archivo de texto que proporciona la información que Ansible necesita sobre el sistema de destino que gestiona. Consulte la documentación de Ansible para obtener más información sobre el inventario de Ansible.

[all]

10.0.0.1
10.0.0.2

Para seguir el tutorial, es posible que desee utilizar sólo una máquina (localhost) y omitir la configuración de autenticación ssh. Esto se puede lograr fácilmente utilizando el siguiente archivo de inventario:

[all]
localhost ansible_connection=local

Acceso root en el sistema de destino

Algunas tareas realizadas por la colección Ansible para Quarkus requerirán privilegios administrativos en el objetivo (crear un grupo y una cuenta de usuario, instalar paquetes). Si Ansible se ejecuta como root, tendrás que añadir las siguientes opciones a la línea de comandos ansible-playbook:

$ ansible-playbook -i inventory  --ask-become-pass  ...

Tutoriales

Con la colección Ansible instalada en el controlador, ya puedes utilizar directamente un playbook proporcionado con él para construir y desplegar tu aplicación Quarkus:

ansible-playbook -i inventory \
  middleware_automation.quarkus.playbook \
  -e app_name=getting-started \
  -e quarkus_app_repo_url='https://github.com/quarkusio/quarkus-quickstarts.git' \
  -e quarkus_app_source_folder='getting-started' \
  -e quarkus_path_to_folder_to_deploy=/opt/quarkus_deploy

Los cuatro parámetros proporcionados al playbook se explican por sí mismos. El primero, app_name, es el nombre de la aplicación, en nuestro caso, es simplemente getting-started. El segundo, quarkus_app_repo_url, es la URL del repositorio Git que hay que obtener. El tercero es opcional, quarkus_app_source_folder especifica, si es necesario, en qué subcarpeta del repositorio se encuentra el código fuente. Por último, el cuarto indica dónde instalar la aplicación en el destino.

Ejecución del Playbook

Una vez que el comando anterior se haya ejecutado correctamente, debería tener una salida similar a la siguiente:

…

PLAY [Build and deploy a Quarkus app using Ansible] ****************************

TASK [Build the Quarkus from https://github.com/quarkusio/quarkus-quickstarts.git.] ***

TASK [middleware_automation.quarkus.quarkus : Ensure required parameters are provided.] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Define path to mvnw script.] *****
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure that builder host localhost has appropriate JDK installed: java-17-openjdk] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Delete previous workdir (if requested).] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure app workdir exists: /tmp/workdir] ***
changed: [localhost]

TASK [middleware_automation.quarkus.quarkus : Checkout the application source code.] ***
changed: [localhost]

TASK [middleware_automation.quarkus.quarkus : Build the App using Maven] *******
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Display build application log] ***
skipping: [localhost]

TASK [Deploy webapp on target.] ************************************************

TASK [middleware_automation.quarkus.quarkus : Ensure required parameters are provided.] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure required OpenJDK is installed on target.] ***
skipping: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure Quarkus system group exists on target system] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure Quarkus user exists on target system.] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure deployement directory exits: /opt/quarkus_deploy.] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Set Quarkus app source dir (if not defined).] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Deploy application from  to target system] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Deploy Systemd configuration for Quarkus app] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Perform daemon-reload to ensure the changes are picked up] ***
skipping: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure Quarkus app service is running.] ***
ok: [localhost]

TASK [middleware_automation.quarkus.quarkus : Ensure firewalld is available.] ***
skipping: [localhost]

TASK [middleware_automation.quarkus.quarkus : Configure firewall for 8080 ports] ***
skipping: [localhost]

PLAY RECAP *********************************************************************
localhost              	: ok=15   changed=2	unreachable=0	failed=0	skipped=5	rescued=0	ignored=0
…

La colección de Ansible para Quarkus hace todo el heavy lifting aquí. En primer lugar, comprueba el código de Github y construye la aplicación a partir de sus fuentes. También se asegura de que el sistema utilizado para este paso tiene instalado el OpenJDK necesario. Por defecto, la aplicación se construye en el localhost (el controlador de Ansible), pero se puede realizar en un sistema remoto si es necesario. Una vez construida la aplicación, la colección se encargará del despliegue.

Una vez más, se comprueba que el OpenJDK apropiado está disponible en el sistema de destino. A continuación, nos aseguramos de que el usuario y el grupo necesarios existen en el sistema de destino. Esto se recomienda sobre todo para poder ejecutar la aplicación Quarkus con un usuario normal, en lugar de root.

Una vez establecidos estos requisitos, el jar puede desplegarse en el destino, junto con la configuración necesaria para la integración de la aplicación en systemd como servicio. Cualquier cambio en la configuración de systemd requiere recargar su demonio, lo que la colección garantiza que ocurrirá siempre que sea necesario. Con todo eso en su lugar, lo único que queda es iniciar el servicio en sí, de lo que Ansible también se encargará.

Por defecto, la colección Ansible para Quarkus instalará y utilizará el OpenJDK 17 disponible en los repositorios Yum del host de destino (o del controlador). Si desea utilizar una versión diferente de OpenJDK, defina la siguiente variable:

$ ansible-playbook -i inventory ...
    -e quarkus_java_package_version: java-17-openjdk

Validar que el despliegue se ha realizado correctamente

es posible que desees verificar manualmente que el playbook haya desplegado la aplicación correctamente. Aquí hay algunas formas de hacerlo.

En primer lugar, como la colección está integrada, podemos comprobar el estado del servicio en uno de los objetivos:

# systemctl status getting-started.service
● getting-started.service - A Quarkus service named getting-started
   Loaded: loaded (/usr/lib/systemd/system/getting-started.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2023-04-13 12:48:18 UTC; 2min 40s ago
 Main PID: 853 (java)
	Tasks: 43 (limit: 1638)
   Memory: 73.3M
   CGroup: /system.slice/getting-started.service
       	└─853 /usr/bin/java -jar /opt/quarkus_deploy/quarkus-run.jar

Apr 13 12:48:18 bd71f39642c8 systemd[1]: Started A Quarkus service named getting-started.
Apr 13 12:48:19 bd71f39642c8 java[853]: __  ____  __  _____   ___  __ ____  ______
Apr 13 12:48:19 bd71f39642c8 java[853]:  --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
Apr 13 12:48:19 bd71f39642c8 java[853]:  -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
Apr 13 12:48:19 bd71f39642c8 java[853]: --\___\_\____/_/ |_/_/|_/_/|_|\____/___/
Apr 13 12:48:19 bd71f39642c8 java[853]: 2023-04-13 12:48:19,284 INFO  [io.quarkus] (main) getting-started 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.16.6.Final) started in 0.607s. Listening on: http://0.0.0.0:8080
Apr 13 12:48:19 bd71f39642c8 java[853]: 2023-04-13 12:48:19,309 INFO  [io.quarkus] (main) Profile prod activated.
Apr 13 12:48:19 bd71f39642c8 java[853]: 2023-04-13 12:48:19,310 INFO  [io.quarkus] (main) Installed features: [cdi, rest, smallrye-context-propagation, vertx]

También puedes comprobar manualmente si se puede acceder a la aplicación:

# curl -I http://localhost:8080/
HTTP/1.1 200 OK
accept-ranges: bytes
content-length: 3918
cache-control: public, immutable, max-age=86400
last-modified: Thu, 2 Mar 2023 11:03:18 GMT
date: Thu, 2 Mar 2023 11:03:18 GMT

Veremos cómo automatizar esas validaciones en la siguiente y última parte de este tutorial.

Escribir un Playbook

Por supuesto, lo más probable es que tenga que basarse en esto, por lo que es posible que desee escribir su propio playbook, en lugar de limitarse a utilizar el proporcionado por la colección. A continuación se muestra un ejemplo de playbook:

- name: "Build and deploy a Quarkus app using Ansible"
  hosts: all
  gather_facts: true
  vars:
    quarkus_app_repo_url: 'https://github.com/quarkusio/quarkus-quickstarts.git'
    app_name: getting-started
    quarkus_app_source_folder: getting-started
    quarkus_path_to_folder_to_deploy: /opt/quarkus_deploy

  pre_tasks:
    - name: "Build the Quarkus from {{ quarkus_app_repo_url }}."
      ansible.builtin.include_role:
        name: quarkus
        tasks_from: build.yml
  tasks:
    - name: "Deploy Quarkus app on target."
      ansible.builtin.include_role:
        name: quarkus
        tasks_from: deploy.yml

Para ejecutar este playbook, utiliza de nuevo el comando ansible-playbook, pero proporcionando ahora la ruta al playbook:

$ ansible-playbook -i inventory playbook.yml

También puedes automatizar la parte de validación que mencionamos en la sección anterior. Puedes usar el módulo ansible.builtin.assert y rellenar los datos de servicio para asegurarte de que el servicio systemd de la aplicación Quarkus se está ejecutando, junto con ansible.builtin.uri para comprobar que se puede acceder a la aplicación Quarkus.

 post_tasks:
    - name: Populate service facts
      ansible.builtin.service_facts:

    - name: "Check that systemd service {{ app_name }} is running."
      ansible.builtin.assert:
        that:
          - ansible_facts.services is defined
          - ansible_facts.services["{{ app_name }}.service"] is defined
          - ansible_facts.services["{{ app_name }}.service"]['state'] == 'running'
          - ansible_facts.services["{{ app_name }}.service"]['status'] == 'enabled'
        quiet: true

    - name: "Check that Quarkus app is accessible"
      ansible.builtin.uri:
        url: 'http://localhost:8080/'

¡Y eso es todo, amigos!

Related content