CLOVER🍀

That was when it all began.

TerraformでリソースやモジュールのOutputを一括で設定する

これは、なにをしたくて書いたもの?

Terraformを使っていて、

output "xxx" {
  value = resource_a.this.xxx
}

output "yyy" {
  value = resource_a.this.yyy
}

output "zzz" {
  value = resource_a.this.zzz
}

...

といった感じで、あるリソースやモジュールのOutputを頑張って並べていくのが面倒だなぁと思い…調べてみたら、
Terraform 0.12からこれを一括で設定できるようになっていたみたいです。

ドキュメントに書いてないじゃないですかっ、気づかないよ!

Output Values - Configuration Language - Terraform by HashiCorp

Resource and module object values

Release Notesなどによると、これを「Resource and module object values」と言い、リソースやモジュール全体を式においての
値として扱えるようになりました。

https://github.com/hashicorp/terraform/blob/v0.12.0/CHANGELOG.md

Release v0.12.0 · hashicorp/terraform · GitHub

Terraform 0.11→0.12で追加された新機能 | Developers.IO

使い方は、こんな感じですね。

output "foo_database" {
  value = mysql_database.foo
}

これまで以下のように属性をたくさん並べていたのを、一括でOutputとして設定するというやり方で良い時はだいぶ楽に
書くことができるようになります、と。

output "foo_database_name" {
  value = mysql_database.foo.name
}

output "foo_database_default_character_set" {
  value = mysql_database.foo.default_character_set
}

...

Release Notesをよく見ると、Output Variablesだけではなく、Input Variablesとして使えるということが書いてあります。

including passing them through input variables and output values to other modules, using an attribute-less reference syntax, like aws_instance.foo.

リソースのインスタンスをまるっと渡して参照できるということですね。モジュールを作る時に使うことがあったり
するでしょうか?覚えておきましょう。

ブログの方には、1行だけ書いてありました。

Generalized type system: use lists and maps more freely, and use resources as object values.

Announcing Terraform 0.12

わからん…。

自分は、TerraformのIssueを眺めていて0.12にこの機能が入っていそうだと気づき、0.12の新機能の情報を探して把握した
感じですね。

Improvement: Export all outputs of a sub module in the current module. Use the map key entries for generating separated output variables. · Issue #8554 · hashicorp/terraform · GitHub

Allow entire resource to be output · Issue #9067 · hashicorp/terraform · GitHub

まあ、紹介はこのくらいにして、使っていってみましょう。

環境

今回の環境は、こちら。

$ terraform version
Terraform v0.12.26
+ provider.mysql v1.9.0

ProviderとしてはMySQLを使って試すことにします。MySQL自体は、8.0で172.17.0.2で動作しているものとします。

リソースのOutputを一括で設定してみる

Terraformのリソース定義ファイルを、こんな感じで用意。
main.tf

terraform {
  required_version = "0.12.26"
}

provider "mysql" {
  endpoint = "172.17.0.2:3306"
  username = "root"
  password = "password"

  version = "1.9.0"
}

resource "mysql_database" "this" {
  name = "my_database"

  default_character_set = "utf8mb4"
  default_collation     = "utf8mb4_ja_0900_as_cs_ks"
}

output "this_database" {
  value = mysql_database.this
}

リソースは、シンプルにひとつだけにしました。

resource "mysql_database" "this" {
  name = "my_database"

  default_character_set = "utf8mb4"
  default_collation     = "utf8mb4_ja_0900_as_cs_ks"
}

で、このリソースのOutputを一括で指定しています。valueに設定するのは、「リソース名.name」です。

output "this_database" {
  value = mysql_database.this
}

applyしてみましょう。

$ terraform apply

リソース作成後、Output Variablesがこんな感じで設定されます。

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

this_database = {
  "default_character_set" = "utf8mb4"
  "default_collation" = "utf8mb4_ja_0900_as_cs_ks"
  "id" = "my_database"
  "name" = "my_database"
}

MySQL Providerのmysql_databaseリソースでのOutput(Attribute)は4つなので、全部網羅されていますね。

MySQL: mysql_database - Terraform by HashiCorp

これは、欲しい時は便利な機能なので覚えておきましょう。

モジュールで試す

今度は、同じことをモジュールでやってみましょう。

こんな感じで、サブモジュールを作成。
modules/database/main.tf

variable "name" {
  type = string
}

resource "mysql_database" "this" {
  name = var.name

  default_character_set = "utf8mb4"
  default_collation     = "utf8mb4_ja_0900_as_cs_ks"
}

output "name" {
  value = mysql_database.this.name
}

output "default_character_set" {
  value = mysql_database.this.default_character_set
}

データベース名だけ変数にしたものですね。

Outputは、意図的に2つに絞っています。

output "name" {
  value = mysql_database.this.name
}

output "default_character_set" {
  value = mysql_database.this.default_character_set
}

このモジュールを利用する側。
main.tf

terraform {
  required_version = "0.12.26"
}

provider "mysql" {
  endpoint = "172.17.0.2:3306"
  username = "root"
  password = "password"

  version = "1.9.0"
}

module "database" {
  source = "./modules/database"

  name = "my_database"
}

output "this_database" {
  value = module.database
}

モジュールのOutputに関しては、リソースと同じように「module.モジュール名」で一括で設定。

output "this_database" {
  value = module.database
}

apply。

$ terraform apply

すると、モジュールがOutputに指定している値が全部得られます。

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

this_database = {
  "default_character_set" = "utf8mb4"
  "name" = "my_database"
}

もちろん、モジュール側でリソースの属性を全部Outputに設定していれば

/*
output "name" {
  value = mysql_database.this.name
}

output "default_character_set" {
  value = mysql_database.this.default_character_set
}
*/

output "database" {
  value = mysql_database.this
}

モジュール利用側では、それが全部反映されます。

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

this_database = {
  "database" = {
    "default_character_set" = "utf8mb4"
    "default_collation" = "utf8mb4_ja_0900_as_cs_ks"
    "id" = "my_database"
    "name" = "my_database"
  }
}

まあ、モジュールが内部で利用しているリソースの属性を全部公開するかどうかは微妙なところもあるので、モジュール間の
データの受け渡しの時とかに活用できるといいのかな?と思いますが。

Remote Stateと組み合わせる

Remote Stateと組み合わせてみましょう。

Remote Stateのバックエンドには、Consuleを利用することにします。1.8.0のConsulを、172.17.0.3のサーバーに立てている
ものとします。

データベースの作成と、ユーザーと権限の作成をそれぞれ別々のTerraform管理単位として行ってみましょう。

まずは、データベースの作成側。
main.tf

terraform {
  required_version = "0.12.26"

  backend "consul" {
    address = "172.17.0.3:8500"
    scheme  = "http"
    path    = "terraform/state/mysql/database"
  }
}

provider "mysql" {
  endpoint = "172.17.0.2:3306"
  username = "root"
  password = "password"

  version = "1.9.0"
}

resource "mysql_database" "this" {
  name = "my_database"

  default_character_set = "utf8mb4"
  default_collation     = "utf8mb4_ja_0900_as_cs_ks"
}

output "this_database" {
  value = mysql_database.this
}

mysql_databaseの属性は、全部Outputとして登録しておきます。

output "this_database" {
  value = mysql_database.this
}

Stateは、Consulに保存します。

terraform {
  required_version = "0.12.26"

  backend "consul" {
    address = "172.17.0.3:8500"
    scheme  = "http"
    path    = "terraform/state/mysql/database"
  }
}

apply。

$ terraform apply

続いて、ユーザーと権限を作る側。
main.tf

terraform {
  required_version = "0.12.26"

  backend "consul" {
    address = "172.17.0.3:8500"
    scheme  = "http"
    path    = "terraform/state/mysql/user"
  }
}

provider "mysql" {
  endpoint = "172.17.0.2:3306"
  username = "root"
  password = "password"

  version = "1.9.0"
}

data "terraform_remote_state" "database" {
  backend = "consul"

  config = {
    address = "172.17.0.3:8500"
    scheme  = "http"
    path    = "terraform/state/mysql/database"
  }
}

resource "mysql_user" "admin_user" {
  user               = "adminuser"
  plaintext_password = "password"
  host               = "%"
}

resource "mysql_grant" "admin_user" {
  user       = "adminuser"
  host       = "%"
  database   = data.terraform_remote_state.database.outputs.this_database.name
  privileges = ["ALL"]

  depends_on = [mysql_user.admin_user]
}

データベースを作成した時のStateを、Data Sourceとして参照します。

data "terraform_remote_state" "database" {
  backend = "consul"

  config = {
    address = "172.17.0.3:8500"
    scheme  = "http"
    path    = "terraform/state/mysql/database"
  }
}

こちらを、データベース名の取得に利用。

resource "mysql_grant" "admin_user" {
  user       = "adminuser"
  host       = "%"
  database   = data.terraform_remote_state.database.outputs.this_database.name
  privileges = ["ALL"]

  depends_on = [mysql_user.admin_user]
}

apply。

$ terraform apply

これで、Remote StateをData Sourceとして扱った時も確認できました、と。

Sensitive?

ところで、この方法を取った時、sensitiveの設定はどうするんでしょうね?

sensitive — Suppressing Values in CLI Output

やっぱり、こんな感じにまるっと設定することになるんでしょうかね?

output "this_database" {
  value = mysql_database.this
  sensitive = true
}

apply時には、こういう出力結果になります。

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

this_database = <sensitive>

まあ、Stateに値が保存されていること自体は変わらない(コンソールに出力されないだけ)ので、そう困りはしない…かな?

モジュールのOutputをそのまま全部出力する場合は、モジュール側のOutputsにsensitive = trueがあっても、呼び出し側が
sensitiveを設定していないと意味ないので、そこは注意ですねぇ。

Quarkusでコマンドラインアプリケーションを作る

これは、なにをしたくて書いたもの?

Quakusでコマンドラインアプリケーションを作れそうな感じのガイドがあったので、試してみようかなと。

Quarkus - Command Mode Applications

Picocli向けのExtensionもあるようです。

Quarkus - Command Mode with Picocli

なのですが、こちらはexperimentalということと、先にシンプルな方からかなということで今回はパス。

環境

今回の環境は、こちらです。

$ java --version
openjdk 11.0.7 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu218.04)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-2ubuntu218.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 11.0.7, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-106-generic", arch: "amd64", family: "unix"

では、簡単なコマンドラインアプリケーションを作成してみます。

プロジェクトを作成する

まずは、プロジェクトを作成してみます。

ドキュメントを見ても、必要そうなExtensionはわからなかったのですが

Quarkus - Command Mode Applications

説明に出てくる「@QuarkusMain」アノテーションはquarkus-coreにあるみたいなので

https://github.com/quarkusio/quarkus/blob/1.5.1.Final/core/runtime/src/main/java/io/quarkus/runtime/annotations/QuarkusMain.java

なにも考えずにプロジェクトを作成してみます。

$ mvn io.quarkus:quarkus-maven-plugin:1.5.1.Final:create \
    -DprojectGroupId=org.littlewings \
    -DprojectArtifactId=plain-commandline-application

pom.xmlに指定された依存関係。なにも指定しなくても、RESTEasyは入るんですね。

  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

できあがったディレクトリに移動。

$ cd plain-commandline-application

シンプルに使う

とりあえず、mainクラスらしきものを作ってみます。
src/main/java/org/littlewings/quarkus/cli/ClipApp.java

package org.littlewings.quarkus.cli;

import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain
public class ClipApp implements QuarkusApplication {
    @Override
    public int run(String... args) throws Exception {
        String word;
        if (args.length > 0) {
            word = args[0];
        } else {
            word = "World";
        }

        System.out.printf("Hello %s!!%n", word);

        return 0;
    }
}

QuarkusApplicationインターフェースを実装し、@QuarkusMainアノテーションを付与すればいいみたいです。
QuarkusApplicationインターフェースから要求されるのは、runメソッドのみです。

runメソッドの戻り値は、プロセスの終了ステータスになります。

「mvn quarkus:dev」してみます。

$ mvn compile quarkus:dev

起動したら、いきなり実行されます。

[INFO] --- quarkus-maven-plugin:1.5.1.Final:dev (default-cli) @ plain-commandline-application ---
Listening for transport dt_socket at address: 5005
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-06-18 22:52:48,548 INFO  [io.quarkus] (Quarkus Main Thread) plain-commandline-application 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.1.Final) started in 0.938s. Listening on: http://0.0.0.0:8080
2020-06-18 22:52:48,551 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2020-06-18 22:52:48,551 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]
Hello World!!
2020-06-18 22:52:48,602 INFO  [io.quarkus] (Quarkus Main Thread) plain-commandline-application stopped in 0.049s
Quarkus application exited with code 0
Press Enter to restart or Ctrl + C to quit

Enterを押すと、もう1回実行されますね。

Restarting...
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-06-18 22:53:20,002 INFO  [io.quarkus] (Quarkus Main Thread) plain-commandline-application 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.1.Final) started in 0.167s. Listening on: http://0.0.0.0:8080
2020-06-18 22:53:20,002 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2020-06-18 22:53:20,002 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]
Hello World!!
2020-06-18 22:53:20,003 INFO  [io.quarkus] (Quarkus Main Thread) plain-commandline-application stopped in 0.000s
Quarkus application exited with code 0
Press Enter to restart or Ctrl + C to quit

プログラムを変更していれば、それが反映されます。

プログラムの引数を指定するには、「quarkus.args」で指定すればいいみたいです。

$ mvn compile quarkus:dev -Dquarkus.args=Quarkus

引数が渡りました。

2020-06-18 22:54:11,939 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]
Hello Quarkus!!

引数を複数渡したい場合は、どうするんでしょう?

2つ要求するようにしてみました。
src/main/java/org/littlewings/quarkus/cli/ClipApp.java

package org.littlewings.quarkus.cli;

import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain
public class ClipApp implements QuarkusApplication {
    @Override
    public int run(String... args) throws Exception {
        String word;
        if (args.length > 0) {
            word = args[0];
        } else {
            word = "World";
        }

        String decoration;
        if (args.length > 1) {
            decoration = args[1];
        } else {
            decoration = "!!";
        }

        System.out.printf("Hello %s%s%n", word, decoration);

        return 0;
    }
}

どうやら、引用符で囲ってスペース区切りで渡せば良さそうです。

$ mvn compile quarkus:dev -Dquarkus.args='Quarkus ?'

2020-06-18 22:59:27,717 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]
Hello Quarkus?

ヒントはこちら。

    /**
     * The arguments passed to the command line.
     * <p>
     * We don't make it a list as the args are separated by a space, not a comma.
     */
    @ConfigItem
    public Optional<String> args;

https://github.com/quarkusio/quarkus/blob/1.5.1.Final/core/runtime/src/main/java/io/quarkus/runtime/CommandLineRuntimeConfig.java

CDIを使ってみる

アプリケーション起動時のログを見ていると、CDI(ArC)が入っているので使えそうですね。

2020-06-18 22:53:20,002 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]

新しくCDI管理Beanを作成し、先ほどのmainクラスのメッセージを組み立てていた部分をそのままCDI管理Beanに移動します。
src/main/java/org/littlewings/quarkus/cli/MessageService.java

package org.littlewings.quarkus.cli;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class MessageService {
    public String create(String... args) {
        String word;
        if (args.length > 0) {
            word = args[0];
        } else {
            word = "World";
        }

        String decoration;
        if (args.length > 1) {
            decoration = args[1];
        } else {
            decoration = "!!";
        }

        return String.format("Hello %s%s", word, decoration);
    }
}

mainクラス側は、こんな感じに。
src/main/java/org/littlewings/quarkus/cli/ClipApp.java

package org.littlewings.quarkus.cli;

import javax.inject.Inject;

import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain
public class ClipApp implements QuarkusApplication {
    @Inject
    MessageService messageService;

    @Override
    public int run(String... args) throws Exception {
        System.out.println(messageService.create(args));

        return 0;
    }
}

実行。

$ mvn compile quarkus:dev -Dquarkus.args='Quarkus ?'

2020-06-18 23:09:01,941 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]
Hello Quarkus?

OKです。

複数のmainクラスがある場合

@QuarkusMainアノテーションが付与されたクラスが、複数ある場合を試してみます。

先ほどのmainクラスをコピーして作成。
src/main/java/org/littlewings/quarkus/cli/ClipApp2.java

package org.littlewings.quarkus.cli;

import javax.inject.Inject;

import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain
public class ClipApp2 implements QuarkusApplication {
    @Inject
    MessageService messageService;

    @Override
    public int run(String... args) throws Exception {
        System.out.println(messageService.create(args));

        return 0;
    }
}

※ プレーンなpublic static void mainメソッドを持ったクラスを定義するやり方もあるようですが、ちょっとうまくいかなかったので
  今回はパスします

実行。

$ mvn compile quarkus:dev -Dquarkus.args='Quarkus ?'

こうすると、mainクラスが一意に定められずに実行に失敗します。

2020-06-18 23:15:36,767 ERROR [io.qua.dep.dev.DevModeMain] (main) Failed to start Quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
    [error]: Build step io.quarkus.deployment.steps.MainClassBuildStep#mainClassBuildStep threw an exception: java.lang.RuntimeException: More than one @QuarkusMain method found with name '': org.littlewings.quarkus.cli.ClipApp and org.littlewings.quarkus.cli.ClipApp2

「mvn package」なども同じように失敗します。

このような場合、@QuarkusMainアノテーションのname属性の値を指定して

@QuarkusMain(name = "cli-app")
public class ClipApp implements QuarkusApplication {
   ...
}


@QuarkusMain(name = "cli-app2")
public class ClipApp2 implements QuarkusApplication {
    ...
}

ビルド時に「-Dquarkus.package.main-class」システムプロパティで@QuarkusMainのname属性に指定した名前を指定するか、

$ mvn compile quarkus:dev -Dquarkus.package.main-class=cli-app

「application.properties」ファイルで指定します。
src/main/resources/application.properties

# Configuration file
# key = value

quarkus.package.main-class=cli-app

システムプロパティで指定できるので、pom.xmlのpropertiesでも書けます。

  <properties>
    ...

    <quarkus.package.main-class>cli-app</quarkus.package.main-class>
  </properties>

アプリケーションの実行時ではなく、ビルド時の指定になるのはちょっと注意点ですね。

今回は、application.propertiesで指定することにしました。
src/main/resources/application.properties

# Configuration file
# key = value

quarkus.package.main-class=cli-app

パッケージングして実行してみる

パッケージングして実行してみましょう。

まずは、JARファイルから。

$ mvn clean package

実行。

$ java -jar target/plain-commandline-application-1.0-SNAPSHOT-runner.jar Quarkus ?
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-06-18 23:28:37,443 INFO  [io.quarkus] (main) plain-commandline-application 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.1.Final) started in 0.674s. Listening on: http://0.0.0.0:8080
2020-06-18 23:28:37,463 INFO  [io.quarkus] (main) Profile prod activated. 
2020-06-18 23:28:37,464 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy]
Hello Quarkus?
2020-06-18 23:28:37,515 INFO  [io.quarkus] (main) plain-commandline-application stopped in 0.050s

続いてネイティブイメージは…ビルドがうちの環境だと辛かったので、諦めました…。なにかしら問題にぶつかることが多いので、
試しておいた方がいいんですけどねぇ…。

RESTEasyを外したい

ところで、今回コマンドラインアプリケーションであるにも関わらず、RESTEasyが起動してそうな感じのログが見えます。

2020-06-18 23:28:37,443 INFO  [io.quarkus] (main) plain-commandline-application 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.1.Final) started in 0.674s. Listening on: http://0.0.0.0:8080

実際、デフォルトだとポート8080がかぶったりすると、起動に失敗しますし。

まあ、pom.xmlにRESTEasyが入っているので、そりゃあそうだろうという気はしますが。

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>

RESTEasyを外してみましょう。そんなことはドキュメントのどこにも書いていないので、完全に興味で試してるだけですが。

依存関係を「quarkus-core」にしてみます。

    <dependency>
      <groupId>io.quarkus</groupId>
      <!-- <artifactId>quarkus-resteasy</artifactId> -->
      <artifactId>quarkus-core</artifactId>
    </dependency>

すると、ビルドはうまくいきますが、実行時にはCDIが必要なようで失敗します。

2020-06-19 00:05:35,599 ERROR [io.qua.run.Application] (main) Error running Quarkus application: java.lang.IllegalStateException: Unable to locate CDIProvider
    at javax.enterprise.inject.spi.CDI.findAllProviders(CDI.java:121)
    at javax.enterprise.inject.spi.CDI.getCDIProvider(CDI.java:82)
    at javax.enterprise.inject.spi.CDI.current(CDI.java:64)
    at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:93)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:61)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
    at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:30)

これは、アプリケーション内でCDIを使っていなくても、同じことになりました。

というわけで、今度は「quarkus-arc」にしてみます。

    <dependency>
      <groupId>io.quarkus</groupId>
      <!-- <artifactId>quarkus-resteasy</artifactId> -->
      <artifactId>quarkus-arc</artifactId>
    </dependency>

今度はうまくいきました。

$ java -jar target/plain-commandline-application-1.0-SNAPSHOT-runner.jar Quarkus ?
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-06-19 00:07:52,050 INFO  [io.quarkus] (main) plain-commandline-application 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.1.Final) started in 0.262s. 
2020-06-19 00:07:52,069 INFO  [io.quarkus] (main) Profile prod activated. 
2020-06-19 00:07:52,069 INFO  [io.quarkus] (main) Installed features: [cdi]
Hello Quarkus?
2020-06-19 00:07:52,074 INFO  [io.quarkus] (main) plain-commandline-application stopped in 0.003s

ExtensionはCDIのみです。

2020-06-19 00:07:52,069 INFO  [io.quarkus] (main) Installed features: [cdi]

こんなところで。