OpsCanary
kubernetesobservabilityPractitioner

Dynamic Configuration for Cloud Native Swift Services in Kubernetes

5 min read CNCF BlogJun 1, 2026Reviewed for accuracy
Share
PractitionerHands-on experience recommended

Dynamic configuration is essential for cloud-native applications that require flexibility and responsiveness to changes. In a Kubernetes environment, managing configuration dynamically can significantly enhance your service's resilience and adaptability. The Swift Configuration library provides a robust mechanism for this by separating the reading of configuration from its provision. This allows you to utilize various ConfigProviders, ensuring that your application can adapt to changes in real-time without downtime.

At the core of this setup is the ConfigReader, which takes an ordered list of types conforming to the ConfigProvider protocol. The first provider that has a value for a given key takes precedence. Static providers handle bootstrap configuration values, while dynamic providers like ReloadingFileProvider are designed for values that need to update without a service restart. You can achieve hot reloading by mounting a ConfigMap as a volume and pointing the provider at the mounted path. For instance, you can configure a ReloadingFileProvider to watch a configuration file, checking for updates every 15 seconds. If a reload produces an invalid result, the provider retains the last known good snapshot, ensuring stability.

In production, be aware of the potential pitfalls. If your configuration file becomes invalid during a reload, the ReloadingFileProvider will not crash your application; instead, it will revert to the last valid configuration. This feature is crucial for maintaining uptime. Always test your configuration changes thoroughly to avoid unexpected behavior. As of June 1, 2026, this approach remains relevant, but ensure you keep an eye on updates to the Swift Configuration library for any new features or changes that could impact your setup.

Key takeaways

  • Utilize ConfigReader to manage configuration from multiple providers effectively.
  • Implement ReloadingFileProvider for hot reloading of configuration without service restarts.
  • Set config.pollIntervalSeconds to 15 for regular checks on configuration file changes.
  • Remember that invalid reloads retain the last known good snapshot to prevent application crashes.

Why it matters

Dynamic configuration allows your services to adapt to changes in real-time, reducing downtime and improving resilience in a cloud-native environment. This flexibility is critical for maintaining service reliability and performance.

Code examples

swift
1// Providers are initialized asynchronously: EnvironmentVariablesProvider reads
2// the process environment and .env file at initialization, so the initialization is asynchronous.
3async let staticProviders: [(any ConfigProvider)] = [
4   CommandLineArgumentsProvider(),
5   EnvironmentVariablesProvider(),
6   EnvironmentVariablesProvider(environmentFilePath: ".env", allowMissing: true),
7   InMemoryProvider(values: [
8       "log.level": "info",
9       "config.filePath": "/etc/config/appsettings.yaml",
10       "config.pollIntervalSeconds": 15,
11       "http.serverName": "my-service",
12   ]),
13]
14
15let initConfig = ConfigReader(providers: staticProviders)
16let logLevel = initConfig.string(
17    forKey: "log.level",
18    as: Logger.Level.self,
19    default: .info
20)
21let httpConfig = initConfig.scoped(to: "http") // reads "http.port", "http.host" as just "port", "host"
22let reloadingProvider = try await ReloadingFileProvider<YAMLSnapshot>(
23   config: initConfig.scoped(to: "config")
24)
25let config = ConfigReader(
26   providers: [reloadingProvider] + staticProviders
27)
swift
1struct ConfigWatchReporter: Service {
2   let config: ConfigReader
3   let logger: Logger
4   func run() async throws {
5       try await self.config.scoped(to: "app")
6       .watchString(forKey: "name", default: "unset") { updates in
7           for try await update in updates.cancelOnGracefulShutdown() {
8               logger.info("Received a configuration change: \(update)")
9           }
10       }
11   }
12}
13let configReporter = ConfigWatchReporter(config: config, logger: logger)
swift
1let app = Application(
2   router: router,
3   configuration: ApplicationConfiguration(reader: config.scoped(to: "http")),
4   services: [
5       reloadingProvider,
6       configReporter,
7   ],
8   logger: logger
9)

When NOT to use this

The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →
Better StackSponsor

Unified observability — logs, uptime monitoring, and on-call in one place. Used by 50,000+ engineering teams to ship faster and sleep better.

Try Better Stack free →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.