Contents

The YAML below shows the complete configuration for this feature. Adjust the values to match your environment.

# configmap.yaml — non-sensitive application config apiVersion: v1 kind: ConfigMap metadata: name: payment-service-config namespace: payments data: # Individual key-value pairs LOG_LEVEL: "INFO" FEATURE_FLAG_NEW_CHECKOUT: "true" MAX_RETRY_ATTEMPTS: "3" # Full application.properties file as a multi-line value application.properties: | spring.application.name=payment-service management.endpoints.web.exposure.include=health,info,prometheus spring.jpa.show-sql=false app.payment.timeout-seconds=30 # Create from literal values kubectl create configmap payment-service-config \ --from-literal=LOG_LEVEL=INFO \ --from-literal=MAX_RETRY_ATTEMPTS=3 \ -n payments # Create from an existing properties file kubectl create configmap payment-service-config \ --from-file=application.properties=./k8s/application-prod.properties \ -n payments # View kubectl get configmap payment-service-config -n payments -o yaml

The YAML below shows the complete configuration for this feature. Adjust the values to match your environment.

# In the Deployment container spec spec: containers: - name: payment-service image: myorg/payment-service:1.0.0 env: # Single key from ConfigMap - name: LOG_LEVEL valueFrom: configMapKeyRef: name: payment-service-config key: LOG_LEVEL # All keys from ConfigMap as env vars (SCREAMING_SNAKE_CASE → spring.property) envFrom: - configMapRef: name: payment-service-config

Spring Boot automatically maps environment variables to properties: SPRING_DATASOURCE_URLspring.datasource.url.

Mount a ConfigMap as a file — Spring Boot's spring.config.location picks it up automatically. Useful for full application.properties or YAML files.

spec: containers: - name: payment-service image: myorg/payment-service:1.0.0 env: - name: SPRING_CONFIG_LOCATION value: "classpath:/,file:/etc/config/" volumeMounts: - name: app-config mountPath: /etc/config readOnly: true volumes: - name: app-config configMap: name: payment-service-config items: - key: application.properties path: application.properties Volume-mounted ConfigMap files are automatically updated by kubelet when the ConfigMap changes (within ~60 seconds) — without pod restart. Environment variables are NOT updated — they are fixed at pod startup.

The YAML below shows the complete configuration for this feature. Adjust the values to match your environment.

# secret.yaml — base64-encoded values (use Sealed Secrets or ESO in production) apiVersion: v1 kind: Secret metadata: name: payment-service-secrets namespace: payments type: Opaque data: # Values must be base64-encoded DB_PASSWORD: cGFzc3dvcmQxMjM= # echo -n "password123" | base64 STRIPE_API_KEY: c2tfbGl2ZV8uLi4= stringData: # stringData is plain text — Kubernetes base64-encodes it REDIS_PASSWORD: "my-redis-password" # Create from literals (Kubernetes does the base64 encoding) kubectl create secret generic payment-service-secrets \ --from-literal=DB_PASSWORD=password123 \ --from-literal=STRIPE_API_KEY=sk_live_... \ -n payments # Create TLS secret kubectl create secret tls api-tls-cert \ --cert=tls.crt \ --key=tls.key \ -n payments # Mount secrets as environment variables spec: containers: - name: payment-service envFrom: - secretRef: name: payment-service-secrets # Or individual secret keys env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: payment-service-secrets key: DB_PASSWORD

Spring Cloud Kubernetes reads ConfigMaps and Secrets directly from the Kubernetes API — no environment variable mapping needed. The ConfigMap name matches spring.application.name by default.

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-client-config</artifactId> </dependency> # application.yml spring: application: name: payment-service # ConfigMap named "payment-service" is loaded automatically cloud: kubernetes: config: enabled: true name: payment-service-config # override name namespace: payments secrets: enabled: true name: payment-service-secrets namespace: payments # RBAC — give the pod permission to read ConfigMaps and Secrets apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: config-reader namespace: payments rules: - apiGroups: [""] resources: ["configmaps", "secrets", "pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: config-reader-binding namespace: payments subjects: - kind: ServiceAccount name: default namespace: payments roleRef: kind: Role name: config-reader apiGroup: rbac.authorization.k8s.io

Spring Cloud Kubernetes can watch ConfigMaps for changes and trigger a context refresh without restarting the pod.

# application.yml spring: cloud: kubernetes: reload: enabled: true mode: polling # or "event" for watch-based (requires RBAC watch verb) period: 15000 # poll every 15 seconds strategy: refresh # refresh vs restart_context vs shutdown // Beans annotated with @RefreshScope are recreated after a reload @RefreshScope @Service public class FeatureFlagService { @Value("${feature.new-checkout:false}") private boolean newCheckoutEnabled; public boolean isNewCheckoutEnabled() { return newCheckoutEnabled; } }

The External Secrets Operator syncs secrets from AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, or Azure Key Vault into Kubernetes Secrets — keeping the source of truth outside the cluster.

# SecretStore — points to AWS Secrets Manager apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: aws-secrets-manager namespace: payments spec: provider: aws: service: SecretsManager region: us-east-1 auth: serviceAccount: # use IRSA for RBAC name: external-secrets-sa --- # ExternalSecret — defines which secrets to sync apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: payment-service-secrets namespace: payments spec: refreshInterval: 1h secretStoreRef: name: aws-secrets-manager kind: SecretStore target: name: payment-service-secrets # resulting K8s Secret name creationPolicy: Owner data: - secretKey: DB_PASSWORD # key in the K8s Secret remoteRef: key: payment-service/prod # path in AWS Secrets Manager property: db_password # field within the secret JSON - secretKey: STRIPE_API_KEY remoteRef: key: payment-service/prod property: stripe_api_key