Skip to content

Managing configuration

Zoe has a powerful configuration engine that can be overridden and customized in a number of ways. Zoe also makes it easy to share configuration among the team using a github repository.

In this guide, we will discover the different ways to configure zoe.

Initializing the configuration

Zoe stores its configuration in ~/.zoe/config by default. The directory location can be overridden with the environment variable ZOE_CONFIG_DIR or by using the option zoe --config-dir /path/to/config.

Add a file named default.yml inside ~/.zoe/config like the following:

clusters:

  cluster1:
    props:
      bootstrap.servers: "cluster1:29092"
      key.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      value.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      key.serializer: "org.apache.kafka.common.serialization.StringSerializer"
      value.serializer: "org.apache.kafka.common.serialization.ByteArraySerializer"

  cluster2:
    props:
      bootstrap.servers: "cluster2:29092"
      key.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      value.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      key.serializer: "org.apache.kafka.common.serialization.StringSerializer"
      value.serializer: "org.apache.kafka.common.serialization.ByteArraySerializer"

runners:
  default: "local"

The configuration above defines two Kafka clusters aliased cluster1 and cluster2. To refer to a specific cluster when using zoe, you can use the --cluster option or the short version -c:

# To target cluster1
zoe -c cluster1 topics list

# To target cluster2
zoe -c cluster2 topics list

Managing multiple environments

If you are dealing with multiple environments, you can create multiple yaml configuration files in ~/.zoe/config as the following:

~/.zoe/config
├── default.yml
└── prod.yml
clusters:

  cluster1:
    props:
      bootstrap.servers: "cluster1:29092"
      key.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      value.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      key.serializer: "org.apache.kafka.common.serialization.StringSerializer"
      value.serializer: "org.apache.kafka.common.serialization.ByteArraySerializer"

  cluster2:
    props:
      bootstrap.servers: "cluster2:29092"
      key.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      value.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      key.serializer: "org.apache.kafka.common.serialization.StringSerializer"
      value.serializer: "org.apache.kafka.common.serialization.ByteArraySerializer"

runners:
  default: "local"
clusters:

  cluster1:
    props:
      bootstrap.servers: "cluster1-prod.example.com:9092"
      key.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      value.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      key.serializer: "org.apache.kafka.common.serialization.StringSerializer"
      value.serializer: "org.apache.kafka.common.serialization.ByteArraySerializer"

  cluster2:
    props:
      bootstrap.servers: "cluster2-prod.example.com:9092"
      key.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      value.deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
      key.serializer: "org.apache.kafka.common.serialization.StringSerializer"
      value.serializer: "org.apache.kafka.common.serialization.ByteArraySerializer"

runners:
  default: "kubernetes"

The example above defines two environments: default and prod. Environments can be specified using the --environment or -e option and giving it the environment name which is the file name without the extension:

# To target cluster1 in the prod environment
zoe -e prod -c cluster1 topics list

# To target cluster2 in the default environment
zoe -e default -c cluster2 topics list

When no environment is specified with -e, the environment named default is used. Thus, the last command could have been written as the following:

# To target cluster2 in the default environment
zoe -c cluster2 topics list

The special common.yml file

You can store configuration values that are shared across all the environments in a file called common.yml inside zoe's configuration directory. The configuration in this file will always be loaded no matter what environment has been specified.

secrets:
  provider: "exec"
  command: [ "my-command", "{secretName}", "{context}" ]

runners:
  default: lambda 

The example above sets the secrets' provider configuration and the default runner in the shared common.yml file. This way, these parameters are loaded for all the environments.

The environment specific configuration values takes precedence over the common.yml configuration values. To know more about zoe's configuration loading chain, checkout the dedicated section in the documentation.

Sharing configuration in git

The above configuration tree can be shared across the whole team in a git repository. This allows the configuration to be written once, and used by all the team members.

If your configuration contains credentials (ex. sasl.jaas.config property), you can use a secret provider to describe the secret in the configuration without exposing its value.

Zoe can easily fetch a remote configuration directory from git using the following command:

zoe config init --from git --url https://github.com/adevinta/zoe --dir docs/guides/simple/config

Overriding configuration values using environment variables

You can override part of zoe's configuration using an environment variable called ZOE_CONFIG_OVERRIDE. This variable takes a json that will be shallow merged into the final configuration.

The example below overrides the bootstrap.servers property of cluster1:

export ZOE_CONFIG_OVERRIDE={"clusters": {"cluster1": {"props": {"bootstrap.servers": "custom.endpoint:9092"}}}}
zoe -c cluster1 topics list

Zoe provides other environment variables to override environment specific configuration values. To know more, checkout the dedicated section about zoe's configuration loading chain.