AWS Secrets Manager + Parameter Store 凭证管理实战:从硬编码到零泄露完整教程(2026最新版)

📅 · AWS 国际版实战教程 - ChengziCloud

一句话结论

Meta Description: AWS Secrets Manager 和 Parameter Store 凭证管理完整教程:创建密钥、IAM 权限策略、Lambda/RDS/ECS 集成、自动轮换、价格对比与成本优化,告别硬编码零泄露实战指南。

本文要点
  • 前言
  • 为什么必须用密钥管理服务:硬编码的 5 大风险
  • Secrets Manager vs Parameter Store:选哪个?
  • 实战一:用 Secrets Manager 管理数据库密码
  • 实战二:用 Parameter Store 管理配置参数
  • IAM 权限策略:谁能读哪些密钥
  • 实战三:Lambda + Secrets Manager 集成
  • 实战四:RDS 自动轮换密码

Meta Description: AWS Secrets Manager 和 Parameter Store 凭证管理完整教程:创建密钥、IAM 权限策略、Lambda/RDS/ECS 集成、自动轮换、价格对比与成本优化,告别硬编码零泄露实战指南。

关键词:AWS Secrets Manager、AWS Parameter Store、密钥管理、凭证轮换、IAM策略、Lambda密钥、RDS密码、SSM Parameter Store、AWS安全合规

前言

先给结论:把数据库密码、API Key、第三方服务凭证硬编码在代码或环境变量里,是 AWS 账号被入侵的第一大入口。 AWS 提供了两个原生工具来解决这个问题:Secrets Manager(管理动态密钥,支持自动轮换)和 Systems Manager Parameter Store(管理配置参数和静态密钥)。选哪个?动态密钥选 Secrets Manager(数据库密码、API Key),静态配置选 Parameter Store(Region、环境标志),两者搭配用最省钱。 本文基于 2026 年最新 AWS 控制台和 CLI 实操,手把手带你从"密钥散落在代码里"升级到"集中管理、自动轮换、零泄露"的安全架构。

一、为什么必须用密钥管理服务:硬编码的 5 大风险

在动手之前,先看看不用密钥管理服务会怎样:

风险场景后果
代码泄露开发者把含密码的代码推到 GitHub数据库被拖库,勒索赎金
环境变量暴露Docker inspect、/proc/xxx/environ 可读容器逃逸后凭证一览无余
无法轮换密码写死在 10 个服务里一次泄露 = 手动改 10 处,漏改就等着被攻击
审计缺失谁在什么时候读了密码?不知道出了安全事件无法溯源
合规失败SOC2、PCI-DSS、等保 2.0 审计被判定不合规,丢客户

AWS 官方推荐的架构:所有敏感信息存入 Secrets Manager 或 Parameter Store,应用通过 IAM 策略按需获取,访问日志全部进 CloudTrail。

二、Secrets Manager vs Parameter Store:选哪个?

很多人搞不清这两个服务的区别。简单记:Secrets Manager 管"秘密"(密码、密钥),Parameter Store 管"参数"(配置、环境变量)。 详细对比:

对比维度Secrets ManagerParameter Store
适合存储数据库密码、API Key、OAuth Token、证书环境标志、Region、配置字符串、非敏感参数
自动轮换✅ 原生支持(RDS/Redshift/DocumentDB/Aurora)❌ 不支持
加密自动 KMS 加密支持 Standard(免费)和 SecureString(KMS 加密)
版本管理✅ 自动多版本,可回滚✅ 支持参数版本
跨区域复制✅ 原生跨区域复制❌ 不支持
付费模式$0.40/密钥/月 + $0.05/10,000 次 API 调用Standard 参数免费,SecureString 免费(API 调用免费)
免费额度无Standard 参数无限免费,SecureString 免费
最大参数大小64 KBStandard: 4 KB,高级参数: 8 KB
CloudTrail 审计✅ 自动记录所有 API 调用✅ 自动记录所有 API 调用

决策口诀:

  • 数据库密码、API Key、需要自动轮换的 → Secrets Manager
  • 环境标志、配置字符串、非敏感信息 → Parameter Store Standard
  • 大于 4KB 但小于 8KB 的加密配置 → Parameter Store SecureString

三、实战一:用 Secrets Manager 管理数据库密码

3.1 控制台操作:创建一个数据库密钥

登录 AWS 控制台,搜索"Secrets Manager",点击"存储新密钥"。

选择"数据库凭证",然后选择数据库类型(以 MySQL 为例):

  • 密钥名称:prod/myapp/mysql
  • 描述:生产环境 MySQL 数据库密码
  • 数据库:选择已有的 RDS 实例(或手动输入连接信息)
  • 用户名:admin
  • 密码:选择"自动生成"(推荐,16 位随机密码)
  • 加密密钥:使用默认的 aws/secretsmanager
  • 轮换:暂不配置(下面单独讲)

点击"存储",密钥创建完成。记下密钥 ARN(后续 IAM 策略和代码集成要用)。

3.2 CLI 操作:批量创建密钥

如果需要一次性创建多个密钥,用 CLI 更高效:


// 创建 MySQL 数据库密钥
aws secretsmanager create-secret \
  --name "prod/myapp/mysql" \
  --description "Production MySQL credentials" \
  --secret-string '{"username":"admin","password":"MyStr0ng!Pass2026"}' \
  --region us-east-1

// 创建 Redis 密钥
aws secretsmanager create-secret \
  --name "prod/myapp/redis" \
  --description "Production Redis auth token" \
  --secret-string '{"host":"my-redis.xxx.cache.amazonaws.com","port":"6379","auth_token":"r3d1s_T0k3n_2026"}' \
  --region us-east-1

// 创建第三方 API Key
aws secretsmanager create-secret \
  --name "prod/myapp/stripe-api-key" \
  --description "Stripe payment gateway API key" \
  --secret-string 'sk_live_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --region us-east-1

关键点:密钥名称用 / 分隔表示层级结构(prod/myapp/mysql),方便后续按前缀批量授权。

3.3 读取密钥:Python + Boto3


import boto3
import json

def get_secret(secret_name):
    """从 Secrets Manager 获取密钥,带本地缓存"""
    client = boto3.client('secretsmanager', region_name='us-east-1')

    try:
        response = client.get_secret_value(SecretId=secret_name)
        secret = json.loads(response['SecretString'])
        return secret
    except client.exceptions.ResourceNotFoundException:
        print(f"密钥 {secret_name} 不存在")
        return None
    except client.exceptions.AccessDeniedException:
        print(f"没有权限读取 {secret_name},检查 IAM 策略")
        return None

    // 使用示例
    db_cred = get_secret('prod/myapp/mysql')
if db_cred:
    conn = pymysql.connect(
        host='mydb.xxx.rds.amazonaws.com',
        user=db_cred['username'],
        password=db_cred['password'],
        database='myapp'
    )

性能优化提示:Boto3 客户端默认每次调用 AWS API 都会发起网络请求。在 Lambda 中建议用 aws-lambda-powertools 库的缓存功能,或自己实现 LRU 缓存,避免每次请求都读 Secrets Manager($0.05/万次 API 调用会累积)。

四、实战二:用 Parameter Store 管理配置参数

4.1 控制台操作:创建参数

搜索"Systems Manager" → "参数存储" → "创建参数":

  • 名称:/myapp/prod/region
  • 类型:String
  • 值:us-east-1
  • 描述:应用部署区域

对于敏感配置,选择"SecureString"类型(使用 KMS 加密):

  • 名称:/myapp/prod/redis-host
  • 类型:SecureString
  • 值:my-redis.xxx.cache.amazonaws.com

4.2 CLI 操作:批量创建参数


// 创建普通字符串参数
aws ssm put-parameter \
  --name "/myapp/prod/region" \
  --type "String" \
  --value "us-east-1" \
  --description "App deployment region"

// 创建 SecureString 参数
aws ssm put-parameter \
  --name "/myapp/prod/redis-host" \
  --type "SecureString" \
  --value "my-redis.xxx.cache.amazonaws.com" \
  --description "Redis cluster endpoint"

// 创建带标签的参数(方便批量管理)
aws ssm put-parameter \
  --name "/myapp/prod/max-connections" \
  --type "String" \
  --value "100" \
  --tags "Key=Environment,Value=prod" "Key=App,Value=myapp"

4.3 高级参数(Advanced Parameters)

如果参数值超过 4KB(比如存储完整的 JSON 配置文件),需要使用高级参数:


aws ssm put-parameter \
  --name "/myapp/prod/app-config" \
  --type "String" \
  --value '{"database":{"pool_size":20,"timeout":30},"cache":{"ttl":3600}}' \
  --tier "Advanced" \
  --description "Full app configuration JSON"

高级参数的限制:8KB 大小上限,每月前 10,000 次 API 调用免费,之后 $0.05/万次。对于绝大多数应用,高级参数完全够用。

五、IAM 权限策略:谁能读哪些密钥

IAM 策略是安全的核心——最小权限原则:只给应用它需要的密钥访问权限,不多给一个。

5.1 Lambda 读取特定密钥的策略


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadMyAppSecrets",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "ssm:GetParameter",
                "ssm:GetParameters"
            ],
            "Resource": [
                "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/*",
                "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/prod/*"
            ]
        },
        {
            "Sid": "DecryptSecureStrings",
            "Effect": "Allow",
            "Action": "kms:Decrypt",
            "Resource": "arn:aws:kms:us-east-1:123456789012:key/xxx",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "ssm.us-east-1.amazonaws.com"
                }
            }
        }
    ]
}

5.2 限制只能读最新版本


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadOnlyLatestVersion",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:us-east-1:*:secret:prod/myapp/*",
            "Condition": {
                "StringEquals": {
                    "secretsmanager:VersionStage": "AWSCURRENT"
                }
            }
        }
    ]
}

安全提醒:永远不要给 secretsmanager:DeleteSecret 或 ssm:DeleteParameter 权限给应用角色——只有管理员才能删除密钥。

六、实战三:Lambda + Secrets Manager 集成

6.1 在 Lambda 中读取密钥


import boto3
import json
from functools import lru_cache

@lru_cache(maxsize=1)
def get_db_config():
    """带 LRU 缓存的密钥获取(Lambda 容器复用时不会重复请求)"""
    client = boto3.client('secretsmanager', region_name='us-east-1')
    response = client.get_secret_value(SecretId='prod/myapp/mysql')
    return json.loads(response['SecretString'])

def lambda_handler(event, context):
    config = get_db_config()

    // 使用密钥建立数据库连接
    import pymysql
    conn = pymysql.connect(
        host=config['host'],
        user=config['username'],
        password=config['password'],
        database=config['dbname'],
        cursorclass=pymysql.cursors.DictCursor
    )

    // 你的业务逻辑...
    return {'statusCode': 200, 'body': 'OK'}

关键优化:Lambda 容器可能被复用(warm start),用 @lru_cache 缓存密钥可以避免重复调用 Secrets Manager API,既省钱又降低延迟。

6.2 Lambda 环境变量中引用密钥(推荐)

AWS 支持在 Lambda 环境变量中直接引用 Secrets Manager 和 Parameter Store 的值:

在 Lambda 配置 → 环境变量 → 编辑中:

  • 键:DB_SECRET
  • 值:{"SecretsManager": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/mysql"}

这样在代码中直接用 os.environ['DB_SECRET'] 即可获取,无需在代码中 import boto3,既简化代码又更安全。

七、实战四:RDS 自动轮换密码

Secrets Manager 最强大的功能是自动轮换数据库密码——设置一次,AWS 每 30 天自动改密码,应用通过密钥名读取最新密码,完全无感。

7.1 启用轮换(控制台)

  1. 打开 Secrets Manager → 选择密钥
  2. 点击"轮换"标签页 → "编辑轮换配置"
  3. 轮换 Lambda:选择或创建一个轮换函数(AWS 提供了 RDS MySQL/PostgreSQL 的预置模板)
  4. 轮换间隔:30 天(最短可设 1 天)
  5. KMS 密钥:使用默认即可

7.2 CLI 启用轮换


// 为 RDS MySQL 密钥配置自动轮换
aws secretsmanager rotate-secret \
  --secret-id "prod/myapp/mysql" \
  --rotation-lambda-arn "arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotationSingleUser" \
  --rotation-rules '{"AutomaticallyAfterDays":30}' \
  --region us-east-1

7.3 轮换流程原理

  1. Secrets Manager 调用轮换 Lambda
  2. Lambda 生成新密码
  3. Lambda 在数据库中更新密码
  4. Lambda 在 Secrets Manager 中更新密钥值
  5. Lambda 验证新密码能正常连接
  6. 完成,旧密码被标记为 AWSPREVIOUS

整个过程不到 30 秒,应用完全无感知——下次读取密钥时自动获得新密码。

八、价格对比与成本优化

8.1 价格对比表

方案月固定成本API 调用费自动轮换适合场景
Secrets Manager$0.40/密钥$0.05/万次✅ 原生支持数据库密码、API Key、需要轮换的密钥
Parameter Store Standard免费免费❌环境标志、配置字符串、非敏感参数
Parameter Store Advanced免费(前10K次)$0.05/万次❌大于 4KB 的配置(JSON 配置文件)
环境变量(硬编码)免费—❌⚠️ 不推荐用于敏感信息

8.2 成本优化策略

策略 1:混合使用,省钱 80%

不要所有东西都塞进 Secrets Manager。实际拆分:

  • Secrets Manager($0.40/个/月):数据库密码、Stripe API Key、SendGrid API Key 等真正需要轮换的密钥
  • Parameter Store Standard(免费):Region、环境标志、最大连接数、日志级别等非敏感配置

假设你有 5 个数据库密钥 + 20 个配置参数:

  • 全用 Secrets Manager:5 × $0.40 = $2.00/月 + API 调用费
  • 混合使用:5 × $0.40 = $2.00/月 + 0(Parameter Store 免费)

策略 2:在 Lambda 中缓存密钥

每次 Lambda 调用都读 Secrets Manager = $0.05/万次。如果 Lambda 每天被调用 10 万次,一年 API 调用费 = $18.25。用 @lru_cache 缓存后,每次容器启动只读一次,成本降到约 $0.06/年(1000 个容器 × $0.05/万次 × 12 月)。

策略 3:合并同类型密钥

一个 Secrets Manager 密钥可以存储 JSON 格式的多个字段。把同一服务的多个凭证合并到一个密钥里(如 {"host":"...","port":"...","username":"...","password":"..."}),减少密钥数量。

九、ECS/EKS 集成:容器化应用的密钥管理

9.1 ECS Fargate 读取 Secrets

在 ECS 任务定义中,可以直接将 Secrets Manager 和 Parameter Store 的值映射为容器环境变量:


{
    "containerDefinitions": [
        {
            "name": "myapp",
            "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest",
            "secrets": [
                {
                    "name": "DB_PASSWORD",
                    "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/mysql:password::"
                }
            ],
            "environment": [
                {
                    "name": "DB_HOST",
                    "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/prod/db-host"
                }
            ]
        }
    ]
}

关键区别:secrets 字段从 Secrets Manager 获取,environment 字段从 Parameter Store 获取。容器启动时自动注入,不需要在代码中调用任何 SDK。

9.2 EKS(Kubernetes)集成

在 Kubernetes 中使用 External Secrets Operator 或 AWS Secrets Store CSI Driver:


// 使用 CSI Driver 将密钥挂载为 Volume
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "prod/myapp/mysql"
        objectType: "secretsmanager"
        jmesPath:
          - path: username
            objectAlias: db-username
          - path: password
            objectAlias: db-password

这样密钥会以文件形式挂载到 Pod 的 /mnt/secrets/ 目录,应用从文件读取即可。

十、审计与监控:谁在什么时候读了密钥

10.1 CloudTrail 审计

所有 Secrets Manager 和 Parameter Store 的 API 调用都会自动记录到 CloudTrail。在 CloudTrail 控制台搜索:

  • 事件源:secretsmanager.amazonaws.com 或 ssm.amazonaws.com
  • 事件名称:GetSecretValue、PutSecretValue、RotateSecret

10.2 设置异常检测告警


// 用 CloudWatch 监控异常的密钥读取行为
aws cloudwatch put-metric-alarm \
  --alarm-name "ExcessiveSecretReads" \
  --metric-name "GetSecretValue" \
  --namespace "AWS/SecretsManager" \
  --statistic Sum \
  --period 300 \
  --threshold 100 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 1 \
  --alarm-actions "arn:aws:sns:us-east-1:123456789012:security-alerts" \
  --region us-east-1

如果某个 Lambda 函数在 5 分钟内读了 100 次密钥,说明可能有死循环或配置错误,立即收到告警。

十一、常见问题 FAQ

Q: Secrets Manager 和 Parameter Store 能一起用吗?

可以,而且推荐这样做。实际架构中,一个应用通常同时使用两者:Secrets Manager 存放数据库密码、API Key 等需要轮换的密钥,Parameter Store 存放环境标志、配置参数等非敏感信息。Lambda 和 ECS 都支持同时引用两个服务。

Q: Secrets Manager 的 $0.40/密钥/月 贵吗?

不贵。10 个密钥 = $4/月,换取的是自动轮换、集中审计、零泄露风险。相比之下,一次数据库泄露的损失(数据恢复、客户赔偿、品牌声誉)远超 $4/月。而且 Parameter Store Standard 是完全免费的,非敏感配置不用花钱。

Q: Lambda 冷启动时读 Secrets Manager 会更慢吗?

会有 50-100ms 的额外延迟(首次调用时)。解决方案:① 用 Lambda 环境变量引用密钥(容器启动时自动注入,不需要在代码中调用 API);② 用 @lru_cache 缓存密钥(warm start 时零延迟);③ 用 Provisioned Concurrency 保持容器热。

Q: 密钥轮换后,旧的密码还能用吗?

轮换完成后,旧密码被标记为 AWSPREVIOUS,默认 24 小时后自动删除。在 24 小时窗口内,使用旧版本标签仍可读取旧密码。这是为了在轮换出问题时可以快速回滚。生产环境建议设置为 0 天(立即删除旧版本)。

Q: Parameter Store 的高级参数和 Secrets Manager 价格一样吗?

不一样。高级参数 API 调用 $0.05/万次(和 Secrets Manager 相同),但没有 $0.40/月的固定费用。对于需要加密但不需要轮换的配置,高级参数比 Secrets Manager 便宜。

Q: 如何跨账号共享密钥?

Secrets Manager 支持跨账号共享:在密钥的资源策略中添加目标账号的 ARN 即可。Parameter Store 不支持跨账号,但可以用 CloudFormation StackSets 在多个账号中同步创建相同参数。

总结

凭证管理是 AWS 安全的基石。从"密码写在代码里"到"Secrets Manager + Parameter Store"的迁移,核心就三步:

  1. 分类:敏感密钥(密码、API Key)放 Secrets Manager,配置参数放 Parameter Store
  2. 授权:用 IAM 策略按前缀精细控制谁能读哪些密钥
  3. 轮换:对数据库密码启用自动轮换,对 API Key 设置定期提醒手动轮换

⚠️ 文中价格为 2026 年参考价,实际费用随区域和官方调价变动,请以 AWS 官网为准。

🚀 需要 AWS 国际版账号?通过 3.chengzicloud.cloud 获取最新注册教程与专属优惠,助你轻松上云。

本文由 3.chengzicloud.cloud 提供,点击访问首页了解更多