Quản lý Secret an toàn trên AWS: Thay thế Environment Variables bằng AWS Secrets Manager (Lambda & EC2) Chuyên mục Devops 2026-01-05 4 Lượt xem 4 Lượt thích 0 Bình luận
Trong các hệ thống cloud hiện đại, quản lý secret (DB credentials, API keys, tokens, …) là một trong những yếu tố quan trọng nhất về bảo mật. Tuy nhiên, rất nhiều hệ thống vẫn đang:
-
Hard-code credentials trong source code
-
Lưu secret trực tiếp trong Environment Variables
-
Chia sẻ file .env giữa nhiều môi trường
Bài viết này sẽ hướng dẫn cách sử dụng AWS Secrets Manager để thay thế Environment Variables, áp dụng cho AWS Lambda và mở rộng cho EC2, kèm theo best practices & lưu ý thực tế khi vận hành production.
Vì sao KHÔNG nên dùng Environment Variables cho Secret?
Nhược điểm của Environment Variables
| Vấn đề | Mô tả |
|---|---|
| Hiển thị | Có thể xem trực tiếp trong Lambda / EC2 console |
| Audit | Không có audit log chi tiết |
| Rotation | Không hỗ trợ tự động |
| Security | Dễ bị lộ khi debug / log |
| Giới hạn | Lambda chỉ cho phép ~4KB |
👉 ENV phù hợp cho config không nhạy cảm, nhưng KHÔNG phù hợp cho secret.
AWS Secrets Manager là gì?
AWS Secrets Manager là service chuyên dụng để:
-
Lưu trữ secret được mã hóa (KMS)
-
Quản lý version
-
Tự động rotate credentials
-
Audit qua CloudTrail
-
Tích hợp native với RDS, Aurora, DocumentDB
Kiến trúc tổng quát
Lambda / EC2
|
| IAM Role
v
AWS Secrets Manager
|
v
Aurora / DocumentDB / External API
PHẦN 1: SỬ DỤNG SECRETS MANAGER TRONG AWS LAMBDA
Bước 1: Tạo Secret trong AWS Console
AWS Console → Secrets Manager → Store a new secret
1. Secret type
-
Chọn: Credentials for Amazon RDS database
2. Credentials
Username: admin (master username của DB)
Password: ********
📌 admin chính là master username của database bạn đã khai báo khi tạo Aurora / DocumentDB.
3. Database
-
Chọn Aurora / DocumentDB cluster tương ứng
4. Secret name
prod/database/credentials
Bước 2: Configure Secret Details
-
Description:
Production database credentials for Lambda -
Encryption key:
aws/secretsmanager (default KMS key) -
Replica regions (optional):
Bật nếu multi-region
Bước 3: (Optional) Enable Rotation
-
Automatic rotation: Enabled
-
Rotation interval: 30 days
-
Lambda function: Create new
👉 AWS sẽ tự động:
-
Rotate password
-
Update DB
-
Update secret
Bước 4: Cấp quyền IAM cho Lambda
Lambda Execution Role → Add Inline Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-northeast-1:*:secret:prod/database/credentials-*"
}
]
}
Bước 5: Lambda Code (Python)
import boto3
import json
import pymysql
def get_secret():
client = boto3.client('secretsmanager')
response = client.get_secret_value(
SecretId='prod/database/credentials'
)
return json.loads(response['SecretString'])
def lambda_handler(event, context):
secret = get_secret()
connection = pymysql.connect(
host=secret['host'],
user=secret['username'],
password=secret['password'],
database=secret['dbname'],
connect_timeout=5
)
return {"status": "connected"}
Performance Tip cho Lambda
Secrets Manager là API call → có latency (~20–50ms)
Best practice:
-
Cache secret trong global scope
SECRET_CACHE = None
def get_secret_cached():
global SECRET_CACHE
if SECRET_CACHE is None:
client = boto3.client('secretsmanager')
response = client.get_secret_value(
SecretId='prod/database/credentials'
)
SECRET_CACHE = json.loads(response['SecretString'])
return SECRET_CACHE
PHẦN 2: SỬ DỤNG SECRETS MANAGER TRÊN EC2
Lambda không phải lúc nào cũng là lựa chọn duy nhất. Với EC2 / ECS / long-running service, cách tiếp cận có chút khác.
Cách 1: EC2 dùng IAM Role (Recommended)
Bước 1: Attach IAM Role cho EC2
IAM Role policy:
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-northeast-1:*:secret:prod/database/credentials-*"
}
Bước 2: Code trên EC2 (Python)
import boto3
import json
def get_secret():
client = boto3.client('secretsmanager', region_name='ap-northeast-1')
response = client.get_secret_value(
SecretId='prod/database/credentials'
)
return json.loads(response['SecretString'])
secret = get_secret()
DB_HOST = secret['host']
👉 Không cần access key / secret key
👉 EC2 lấy credential qua Instance Metadata Service (IMDS)
Cách 2: Inject Secret khi EC2 boot (Không khuyến khích)
aws secretsmanager get-secret-value \
--secret-id prod/database/credentials \
--query SecretString \
--output text > /opt/app/secret.json
❌ Dễ bị leak
❌ Không rotation runtime
❌ Không audit tốt
So sánh: Lambda vs EC2 khi dùng Secrets Manager
| Tiêu chí | Lambda | EC2 |
|---|---|---|
| IAM | Execution Role | Instance Role |
| Cache | In-memory | In-memory / file |
| Rotation | Tự động | Tự động |
| Security | Rất cao | Cao |
| Latency | Có (API call) | Ít ảnh hưởng |
Best Practices Thực Tế (RẤT QUAN TRỌNG)
✅ Nên làm
-
Tách secret theo environment:
-
dev/database/credentials
-
prod/database/credentials
-
-
Tạo DB user riêng cho application
-
Enable CloudTrail cho Secrets Manager
-
Dùng IAM Role thay vì access key
-
Cache secret trong memory
❌ Không nên làm
-
Dùng master DB user cho app
-
Log secret ra CloudWatch
-
Hard-code secret name trong nhiều nơi
-
Chia sẻ secret giữa nhiều service không liên quan
Khi nào NÊN dùng Secrets Manager?
✅ Database credentials
✅ API keys (Stripe, OpenAI, Twilio…)
✅ OAuth client secret
✅ Production workloads
Khi nào KHÔNG cần?
⚠️ Feature flags
⚠️ Non-sensitive config
⚠️ Local development (có thể mock)
Kết luận
AWS Secrets Manager không chỉ là nơi lưu secret – mà là một phần quan trọng của kiến trúc security hiện đại.
Việc thay thế Environment Variables bằng Secrets Manager:
-
Giảm rủi ro security
-
Chuẩn hóa vận hành
-
Dễ audit & scale
-
Phù hợp production-grade system
Nếu bạn đang chạy:
-
Lambda
-
EC2
-
ECS / Fargate
-
Aurora / DocumentDB
👉 Secrets Manager là lựa chọn gần như bắt buộc.
Bình luận (0)