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:
|
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!