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_HOMEconfigured 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
| The Ansible collection we just installed only supports RHEL, Fedora, and other Linux distributions using RPMs. Ansible defines these as "RedHat family". Using the content on other platforms (Windows, Debian, Ubuntu, …), while not impossible, will require a few adjustments. |
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
We’ll see how to automate those validations in the next and last part of this 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
You can also automate the validation part we mentioned in the previous section. You can use the ansible.builtin.assert module and populate the service facts to ensure the systemd service of the Quarkus app is running, along with ansible.builtin.uri to check that the Quarkus app is accessible.
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!