99 Ngày Spring — Ngày 91: Config và Secrets cho Production
Cùng một bản build phải chạy được ở dev, staging và production; thứ khác nhau giữa các môi trường là cấu hình. Nguyên tắc 12-factor nói cấu hình nằm ở môi trường, không nằm trong code. Spring Boot hỗ trợ sẵn điều đó, nhưng secret cần thêm một lớp kỷ luật: không vào Git, không vào image, không vào log.

1. Cấu hình đến từ môi trường
Spring Boot đọc property từ nhiều nguồn và nguồn bên ngoài thắng nguồn đóng gói: tham số dòng lệnh, rồi biến môi trường, rồi file cấu hình bên ngoài jar, rồi mới tới application.yml trong jar. Relaxed binding ánh xạ biến SPRING_DATASOURCE_URL thành spring.datasource.url. Vì vậy application.yml trong jar chỉ nên chứa giá trị mặc định an toàn, còn giá trị riêng của từng môi trường được truyền vào lúc chạy.
# packaged defaults (application.yml)
payment:
base-url: http://localhost:9090
timeout: 2s
# production, supplied by the platform
# PAYMENT_BASE_URL=https://pay.internal.example
# PAYMENT_TIMEOUT=1s
# SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/shop2. @ConfigurationProperties có kiểm tra
Gom cấu hình của một tính năng vào một record có kiểu thay vì rải @Value khắp nơi. Thêm @Validated và các ràng buộc Bean Validation để ứng dụng từ chối khởi động khi thiếu hoặc sai cấu hình. Lỗi lúc khởi động rẻ hơn nhiều so với NullPointerException ở request đầu tiên vào lúc nửa đêm.
@Validated
@ConfigurationProperties("payment")
record PaymentProperties(
@NotNull URI baseUrl,
@NotNull @DurationMin(millis = 100) Duration timeout,
@NotBlank String apiKey) {}
@SpringBootApplication
@ConfigurationPropertiesScan
class ShopApplication {}3. Secret: không Git, không image, không log
Secret là cấu hình mà lộ ra thì gây thiệt hại: mật khẩu database, API key, khóa ký JWT. Nền tảng chạy ứng dụng nên cấp chúng lúc chạy, qua biến môi trường hoặc tốt hơn là file được mount. Spring Boot đọc được cả thư mục secret bằng configtree: mỗi file là một property, tên file là key, nội dung là giá trị. Với hệ thống lớn, dùng secret manager như Vault hoặc dịch vụ của cloud để có phân quyền, nhật ký truy cập và xoay vòng.
# /run/secrets/payment.api-key -> property payment.api-key
spring.config.import=optional:configtree:/run/secrets/4. Kỷ luật vận hành
Actuator endpoint /env và /configprops che giá trị theo mặc định từ Spring Boot 3; đừng mở lại ở production. Profile dùng để bật nhóm bean khác nhau, không dùng để cất mật khẩu trong application-prod.yml. Khi một secret đã lỡ vào Git, xóa commit là chưa đủ: phải coi như đã lộ và xoay vòng ngay.
Một image cho mọi môi trường; chỉ cấu hình thay đổi.
Mỗi môi trường và mỗi service có secret riêng, quyền tối thiểu.
Không in toàn bộ cấu hình hay header Authorization ra log.
Bật quét secret trong CI để chặn trước khi merge.
Có quy trình xoay vòng đã được diễn tập, không đợi đến khi có sự cố.
Cấu hình tốt là cấu hình sai thì ứng dụng không khởi động, và secret tốt là secret xoay vòng được. Ngày 92 làm cho log của production trở nên tra cứu được.
Tài liệu đối chiếu
https://docs.spring.io/spring-boot/reference/features/external-config.html
https://12factor.net/config
Site Admin
Engineer and writer. Building things with TypeScript and distributed systems.
Bình luận (0)
Bạn cần đăng nhập bằng Google để bình luận.
Hãy là người bình luận đầu tiên.


