Quarkus Consul Config

This guide explains how your Quarkus application can read configuration properties at runtime from HashiCorp Consul.

Prerequisites

To complete this guide, you need:

  • less than 15 minutes

  • an IDE

  • JDK 17+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.8.1+

Solution

We recommend that you follow the instructions in the next sections and create the application step by step.

Introduction

Consul is a versatile system which among other things, provides a distributed Key-Value store that is used in many architectures as a source of configuration for services. This Key-Value store is what the quarkus-config-consul extension interacts with in order to allow Quarkus applications to read runtime configuration properties from Consul.

Starting Consul

There are various ways to start Consul that vary in complexity, but for the purposes of this guide, we elect to start a single Consul server with no persistence via Docker, like so:

docker run --rm --name consul -p 8500:8500 -p 8501:8501 consul:1.7 agent -dev -ui -client=0.0.0.0 -bind=0.0.0.0 --https-port=8501

Please consult the documentation to learn more about the various Consul installation options.

Creating the Maven project

First, we need a new project. Create a new project with the following command:

mvn io.quarkus.platform:quarkus-maven-plugin:3.14.0:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=config-consul-quickstart \
    -DclassName="org.acme.consul.config.GreetingResource" \
    -Dpath="/greeting" \
    -Dextensions="config-consul"
cd config-consul-quickstart

This command generates a Maven project with a REST endpoint and imports the config-consul extension.

If you already have your Quarkus project configured, you can add the config-consul extension to your project by running the following command in your project base directory:

./mvnw quarkus:add-extension -Dextensions="config-consul"

This will add the following to your pom.xml:

<dependency>
    <groupId>io.quarkiverse.config</groupId>
    <artifactId>quarkus-config-consul</artifactId>
    <version>2.4.0</version>
</dependency>

GreetingController

The Quarkus Maven plugin automatically generated a GreetingResource JAX-RS resource in the src/main/java/org/acme/consul/config/client/GreetingResource.java file that looks like:

package org.acme.consul.config.client;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/greeting")
public class GreetingResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

As we want to use configuration properties obtained from the Config Server, we will update the GreetingResource to inject the message property. The updated code will look like this:

package org.acme.consul.config.client;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Path("/greeting")
public class GreetingResource {
    @ConfigProperty(name = "greeting.message", defaultValue="Hello from default")
    String message;
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return message;
    }
}

Configuring the application

Quarkus provides various configuration knobs under the quarkus.consul-config root. For the purposes of this guide, our Quarkus application is going to be configured in application.properties as follows:

# use the same name as the application name that was configured when standing up the Config Server
quarkus.application.name=consul-test
# enable retrieval of configuration from Consul - this is off by default
quarkus.consul-config.enabled=true
# this is a key in Consul's KV store that the Quarkus application will read and try to extract properties from
quarkus.consul-config.properties-value-keys=config/${quarkus.application.name}

Add Configuration to Consul

For the previous application configuration to work, we need to add a config/consul-test key under Consul’s Key Value store. The value of this key will essentially be a properties "file" containing the application configuration. In this case we want to add the following data to the config/consul-test key:

greeting.message=Hello from Consul

When adding this configuration from the UI, Consul will automatically convert the data into the necessary base64 encoding. If you instead add the configuration via the Consul’s REST API, make sure to first encode the previous data into base64.

In this use case we made the value of the key as a properties "file", because we used quarkus.consul-config.properties-value-keys in the application. The extension also provides the ability to use the raw values of keys when quarkus.consul-config.raw-value-keys is used. Furthermore, these two properties can be used simultaneously, while each one also supports setting multiple keys.

Package and run the application

Run the application with: ./mvnw compile quarkus:dev. Open your browser to http://localhost:8080/greeting.

The result should be: Hello from Consul as it is the value obtained from the Consul Key Value store.

Run the application as a native executable

You can of course create a native image using the instructions of the Building a native executable guide.

Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

If set to true, the application will attempt to look up the configuration from Consul

Environment variable: QUARKUS_CONSUL_CONFIG_ENABLED

boolean

false

Consul agent host

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_HOST_PORT

InetSocketAddress

localhost:8500

Whether or not to use HTTPS when communicating with the agent

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_USE_HTTPS

boolean

false

Consul token to be provided when authentication is enabled

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_TOKEN

string

TrustStore to be used containing the SSL certificate used by Consul agent Can be either a classpath resource or a file system path

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_TRUST_STORE

path

Password of TrustStore to be used containing the SSL certificate used by Consul agent

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_TRUST_STORE_PASSWORD

string

KeyStore to be used containing the SSL certificate for authentication with Consul agent Can be either a classpath resource or a file system path

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_KEY_STORE

path

Password of KeyStore to be used containing the SSL certificate for authentication with Consul agent

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_KEY_STORE_PASSWORD

string

Password to recover key from KeyStore for SSL client authentication with Consul agent If no value is provided, the key-store-password will be used

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_KEY_PASSWORD

string

When using HTTPS and no keyStore has been specified, whether or not to trust all certificates

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_TRUST_CERTS

boolean

false

The amount of time to wait when initially establishing a connection before giving up and timing out.

Specify 0 to wait indefinitely.

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_CONNECTION_TIMEOUT

Duration

10s

The amount of time to wait for a read on a socket before an exception is thrown.

Specify 0 to wait indefinitely.

Environment variable: QUARKUS_CONSUL_CONFIG_AGENT_READ_TIMEOUT

Duration

60s

Common prefix that all keys share when looking up the keys from Consul. The prefix is not included in the keys of the user configuration

Environment variable: QUARKUS_CONSUL_CONFIG_PREFIX

string

Keys whose value is a raw string. When this is used, the keys that end up in the user configuration are the keys specified her with '/' replaced by '.'

Environment variable: QUARKUS_CONSUL_CONFIG_RAW_VALUE_KEYS

list of string

Keys whose value represents a properties file. When this is used, the keys that end up in the user configuration are the keys of the properties file, not these keys

Environment variable: QUARKUS_CONSUL_CONFIG_PROPERTIES_VALUE_KEYS

list of string

If set to true, the application will not start if any of the configured config sources cannot be located

Environment variable: QUARKUS_CONSUL_CONFIG_FAIL_ON_MISSING_KEY

boolean

true

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.