You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次部署时自动化填充AWS Parameter Store的Serverless技术问题

解决Serverless部署时SSM参数缺失&自动创建RDS的问题

我明白你的痛点:首次部署时SSM参数还没创建,Serverless提前去读参数导致报错,之前用的before:package:cleanup钩子时机确实太晚了——那时候Serverless已经在解析CloudFormation模板、尝试拉取SSM参数了。给你几个可行的方案,从省心到灵活:

方案一:用CloudFormation自定义资源(最省心)

不用写额外脚本或插件,直接在serverless.yml里定义CloudFormation资源,让CloudFormation自动先创建SSM参数,再部署RDS——完全集成在部署流程里,不会有参数找不到的问题。

示例配置:

resources:
  Resources:
    # 先创建SSM用户名参数
    RDSAdminUserParam:
      Type: AWS::SSM::Parameter
      Properties:
        Name: /my-app/rds/admin-user
        Type: String
        Value: db-admin
        Description: RDS管理员账号

    # 自动生成随机密码并存到SSM
    RDSAdminPassParam:
      Type: AWS::SSM::Parameter
      Properties:
        Name: /my-app/rds/admin-pass
        Type: SecureString
        # 用CloudFormation内置函数从栈ID生成随机字符串,也可以换Lambda生成更复杂的密码
        Value: !Join ['', [!Select [0, !Split ['-', !Select [4, !Split ['/', !Ref AWS::StackId]]]], !Select [1, !Split ['-', !Select [4, !Split ['/', !Ref AWS::StackId]]]]]]
        Description: 自动生成的RDS管理员密码

    # 引用SSM参数创建RDS实例
    MyRDSInstance:
      Type: AWS::RDS::DBInstance
      Properties:
        DBInstanceClass: db.t3.micro
        Engine: MySQL
        MasterUsername: !Ref RDSAdminUserParam
        MasterUserPassword: !Ref RDSAdminPassParam
        PubliclyAccessible: false # 生产环境建议关闭公网访问
        AllocatedStorage: 20
        # 其他RDS配置按需添加...

部署时CloudFormation会严格按顺序执行:先创建两个SSM参数,再用这些参数创建RDS。后续调试数据库时,用AWS CLI就能取到凭据:

# 获取用户名
aws ssm get-parameter --name /my-app/rds/admin-user

# 获取密码(需要解密)
aws ssm get-parameter --name /my-app/rds/admin-pass --with-decryption

方案二:用更早的Serverless钩子执行自定义脚本

如果需要自定义参数生成逻辑(比如从外部系统拉取密码),可以把脚本绑定到Serverless开始解析模板之前的钩子,确保参数在模板读取前就准备好。推荐这两个钩子:

  • before:package:package:在打包部署资源前执行,此时还未处理模板中的SSM引用
  • before:deploy:deploy:如果部署流程包含自动打包,这个钩子会在打包启动前触发

修改serverless.yml的插件配置:

plugins:
  - serverless-scriptable-plugin

custom:
  scriptable:
    hooks:
      before:package:package: ${file(scripts/create-ssm-params.js)}

然后编写scripts/create-ssm-params.js脚本,逻辑是检查参数是否存在,不存在就自动创建:

const { SSMClient, GetParameterCommand, PutParameterCommand } = require('@aws-sdk/client-ssm');
const crypto = require('crypto');

module.exports = async () => {
  const ssmClient = new SSMClient({ region: process.env.AWS_REGION || 'us-east-1' });
  
  // 定义要创建的参数:用户名固定,密码自动生成16位随机字符串
  const paramsToSet = [
    { name: '/my-app/rds/admin-user', value: 'db-admin', type: 'String' },
    { name: '/my-app/rds/admin-pass', value: crypto.randomBytes(16).toString('hex'), type: 'SecureString' }
  ];

  for (const param of paramsToSet) {
    try {
      // 先检查参数是否存在
      await ssmClient.send(new GetParameterCommand({ Name: param.name }));
      console.log(`✅ 参数 ${param.name} 已存在,跳过`);
    } catch (err) {
      if (err.name === 'ParameterNotFound') {
        // 不存在则创建参数
        await ssmClient.send(new PutParameterCommand({
          Name: param.name,
          Value: param.value,
          Type: param.type,
          Overwrite: false // 避免覆盖已有参数
        }));
        console.log(`✅ 创建缺失参数 ${param.name}`);
      } else {
        // 其他错误直接抛出,中断部署
        throw err;
      }
    }
  }
};

⚠️ 注意:要确保部署用的AWS账号拥有ssm:GetParameter和ssm:PutParameter的权限,否则脚本会执行失败。

总结

  • 追求简单稳定:选方案一,完全依赖CloudFormation原生能力,不用额外维护脚本;
  • 需要自定义参数逻辑:选方案二,用更早的钩子提前创建参数,适配复杂场景。

内容的提问来源于stack exchange,提问作者Lukasz_K_K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:22:42