Lambda函数SSM环境变量未更新问题求助
问题场景
我新建了一个Cognito栈,确认Parameter Store里的参数已经更新为新Cognito栈的ID,但Lambda函数的环境变量仍然指向已删除的旧栈ID,怀疑是缓存问题。尝试用--no-previous-parameters部署无效,求解决办法。
相关代码
SSM参数读取类:
export class SSMParameterReader extends AwsCustomResource { constructor(scope: Construct, name: string, props: SSMParameterReaderProps) { const { parameterName, region } = props; const ssmAwsSdkCall: AwsSdkCall = { service: 'SSM', action: 'getParameter', parameters: { Name: parameterName, }, region, physicalResourceId: { id: name }, // Update physical id to always fetch the latest version }; super(scope, name, { onUpdate: ssmAwsSdkCall, policy: { statements: [ new iam.PolicyStatement({ resources: ['*'], actions: ['ssm:GetParameter'], effect: iam.Effect.ALLOW, }), ], }, }); } public getParameterValue(): string { return this.getResponseField('Parameter.Value').toString(); } }
参数调用函数:
export function getFromSSM(scope: Construct, paramName: string, env?: any): string { return new SSMParameterReader(scope, scope.node.id + paramName + 'Reader', { parameterName: paramName, region: env?.region || 'eu-central-1', }).getParameterValue(); }
问题原因
你的SSMParameterReader使用了固定值作为physicalResourceId,CDK的自定义资源只有在物理ID发生变化时,才会触发资源更新逻辑。由于这个ID始终不变,即使SSM参数的值已经更新,CDK会判定该自定义资源没有变更,不会重新执行getParameter获取最新值,最终导致Lambda的环境变量一直沿用旧的参数值。
解决方案
1. 让物理ID随SSM参数版本动态变化
修改ssmAwsSdkCall中的physicalResourceId配置,用SSM参数的版本号作为物理ID。参数更新时版本号会递增,CDK就会触发自定义资源重新拉取最新值:
const ssmAwsSdkCall: AwsSdkCall = { service: 'SSM', action: 'getParameter', parameters: { Name: parameterName, }, region, // 用参数版本作为物理ID,版本变化时触发更新 physicalResourceId: PhysicalResourceId.fromResponse('Parameter.Version'), };
2. 补充自定义资源的创建触发逻辑
原代码只配置了onUpdate,首次创建栈时不会触发参数读取,建议同时添加onCreate配置,确保首次部署也能正确获取参数:
super(scope, name, { onCreate: ssmAwsSdkCall, // 添加创建时的执行逻辑 onUpdate: ssmAwsSdkCall, policy: { statements: [ new iam.PolicyStatement({ resources: ['*'], actions: ['ssm:GetParameter'], effect: iam.Effect.ALLOW, }), ], }, });
3. 强制触发CDK更新
如果上述修改后仍未生效,可以尝试强制部署来跳过CDK的缓存判断:
cdk deploy --force
或者临时修改自定义资源的逻辑ID(比如给Reader的名称加个临时后缀),部署后再改回原名称,这样CDK会重新创建自定义资源,强制拉取最新的SSM参数。
验证
修改代码后重新部署CDK栈,检查Lambda函数的环境变量是否已更新为新的Cognito栈ID,同时确认Parameter Store中的参数版本是否被正确识别。
内容的提问来源于stack exchange,提问作者Karim Chaari

