skip to content

Externalized Configuration

Configuration for a fleet rather than one app: a config server over git or Vault, the client side, refresh, cluster-wide broadcast, encryption, and the Kubernetes-native alternatives. Interviewers ask how a password gets to fifty instances without being committed anywhere.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

page 1 of 2

What is Spring Cloud Bus and what problem does it solve?

level: juniorimportance: must knowfreq 55%

answer

  1. Broker links all instances (Kafka/Rabbit)
  2. One busrefresh -> whole cluster
  3. vs per-instance /actuator/refresh
  4. Built on Stream, topic springCloudBus
  5. starter-bus-amqp / starter-bus-kafka

basics

~20 s

Spring Cloud Bus links all instances of your microservices through a shared message broker (Kafka or RabbitMQ). You can then broadcast one message — like 'refresh your config' — to the whole cluster at once instead of calling each instance.

solid answer

~40 s

Spring Cloud Bus connects application instances over a lightweight message broker (RabbitMQ or Kafka) so they can broadcast events to each other. Its most common use is distributed configuration refresh: after you change values in a config repo, you POST once to /actuator/busrefresh on any single instance, and the Bus propagates a RefreshRemoteApplicationEvent across the broker to every instance, each of which re-reads its config and rebinds @RefreshScope / @ConfigurationProperties beans. Without the Bus you'd have to call /actuator/refresh on each instance individually, which doesn't scale. Under the hood the Bus is built on Spring Cloud Stream, using a shared topic (default 'springCloudBus') as the broadcast channel. You add it with spring-cloud-starter-bus-amqp or spring-cloud-starter-bus-kafka.

code

yaml · 18 lines
yaml
# build.gradle: implementation 'org.springframework.cloud:spring-cloud-starter-bus-amqp'

# application.yml
spring:
  rabbitmq:
    host: rabbit.internal
    port: 5672
    username: app
    password: ${RABBIT_PASSWORD}

management:
  endpoints:
    web:
      exposure:
        include: busrefresh   # must expose the Actuator endpoint

# Trigger a cluster-wide refresh with ONE call to ANY instance:
#   curl -X POST http://any-instance:8080/actuator/busrefresh

go deeper

for a junior

Know the one-liner: Bus = broker linking instances so one busrefresh call refreshes the whole cluster.

for a middle

Be able to name the starters, the default springCloudBus topic, and the exposure config for the Actuator endpoint.

for a senior

Explain that it's built on Spring Cloud Stream and carries RefreshRemoteApplicationEvent, plus the refresh vs busrefresh distinction.

for a principal

Position the Bus in the config-propagation architecture and know its limits — it's a control-plane broadcast, not a domain-event system.

## The problem In a microservice system you often run many instances of the same service. Spring Cloud Config lets those instances load configuration from a central Git-backed Config Server. But configuration is read at startup (and cached). When you change a property in the config repo, running instances don't see it automatically. Spring Boot Actuator gives each instance a `/actuator/refresh` endpoint: POST to it and that **one** instance re-reads its configuration and rebinds beans annotated with `@RefreshScope` and `@ConfigurationProperties`. The pain: with 30 instances you'd have to call `/actuator/refresh` 30 times, and you'd need to know every instance's address. ## What Spring Cloud Bus adds The Bus links all instances together over a shared **message broker** — either **RabbitMQ** or **Apache Kafka**. Think of it as an event backbone connecting every node. Instead of calling refresh per-instance: 1. you POST **once** to `/actuator/busrefresh` on any single instance; 2. that instance publishes a `RefreshRemoteApplicationEvent` onto the broker; 3. every instance subscribed to the Bus receives it and performs a local refresh. One call, whole cluster refreshed. ## How it's wired The Bus is implemented on top of **Spring Cloud Stream** — it does not talk to the broker directly, it uses a Stream binder. All instances share a single broker destination (a Kafka topic / Rabbit exchange) named **`springCloudBus`** by default. Messages carry `RemoteApplicationEvent` subclasses. ## Getting it running 1. Add one starter — `spring-cloud-starter-bus-amqp` (RabbitMQ) or `spring-cloud-starter-bus-kafka` — 2. and point it at a reachable broker (e.g. `spring.rabbitmq.host` / `spring.kafka.bootstrap-servers`). 3. Because `busrefresh` is an Actuator endpoint, you must **expose** it: `management.endpoints.web.exposure.include=busrefresh`. Then any config change followed by one `POST /actuator/busrefresh` reaches the whole fleet. ## Beyond refresh The same event backbone also carries `EnvironmentChangeRemoteApplicationEvent` (via the `/actuator/busenv` endpoint, which pushes a single property to the cluster) and optional acknowledgement/trace events. But config refresh is by far the headline use case. ## When to use it - Use the Bus when you have many instances and want cluster-wide, low-friction config refresh (or lightweight state-change broadcasts). - If you have a single instance, plain `/actuator/refresh` is enough and the Bus is overkill. - The Bus is not a general application messaging system — for domain events use Spring Cloud Stream / a broker directly.

  • How is /actuator/busrefresh different from /actuator/refresh?
    /actuator/refresh refreshes only the single instance you call. /actuator/busrefresh publishes a RefreshRemoteApplicationEvent onto the broker so every instance connected to the Bus refreshes — one call fans out to the whole cluster.
  • Which brokers does Spring Cloud Bus support?
    RabbitMQ (via spring-cloud-starter-bus-amqp) and Apache Kafka (via spring-cloud-starter-bus-kafka). It uses Spring Cloud Stream binders underneath, so the broker choice is just which starter/binder you include.

saying these in an interview costs you the question

  • Thinking the Bus talks to the broker directly rather than through Spring Cloud Stream
  • Believing busrefresh restarts the application (it only re-reads config and rebinds beans)
  • Assuming the Bus itself stores or serves configuration (that's the Config Server; the Bus only broadcasts the refresh signal)

context

open as a page

How does a Spring Boot application connect to a Spring Cloud Config Server using spring.config.import, and what does the configserver: prefix do?

level: juniorimportance: must knowfreq 78%

basics

~10 s

Add the spring-cloud-starter-config dependency, then set spring.config.import=configserver:http://localhost:8888 in application.yml. On startup the app fetches its properties from that Config Server before creating beans.

open as a page

In a Spring Cloud Config Server property repository, what does the {cipher} prefix on a property value mean, and what happens to it before the client receives the value?

level: juniorimportance: must knowfreq 55%

basics

~20 s

{cipher} marks a property value as encrypted at rest in the config repo. By default the Config Server decrypts it and sends the plain value to the client, so the secret never sits in git as plaintext.

open as a page

What does Spring Cloud Kubernetes do with a ConfigMap, and how does its data reach your beans?

level: juniorimportance: must knowfreq 60%

basics

~10 s

Spring Cloud Kubernetes reads a Kubernetes ConfigMap (named after your app) and adds its key/value entries to the Spring Environment as a PropertySource, so @Value and @ConfigurationProperties see them like any other property.

open as a page

What is @RefreshScope and what happens when you POST to /actuator/refresh?

level: juniorimportance: must knowfreq 70%

basics

~10 s

@RefreshScope marks a bean so it can pick up new configuration at runtime. Calling POST /actuator/refresh reloads the configuration and recreates those beans, so they see the new property values without restarting the app.

open as a page

What is Spring Cloud Config Server, and how do you turn a Spring Boot application into one?

level: juniorimportance: must knowfreq 78%

basics

~10 s

It is a central server that stores application configuration (usually in git) and serves it to client apps over HTTP. You add the spring-cloud-config-server dependency and put @EnableConfigServer on the main class.

open as a page

What is Spring Cloud Vault, and how do secrets stored in HashiCorp Vault end up as ordinary properties your beans can inject?

level: juniorimportance: must knowfreq 60%

basics

~10 s

Spring Cloud Vault reads secrets from HashiCorp Vault at startup and adds them to Spring's Environment as a property source, so @Value and @ConfigurationProperties inject them just like application.yml values.

open as a page

What exactly happens when you POST to /actuator/busrefresh, and which event is broadcast?

level: middleimportance: must knowfreq 50%

basics

~20 s

The instance you call publishes a RefreshRemoteApplicationEvent onto the shared broker topic. Every instance on the Bus receives it and does a local refresh — re-reading config and rebinding @RefreshScope / @ConfigurationProperties beans, exactly like calling /actuator/refresh on each one.

open as a page

What do spring.cloud.config.fail-fast and the retry settings do, and how are they wired together on the client?

level: middleimportance: must knowfreq 70%

basics

~20 s

fail-fast=true makes the app refuse to start if it cannot reach the Config Server. Adding spring-retry and Spring AOP lets it retry the connection a few times (with backoff) before giving up, controlled by spring.cloud.config.retry.* properties.

open as a page

On /actuator/refresh, which beans pick up new values — @Value beans vs @ConfigurationProperties beans — and why?

level: middleimportance: must knowfreq 60%

basics

~10 s

@ConfigurationProperties beans are automatically rebound with new values on refresh, no annotation needed. A bean using @Value only picks up new values if you also put @RefreshScope on it.

open as a page

Explain the /{application}/{profile}/{label} endpoint the Config Server exposes: what does each path variable mean and how does it map to files in the backend?

level: middleimportance: must knowfreq 70%

basics

~20 s

application is the client's spring.application.name, profile is its active profile(s), and label is the git branch/tag (defaults to main). The server maps these to files like {application}-{profile}.yml on that branch and returns their merged properties.

open as a page

How does Spring Cloud Kubernetes reload configuration when a ConfigMap changes, and what are the watch vs polling modes?

level: seniorimportance: must knowfreq 55%

basics

~20 s

Enable spring.cloud.kubernetes.reload.enabled=true. In event (watch) mode it watches ConfigMaps/Secrets via the Kubernetes API and reacts instantly; in polling mode it re-reads them on a fixed period. A detected change fires a refresh that rebinds beans.

open as a page

How does Spring Cloud Vault handle lease renewal and rotation for dynamic secrets, and what must your beans do to pick up rotated values?

level: seniorimportance: must knowfreq 40%

basics

~20 s

Dynamic secrets come with a lease (a TTL). A SecretLeaseContainer renews the lease before it expires and, when it can't renew, requests fresh secrets (rotation). To use rotated values, your beans must be in @RefreshScope so they're recreated with the new values.

open as a page

What dependencies and configuration are required to enable Spring Cloud Bus refresh in a service?

level: middleimportance: should knowfreq 30%

basics

~10 s

Add one broker starter — spring-cloud-starter-bus-amqp (RabbitMQ) or spring-cloud-starter-bus-kafka — plus Actuator, point the app at a running broker, and expose the endpoint with management.endpoints.web.exposure.include=busrefresh. Then POST /actuator/busrefresh.

open as a page

How do you produce a {cipher} value for the config repo using the Config Server's /encrypt and /decrypt endpoints?

level: middleimportance: should knowfreq 45%

basics

~10 s

POST the plaintext to the Config Server's /encrypt endpoint; it returns ciphertext. You paste that into the repo prefixed with {cipher}. POST ciphertext to /decrypt to reverse it. Both need a configured key.

open as a page

How does Spring Cloud Kubernetes expose Kubernetes Secrets to the Environment, and what security defaults matter?

level: middleimportance: should knowfreq 45%

basics

~10 s

It contributes a Secrets PropertySource so Secret keys become Spring properties. Secret values are base64-decoded automatically. Reading Secrets via the Kubernetes API is opt-in (enableApi); by default it reads Secrets from mounted file paths.

open as a page

What backends can a Config Server use to store configuration, and how do you configure git vs native?

level: middleimportance: should knowfreq 58%

basics

~10 s

Common backends are git (default, versioned), native (files on the classpath or filesystem, handy for local dev), and Vault (secrets). Git needs spring.cloud.config.server.git.uri; native is enabled with the 'native' profile and search-locations.

open as a page

What is the difference between KV secret engine v1 and v2 in Spring Cloud Vault, and how does configuration differ?

level: middleimportance: should knowfreq 45%

basics

~20 s

KV v1 stores a single current value per key; KV v2 adds versioning (history, soft-delete) and uses a different read path with a /data/ segment. Spring Cloud Vault handles the path difference when you set the backend version.

open as a page

How does Spring Cloud Bus use Spring Cloud Stream, and how does it ensure the event reaches every instance rather than just one?

level: seniorimportance: should knowfreq 35%

basics

~20 s

The Bus doesn't talk to the broker directly — it rides on Spring Cloud Stream, publishing to a shared destination called springCloudBus. To broadcast (not load-balance) it gives each instance a distinct identity (spring.cloud.bus.id) so every instance receives its own copy of the event.

open as a page

Explain the difference between the ConfigData import mechanism and the legacy bootstrap context for Config Client, and how you'd re-enable bootstrap.

level: seniorimportance: should knowfreq 52%

basics

~20 s

Old versions created a separate 'bootstrap' application context from bootstrap.yml to fetch config before the main app. Since Spring Boot 2.4 that's replaced by spring.config.import handled inside the normal startup. To use the old way you add spring-cloud-starter-bootstrap or set spring.cloud.bootstrap.enabled=true.

open as a page

When properties come from both the Config Server and the client's local application.yml, which wins, and how can you change that?

level: seniorimportance: should knowfreq 58%

basics

~10 s

By default the Config Server's properties take precedence over the client's local application.yml, so central config overrides local defaults. You can flip this with flags like spring.cloud.config.override-none=true so local values win instead.

open as a page

By default the Config Server decrypts {cipher} values before responding. How do you make the client decrypt instead, and why might you want that?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Set spring.cloud.config.server.encrypt.enabled=false on the server so it passes {cipher} values through untouched. Each client must then hold the key and decrypt them itself. You'd do this so plaintext secrets never leave the client boundary or transit the network.

open as a page

Compare configuring symmetric encryption (encrypt.key) versus an RSA keystore for a Spring Cloud Config Server. When would you choose each?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Symmetric uses a single shared secret in encrypt.key — simple but the same key encrypts and decrypts. An RSA keystore uses a public/private key pair (encrypt.keyStore.*) so encryption and decryption can be separated, giving stronger, more manageable at-rest protection.

open as a page

Explain how a config change ends up rebinding a @RefreshScope / @ConfigurationProperties bean, without a Config Server.

level: seniorimportance: should knowfreq 40%

basics

~20 s

The reload watcher detects the ConfigMap change and publishes a RefreshEvent. Spring Cloud's ContextRefresher rebuilds the Environment, re-binds @ConfigurationProperties beans, and destroys @RefreshScope beans so they are recreated with the new values on next use.

open as a page

Walk through the events fired by ContextRefresher during /actuator/refresh: EnvironmentChangeEvent vs RefreshScopeRefreshedEvent — what each carries and their order.

level: seniorimportance: should knowfreq 40%

basics

~20 s

First the Environment is reloaded and an EnvironmentChangeEvent is published carrying the set of changed property keys. Then the refresh scope is cleared and a RefreshScopeRefreshedEvent is published to signal that refresh-scoped beans were evicted.

open as a page

What are the concurrency and lifecycle gotchas of @RefreshScope beans — in-flight requests, @PostConstruct, and beans holding expensive resources?

level: seniorimportance: should knowfreq 30%

basics

~20 s

A refresh evicts the bean but recreation is lazy, so a request already running keeps the old instance. On recreation, the old bean's @PreDestroy runs and the new bean's @PostConstruct runs again. Beans that open connections or pools get torn down and rebuilt, which can be costly.

open as a page

What is the EnvironmentRepository abstraction, and what does its findOne(application, profile, label) return?

level: seniorimportance: should knowfreq 44%

basics

~20 s

EnvironmentRepository is the interface every Config Server backend implements. Its findOne(application, profile, label) method reads the backend and returns an Environment object holding an ordered list of PropertySources for that app/profile/label, which the client merges.

open as a page

Walk through how the Config Server resolves profiles and labels for a request, including precedence and the default label.

level: seniorimportance: should knowfreq 40%

basics

~20 s

Profiles pick which -{profile} files to include and how they layer (more specific wins over shared/base files). The label selects the git branch/tag/commit to read from; if the client sends none, the server's default-label (main, historically master) is used.

open as a page

How does Spring Cloud Vault's database secret engine integration provide a DataSource, and what are the operational implications of per-instance dynamic credentials?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Vault's database engine generates a unique, short-lived DB username/password per request. Spring Cloud Vault reads database/creds/<role> and exposes them as spring.datasource.username/password, so your DataSource connects with generated credentials that Vault renews or rotates via leases.

open as a page

You run 30 Spring Boot services on Kubernetes and want config changes to take effect safely. How do you design ConfigMap/Secret reload, and what are the failure modes?

level: principalimportance: should knowfreq 30%

basics

~20 s

Enable reload with event+refresh for fast, zero-downtime changes to refresh-safe values, scope watches to each app's own ConfigMap/Secret with least-privilege RBAC, and use restart_context/shutdown (with replicas + probes) for structural changes. Guard against instant bad config with validation and rollout controls.

open as a page

showing 1–30 of 36