如何通过AWS CDK在构建时将SSM密钥加载到Lambda环境变量中
如何用AWS CDK在构建时将SSM参数存储的密钥注入Lambda环境变量
问题原因解析
你遇到的ValidationError是因为CloudFormation本身不支持直接引用SecureString类型的SSM参数作为Lambda环境变量值。SecureString是加密存储的,CloudFormation无法在部署阶段自动解密并注入明文到环境变量,因此会抛出类型不支持的错误。而AwsCustomResource方案虽然可行,但会额外创建一个用于拉取参数的Lambda,不符合你的需求。
可行解决方案:构建时主动拉取参数
要实现**构建阶段(synth时)**获取SSM参数并注入Lambda环境变量,有两种可靠方式,均无需额外创建Lambda资源:
方法1:在CDK代码中用AWS SDK直接拉取
通过在CDK synth阶段调用AWS SDK的SSM客户端,主动获取参数值,再直接赋值给Lambda环境变量。
步骤:
- 安装AWS SDK v3的SSM客户端:
npm install @aws-sdk/client-ssm
- 修改CDK代码:
import { App, Stack } from 'aws-cdk-lib'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { Runtime } from 'aws-cdk-lib/aws-lambda'; import path from 'path'; import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'; // 用异步函数处理SSM调用 async function createLambdaStack(app: App) { const stack = new Stack(app, 'LambdaSSMParamStack'); // 初始化SSM客户端(替换为你的AWS区域) const ssmClient = new SSMClient({ region: 'cn-north-1' }); // 发送获取参数请求(带解密) const paramCmd = new GetParameterCommand({ Name: 'BIGQUERY_JSON_CRED', WithDecryption: true, }); const paramResp = await ssmClient.send(paramCmd); const bqCred = paramResp.Parameter?.Value || ''; // 创建Lambda并注入环境变量 new NodejsFunction(stack, 'HelloLambda', { entry: path.resolve(__dirname, '../src/functions/hello/handler.ts'), handler: 'handler', runtime: Runtime.NODEJS_20_X, environment: { BIGQUERY_JSON_CRED: bqCred, }, }); } const app = new App(); // 处理异步错误 createLambdaStack(app).catch(err => { console.error('构建失败:', err); process.exit(1); }); app.synth();
注意事项:
- 执行CDK的环境(本地/CI/CD)需要拥有
ssm:GetParameter权限,若参数用自定义KMS密钥加密,还需kms:Decrypt权限。 - 生成的CloudFormation模板(
cdk.out目录下)会包含明文参数值,务必将cdk.out加入.gitignore,避免泄露敏感信息。 - 参数更新后需重新执行
cdk synth && cdk deploy,因为值是在构建阶段固定的。
方法2:通过CDK Context参数注入
通过命令行将SSM参数值传入CDK Context,再在代码中读取Context值注入环境变量,无需在CDK代码中引入AWS SDK。
步骤:
- CDK代码中读取Context:
import { App, Stack } from 'aws-cdk-lib'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { Runtime } from 'aws-cdk-lib/aws-lambda'; import path from 'path'; const app = new App(); const stack = new Stack(app, 'LambdaSSMParamStack'); // 从Context中获取参数值 const bqCred = app.node.tryGetContext('bigqueryCred') || ''; new NodejsFunction(stack, 'HelloLambda', { entry: path.resolve(__dirname, '../src/functions/hello/handler.ts'), handler: 'handler', runtime: Runtime.NODEJS_20_X, environment: { BIGQUERY_JSON_CRED: bqCred, }, }); app.synth();
- 部署时通过命令行注入参数:
cdk deploy --context bigqueryCred=$(aws ssm get-parameter --name BIGQUERY_JSON_CRED --with-decryption --query Parameter.Value --output text)
注意事项:
- 同样要确保执行
aws ssm命令的环境拥有对应权限。 - 构建后的模板仍会包含明文参数值,需注意模板安全。
内容的提问来源于stack exchange,提问作者TheSmartMonkey
相关产品推荐
相关产品推荐

