AnsibleでQuarkusのデプロイを自動化
Ansible を使ってQuarkusアプリをビルドしてデプロイする方法を見てみましょう。コードのチェックアウトから、Mavenを使用してアプリケーションをコンパイルし、AnsibleとQuarkus用のコレクションを使用して、ターゲットシステム上に systemd サービスとしてデプロイしてサービスを開始するまでのプロセス全体を自動化する方法を見ていきます。
最初のパートは、Ansible(Ansibleが実行される場所)でのアプリケーションコードのチェックアウト、コンパイル、パッケージングです。このチュートリアルのベースとして、 Quarkus QuickStartsディレクトリ で提供されているget-startedサンプルアプリケーションを使用します。また、Ansibleのエクステンションである Quarkus collection for Ansibleを活用して、これは、必要なボイラープレートを軽減し、Ansibleを使用してQuarkusを迅速にビルドおよびデプロイします。
前提条件
このガイドを完成させるには、以下が必要です:
-
ざっと 10 minutes
-
IDE
-
JDK 17+がインストールされ、
JAVA_HOME
が適切に設定されていること -
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
ワークステーションに Ansibleをインストール する必要があります。これが完了したら、次のコマンドでQuarkus専用のAnsible用エクステンションをインストールできます:
$ ansible-galaxy collection install middleware_automation.quarkus
今インストールしたAnsibleコレクションは、RHEL、Fedora、その他のRPMを使ったLinuxディストリビューションのみをサポートしています。Ansibleはこれらを「RedHatファミリー」と定義しています。他のプラットフォーム(Windows、Debian、Ubuntu、…)でコンテンツを使用することは、不可能ではありませんが、いくつかの調整が必要です。 |
インベントリファイル
Ansibleに慣れていない場合は、上記のコマンドを正しく実行するためにインベントリを提供する必要があることに注意してください。これは、Ansibleが管理するターゲット・システムに必要な情報を提供する単純なテキスト・ファイルです。 Ansible インベントリ の詳細については、Ansibleドキュメントを参照してください。
[all]
10.0.0.1
10.0.0.2
チュートリアルに従うには、1台のマシン(localhost)だけを使用し、ssh認証のセットアップをスキップしたいかもしれません。これは、以下のインベントリファイルを使用することで簡単に実現できます:
[all]
localhost ansible_connection=local
チュートリアル
コントローラにAnsibleコレクションがインストールされていれば、Quarkusアプリケーションをビルドしてデプロイするために、Ansibleに付属のplaybookを直接使用することができます:
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
playbookに提供される4つのパラメータは、かなり自明です。最初のもの、 app_name
はアプリケーションの名前で、私たちの場合は getting-started
とします。2つ目の quarkus_app_repo_url
は、チェックアウトするGitリポジトリのURLです。3番目はオプションで、 quarkus_app_source_folder
は、必要であれば、ソースコードがリポジトリのどのサブフォルダーにあるかを指定します。最後に4つ目は、ターゲットの何処にアプリケーションをインストールするかを指定します。
Playbookの実行
上記のコマンドが正常に実行されると、以下のような出力が得られるはずです:
…
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
…
Quarkus用のAnsibleコレクションは、 大変な作業
はすべて実施してくれます。まず、Githubからコードをチェックアウトし、そのソースからアプリケーションをビルドします。また、このステップで使用するシステムに必要なOpenJDKがインストールされていることを確認します。デフォルトでは、アプリケーションはlocalhost(Ansibleコントローラー)上でビルドされますが、必要に応じてリモートシステム上で実行することもできます。アプリケーションがビルドされると、コレクションがデプロイを行います。
ここでも、適切なOpenJDKがターゲット・システム上で利用可能かどうかをチェックします。次に、必要なユーザーとグループがターゲットに存在するようにします。これは主に、Quarkusアプリをrootアカウントではなく、一般ユーザーで実行できるようにするために推奨されます。
これらの要件が揃えば、アプリをサービスとしてsystemdに統合するために必要な設定とともに、jarをターゲットにデプロイすることができます。systemdの設定を変更するには、デーモンをリロードする必要があります。このコレクションは、必要なときにいつでも実行されることを保証します。すべての設定が揃ったので、あとはサービス自体を起動するだけです。
デフォルトでは、Quarkus用のAnsibleコレクションは、ターゲットホスト(またはコントローラー)のYumリポジトリで利用可能なOpenJDK 17をインストールして使用します。異なるバージョンのOpenJDKを使用したい場合は、以下の変数を定義します:
|
デプロイが成功したことの検証
このチュートリアルの目的のために、プレイブックが本当にアプリを正しくデプロイしたかどうか、手動でチェックしたいと思うかもしれません。そのためのいくつかの方法を紹介しましょう。
まず、コレクションが統合されたので、ターゲットの1つでサービスのステータスをチェックできます:
# 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]
手動で、アプリが到達可能かどうかをテストすることもできます:
# 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
このチュートリアルの最後となる次のパートでは、これらの検証を自動化する方法を見ていきましょう。
プレイブックの作成
もちろん、これに基づいて構築する必要がある可能性が高いため、コレクションによって提供されるプレイブックを単に使用するのではなく、独自のプレイブックを作成することもできます。 以下はそのようなプレイブックの例です。
- 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
このプレイブックを実行するには、再びansible-playbookコマンドを使用しますが、今度はプレイブックへのパスを指定します:
$ ansible-playbook -i inventory playbook.yml
また、前のセクションで説明した検証部分を自動化することもできます。 ansible.builtin.assert モジュールを使用し、Quarkusアプリのsystemdサービスが実行されていることを確認するために サービスファクト を入力し、Quarkusアプリがアクセス可能であることを確認するために ansible.builtin.uri を入力します。
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/'
以上です!