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

AWS CodeBuild中CDK读取SSM参数时捕获异常失败问题

解决CDK中SSM参数Lookup失败导致CodeBuild终止的问题

问题场景

我在CodeBuild项目中使用CDK代码读取SSM参数,首次运行时该参数不存在,我写了try/catch逻辑想让程序继续执行,但还是报错终止了CodeBuild:

SSM parameter not available in account 1234, region us-east-1: /api-endpoint error stops the codebuild project error

我的代码:

let apiEndpoint: string;

try {
  apiEndpoint = ssm.StringParameter.valueFromLookup(this, `api-endpoint`)
} catch (error: any) {
  if (error.message.includes('ParameterNotFound')) {
    // Handle the case where the parameter doesn't exist yet
    console.warn('SSM parameter "api-endpoint" not found. Using default value.');
    apiEndpoint = 'default-value';
  } else {
    // Handle other errors
    throw error;
  }
}

核心原因

你遇到的问题本质是**ssm.StringParameter.valueFromLookup是CDK合成阶段(synth)执行的操作,而非运行时逻辑**。CDK在生成CloudFormation模板的过程中会同步调用AWS API查询SSM参数,如果参数不存在,这个查询会直接抛出异常并终止synth流程——你的try/catch块是TypeScript代码逻辑,只会在代码运行时生效,根本到不了触发catch的阶段。

解决方案

方案1:在CodeBuild运行时读取SSM参数(推荐)

放弃在CDK中提前查询参数,改为在CodeBuild的构建脚本里用AWS CLI读取,这样可以在运行时捕获参数不存在的情况:

修改buildspec.yml:

version: 0.2
phases:
  build:
    commands:
      - |
        # 尝试读取SSM参数,捕获错误输出
        API_ENDPOINT=$(aws ssm get-parameter --name "/api-endpoint" --query "Parameter.Value" --output text 2>/dev/null)
        if [ -z "$API_ENDPOINT" ]; then
          echo "SSM参数/api-endpoint不存在,使用默认值"
          API_ENDPOINT="default-value"
        fi
        # 将参数设为环境变量供后续步骤使用
        export API_ENDPOINT=$API_ENDPOINT
        # 执行你的构建命令,比如 npm run build

方案2:在CDK中使用自定义资源处理

如果必须在CDK层面获取参数值,可以用AWS自定义资源(Custom Resource)来异步读取SSM参数,这样即使参数不存在,也可以在部署阶段处理并返回默认值:

import * as cdk from 'aws-cdk-lib';
import * as customresources from 'aws-cdk-lib/custom-resources';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as codebuild from 'aws-cdk-lib/aws-codebuild';

export class YourStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 创建自定义资源读取SSM参数
    const ssmLookupResource = new customresources.AwsCustomResource(this, 'ApiEndpointLookup', {
      onCreate: {
        service: 'SSM',
        action: 'getParameter',
        parameters: {
          Name: 'api-endpoint'
        },
        physicalResourceId: customresources.PhysicalResourceId.of('ApiEndpointLookup'),
      },
      // 给自定义资源添加读取SSM参数的权限
      policy: customresources.AwsCustomResourcePolicy.fromStatements([
        new iam.PolicyStatement({
          actions: ['ssm:GetParameter'],
          resources: [`arn:aws:ssm:${this.region}:${this.account}:parameter/api-endpoint`],
        }),
      ]),
      timeout: cdk.Duration.minutes(5),
    });

    // 获取参数值,处理不存在的情况
    const apiEndpoint = ssmLookupResource.getResponseField('Parameter.Value').toString() || 'default-value';

    // 将参数传递给CodeBuild项目
    new codebuild.Project(this, 'YourBuildProject', {
      // ...其他配置
      environmentVariables: {
        API_ENDPOINT: { value: apiEndpoint },
      },
    });
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:06:00