AWS Secrets Manager 详解
AWS Secrets Manager 是什么?说白了,就是 AWS 帮你管密码、、数据库连接串这些敏感信息的托管服务。我刚开始接触多云项目时,团队还在手动把密钥写进环境变量,结果一次误操作把生产库密码打到了日志里……嗯,从那以后,我坚定地上了 Secrets Manager。
它解决了什么问题?
先想想平时你怎么管密钥:写在代码里?不安全。存在配置文件里?容易泄漏。用 KMS 加密后存 S3?轮换时还得写一堆脚本。Secrets Manager 把这些痛点一锅端了:
- 集中存储:所有密钥放一个地方,不用再翻几十个文件。
- 自动轮换:设置好轮换周期,它自己换,不用半夜爬起来改密码。
- 细粒度访问控制:结合 IAM,谁可以读哪个密钥,清清楚楚。
- 审计追踪:每次读密钥都记在 CloudTrail 里,出了问题可以溯源。
核心概念:Secret 与 Secret Value
在 Secrets Manager 里,一个“Secret”是一个逻辑容器,包含元数据(名称、标签、描述、轮换配置)和实际的“Secret Value”。Secret Value 可以是任意字符串,但最常见的是 JSON 格式,比如:
{
"username": "admin",
"password": "SuperSecret!2025",
"host": "db.example.com",
"port": 3306
}
我个人习惯把同一个服务的所有连接信息放在一个 Secret 里,用 JSON 组织,这样读取时一次拿到全部,避免多次 API 调用。
自动轮换机制
自动轮换是 Secrets Manager 最吸引人的功能。它怎么做到的?通过一个 Lambda 函数。AWS 提供了针对 RDS、Redshift、DocumentDB 等服务的预置轮换模板,也可以自己写。
轮换流程大致是:
- Secrets Manager 调用 Lambda,生成一个新密码。
- Lambda 用当前“待定”版本更新数据库。
- 验证新密码可用,然后将新版本标记为“当前”,旧版本标记为“以前”。
- 应用可以在过渡期内同时使用新旧两个版本,避免断连。
这里有个关键细节:切换不是瞬间的,中间有短暂的“双版本”共存窗口。如果你的应用只认一个密码,需要做好重试机制。
访问控制:IAM 与资源策略
Secrets Manager 支持两种策略:
- IAM 策略:附加给用户、角色,控制他们能访问哪些 Secret。
- 资源策略:直接挂在 Secret 上,控制谁能访问这个 Secret,甚至可以跨账号。
我建议优先用 IAM 策略,因为它更符合最小权限原则。资源策略适合跨账号场景,比如你需要让另一个 AWS 账号里的应用读取你的密钥。
| 策略类型 | 适用场景 | 示例 |
|---|---|---|
| IAM 策略 | 同账号下用户/角色 | 允许某 EC2 实例的角色读取特定 Secret |
| 资源策略 | 跨账号或公开访问 | 允许另一账号的 Lambda 访问本账号的 Secret |
如何用 SDK 读取 Secret
来看一段 Python 代码,这是最常用的方式:
import boto3
import json
def get_secret(secret_name):
client = boto3.client('secretsmanager')
try:
response = client.get_secret_value(SecretId=secret_name)
secret_string = response.get('SecretString')
if secret_string:
return json.loads(secret_string)
else:
# 如果是二进制密钥,走 SecretBinary
return response.get('SecretBinary')
except Exception as e:
print(f"读取密钥 {secret_name} 失败: {e}")
raise
注意 get_secret_value 这个 API 会返回整个 Secret 的当前版本。如果启用了多版本,你可以指定 VersionStage 参数来获取历史版本。我个人只在回滚场景下才用历史版本,平时不要依赖它,因为轮换后旧版本会逐渐被清理。
性能与成本考量
Secrets Manager 的 API 调用是按次数计费的。每次读取大概 0.05 美元/万次,看着便宜,但如果你在热搜路径里每毫秒都读一次,账单会很难看。建议:
- 在应用启动时读取一次,缓存在内存中,定时刷新。
- 不要每次请求都去读 Secret,除非密钥会高频轮换。
- 利用 SDK 内置缓存,比如 AWS Lambda 扩展的 Secrets Manager 缓存层。
Secrets Manager 整体架构
下面这张图展示了核心工作流:
避坑指南(实测过的)
用 Secrets Manager 时,有几个坑我反复踩过,列出来希望你能跳过:
- 不要直接使用根账号密钥:Secrets Manager 本身不存储 AWS 根账号的密钥,但如果你把 IAM 用户的 Access Key 当作 Secret 存进去,记得也要自动轮换,否则泄露后很难收场。
- 注意 VPC 端点:如果你的应用在 VPC 内且没有公网访问,必须创建 Secrets Manager 的 VPC 端点,否则 API 调用会超时。我见过运维小伙子配了三天没搞定,最后发现忘了加端点策略。
- 轮换超时问题:默认轮换 Lambda 超时是 15 分钟,如果你的数据库在另一个区域,网络延迟加上 SSL 握手可能超时,建议改成 5 分钟以上,或者把 Lambda 部署在离数据库近的区域。
- 版本管理:Secrets Manager 最多保留 100 个版本,超过后会删除最旧的。如果你的轮换频率很高(比如每 5 分钟一次),最好调大保留数量,或者关掉自动清理。
总结性建议
AWS Secrets Manager 不是银弹,但相比自建 Vault 或明文存储,它省心太多了。我现在的习惯是:所有多云项目的密钥,统一通过 AWS Secrets Manager 管理,然后再用 Terraform 或 Crossplane 同步到其他云。至于怎么同步,那是后面章节的事。
嗯,最后补一句:永远不要把 Secret 打出来或者写进日志。我在代码审查时遇到过同事为了调试,把整个 Secret JSON 打印出来,结果被运维告警系统捕获……嗯,那场面挺尴尬的。