Loading…
Spring Boot Configuration Management Best Practices
JetbrainsSiva Katamreddy
Summary
Spring Boot externalizes application configuration across files, environment variables, system properties, and command-line arguments to allow a single artifact to run across multiple environments. A resilient setup classifies values into application defaults, deployment configurations, and externalized secrets stored in dedicated vaults. Binding properties to type-safe Java records via @ConfigurationProperties ensures immutability, supports relaxed property mapping, and eliminates the discovery issues common to scattered @Value annotations. Enforcing validation with @Validated and Jakarta Bean Validation constraints triggers fail-fast startup behavior when required settings are absent or malformed. Property precedence determines the effective runtime values, which must be adapted appropriately whether deploying a monolith, containerized workloads in Kubernetes, or a microservices cluster.
Context
Configuring Spring Boot applications across various deployment environments often risks runtime failures and security issues when configuration is mixed with application code, lacks startup validation, or improperly exposes secrets.
Approach / What changed
Categorizing configurations into defaults, deployment settings, and secrets, while using @ConfigurationProperties with Java records, Jakarta Bean Validation for fail-fast startup checks, and platform-specific property injection.
Takeaways
- Java records are preferred for @ConfigurationProperties because they provide out-of-the-box immutability, preventing accidental runtime modifications that can occur with setter-based class binding.
- Combining @Validated with Jakarta Bean Validation and spring-boot-starter-validation stops application startup immediately when required properties are missing, out of range, or structurally invalid.
- Spring Boot resolves conflicting properties through a precedence hierarchy where command-line arguments override Java system properties, OS environment variables, and property files in descending order.
Related reading
Grab ·
Palana (Part 1): Why Grab built a secure platform for autonomous AI Agents
Autonomous AI agents introduce significant operational and security risks when granted network access, persistent state, and credentials. To address these concerns without impeding developer productivity, Grab created Palana, an in-house Kubernetes-native execution substrate. The platform isolates each agent workload within its own namespace, pairing it with dedicated storage, network policies, and role-based access control. Network egress is funneled through an Envoy and Open Policy Agent proxy layer that audits requests and injects credentials from HashiCorp Vault using placeholder tokens, keeping raw secrets outside the agent runtime. This design allows Grab to securely host hundreds of long-running workflows, remote coding environments, and automation bots.
Kevin LittlejohnSlack ·
Shipyard: How We Built Slack’s Next-Generation EC2 Platform
Slack developed Shipyard to modernize its EC2 infrastructure by replacing continuously updated, mutable instances with immutable deployable artifacts. The platform adopts a layered image architecture starting with a standardized base image called slack-zero, which is built using AWS Image Builder and consumed by downstream service-specific machine images. Rather than running periodic Chef jobs in the background, configuration management is restricted to image baking and initial instance provisioning phases. Fleet management is handled through the Peekaboo inventory system, metric-driven progressive rollouts via Gondola, and automated instance rotation managed by a lifecycle component known as the Reaper. Developers validate cookbook updates prior to merging using Ship Quick, which provisions real infrastructure across dedicated worker fleets to verify provisioning workflows.
Archie GunasekaraGrab ·
One Small Step Closer to Containerising Service Binaries
Engineering teams at Grab initiated a transition to containerized microservices to standardize environments, enhance security, and decouple services from internal runtime tooling. During this migration, developers noticed that statically-linked Go service binaries were reaching bloated sizes over 100 MB. By analyzing the binaries using the open-source tool go-binsize-viz alongside the Go nm toolchain, the team visualized compiled symbols as interactive treemaps. This analysis revealed that 11 MB of unused message format symbols were being pulled in because a generic interface shared a directory with auto-generated streaming code. Restructuring the packages to isolate interfaces from generated code successfully decreased the binary size down to 78 MB.
Stan HalkaGrab ·
Palana (Part 2): Architecting isolation, identity, and auditability for AI agents
Grab's Palana platform provisions isolated, Kubernetes-native runtime environments for autonomous AI agents using dedicated per-agent namespaces and role-based access controls. The architecture separates network enforcement across layers, applying Layer 3 and Layer 4 containment with Cilium and NetworkPolicy alongside Layer 7 application filtering evaluated by Open Policy Agent. Agent interactions with large language models route through a LiteLLM proxy wrapper that retrieves credentials from HashiCorp Vault based on Kubernetes pod context rather than client headers. Secrets management is divided between directly readable agent paths and proxy-only placeholder paths that prevent raw tokens from residing in runtime filesystems. An automated reaper monitors multi-source activity signals to shut down idle compute resources while preserving persistent storage and configuration state.
Kevin Littlejohn