如何使用 AWS CDK 从两个不同账户获取 SSM 参数

Ped*_*iro 8 ssm aws-cdk

我有一个场景,我使用 CodePipeline 将我的 cdk 项目从一个工具帐户部署到多个环境帐户。我的管道部署方式是cdk deploy从 CodeBuild 作业中运行。

我的团队决定使用 SSM 参数存储来存储配置,最终我们在环境帐户中获得了一些参数,例如resources/vpc/id我可以在部署时间 => 中读取的 VPC_ID ( ) ssm.StringParameter.valueForStringParameter

但是,其他参数位于工具帐户中,例如我的环境帐户 ( environment/nonprod/account/id) 中的帐户 ID 和其他全局配置。我在获取这些值时遇到问题。

目前,我能想到的唯一方法是使用一个步骤来读取上一步中的所有这些值并将它们加载到上下文值中。

对于这个问题有更优雅的方法吗?我希望我可以指定从哪个帐户获取 SSM 值。有任何想法吗?

谢谢。

Joh*_*ohn 1

作为管道的一部分,我将添加一个执行 Lambda 的初步步骤。然后,Lambda 可以执行您希望获取所需元数据/配置的任何查询。然后,可以将该 Lambda 的输出传递到 CodeBuild 步骤。

例如在 Lambda 中:

export class ConfigFetcher {

  codepipeline = new AWS.CodePipeline();

  async fetchConfig(event: CodePipelineEvent, context : Context) : Promise<void> {

    // Retrieve the Job ID from the Lambda action
    const jobId = event['CodePipeline.job'].id;

    // now get your config by executing whatever queries you need, even cross-account, via the SDK
    // we assume that the answer is in the variable someValue
    const params = {
      jobId: jobId,
      outputVariables: {
        MY_CONFIG: someValue,
      },
    };
    // now tell CodePipeline you're done
    await this.codepipeline.putJobSuccessResult(params).promise().catch(err => {
      console.error('Error reporting build success to CodePipeline: ' + err);
      throw err;
    });
 
    // make sure you have some sort of catch wrapping the above to post a failure to CodePipeline
// ...
  }
}

const configFetcher = new ConfigFetcher();

exports.handler = async function fetchConfigMetadata(event: CodePipelineEvent, context : Context): Promise<void> {
  return configFetcher.fetchConfig(event, context);
};
Run Code Online (Sandbox Code Playgroud)

假设您使用 CDK 创建管道,那么您的 Lambda 步骤将使用如下内容创建:

const fetcherAction = new LambdaInvokeAction({
  actionName: 'FetchConfigMetadata',
  lambda: configFetcher,
  variablesNamespace: 'ConfigMetadata',
});
Run Code Online (Sandbox Code Playgroud)

请注意 的使用variablesNamespace:我们稍后需要引用它,以便从 Lambda 的输出中检索值并将它们作为环境变量插入到 CodeBuild 环境中。

现在我们的 CodeBuild 定义,再次假设我们使用 CDK 创建:

new CodeBuildAction({
  // ...
  environmentVariables: {
    MY_CONFIG: {
      type: BuildEnvironmentVariableType.PLAINTEXT,
      value: '#{ConfigMetadata.MY_CONFIG}',
    },
  },
Run Code Online (Sandbox Code Playgroud)

我们可以在 CodeBuild 中随意调用该变量,但请注意,该变量ConfigMetadata.MY_CONFIG需要与 Lambda 的命名空间和输出值相匹配。

您可以让您的 lambda 执行任何您想要检索所需数据的操作 - 只需要为其授予适当的权限即可在需要时访问其他 AWS 账户,您可以使用角色假设来完成此操作。使用 Lambda 作为管道步骤将比在管道中使用 CodeBuild 步骤快得多,而且更容易更改:如果您使用 Typescript/JS 或 Python 编写 Lambda 代码,您甚至可以使用 AWS 控制台执行以下操作: - 在测试它是否正确执行时进行编辑。