[英]How to fetch SSM Parameters from two different accounts using AWS CDK
我有一个场景,我正在使用 CodePipeline 将我的 cdk 项目从一个工具帐户部署到多个环境帐户。 我的管道部署方式是从 CodeBuild 作业中运行cdk deploy
。
我的团队决定使用 SSM Parameter Store 来存储配置,我们最终在环境帐户中找到了一些参数,例如我可以在部署时读取的 VPC_ID ( resources/vpc/id
) => ssm.StringParameter.valueForStringParameter
.
但是,其他参数存在于工具帐户中,例如来自我的环境帐户 ( environment/nonprod/account/id
) 和其他全局配置的帐户 ID。 我无法获取这些值。
目前,我能想到的唯一方法是使用一个步骤来读取上一步中的所有这些值并将它们加载到上下文值中。
这个问题有更优雅的方法吗? 我希望我可以指定从哪个帐户获取 SSM 值。 有任何想法吗?
谢谢你。
正如您已经说过的那样,没有本地支持。 我还在跨账户部署中使用 CodePipeline,因此所有自动化参数或产品指定参数都存储在安全账户中,CodePipeline 使用 CloudFormation 作为操作提供者部署资源。
不支持 SSM 参数的跨账户解析,所以最后,我在我的 CodePipeline 中添加了一个额外的步骤(阶段),这不过是一个 CodeBuild 项目,它在容器化环境中运行脚本,然后脚本“同步”参数从自动化账户到目标账户。
AFAIK 没有本地方法可以实现您所描述的内容。 如果有办法我也想知道。 我相信您可以为此目的使用 lambda 烘焙的 CloudFormation 自定义资源。
您可以将参数传递给 lambda 请求并从 lambda 响应中获取信息。
见https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html , https://www.2ndwatch.com/blog/a-step-by-step-guide -on-using-aws-lambda-backed-custom-resources-with-amazon-cfts/和https://docs.aws.amazon.com/cdk/api/latest/docs/custom-resources-readme.html更多信息。
作为管道的一部分,我会添加一个初步步骤来执行 Lambda。然后 Lambda 可以执行您希望获取所需的任何元数据/配置的任何查询。 然后可以将 Lambda 中的 output 传递到 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);
};
假设您使用 CDK 创建管道,那么您的 Lambda 步骤将使用如下内容创建:
const fetcherAction = new LambdaInvokeAction({
actionName: 'FetchConfigMetadata',
lambda: configFetcher,
variablesNamespace: 'ConfigMetadata',
});
请注意variablesNamespace
的使用:我们稍后需要引用它,以便从 Lambda 的 output 中检索值并将它们作为 env 变量插入到 CodeBuild 环境中。
现在我们的 CodeBuild 定义,再次假设我们使用 CDK 创建:
new CodeBuildAction({
// ...
environmentVariables: {
MY_CONFIG: {
type: BuildEnvironmentVariableType.PLAINTEXT,
value: '#{ConfigMetadata.MY_CONFIG}',
},
},
我们可以在 CodeBuild 中随意调用该变量,但请注意ConfigMetadata.MY_CONFIG
需要匹配命名空间和 Lambda 的 output 值。
你可以让你的 lambda 做任何你想做的事情来检索它需要的任何数据——如果需要的话,它只需要被授予适当的权限才能访问其他 AWS 账户,你可以使用角色承担来做到这一点。 使用 Lambda 作为管道步骤比在管道中使用 CodeBuild 步骤快很多,而且更容易更改:如果您在 Typescript/JS 或 Python 中编写 Lambda 代码,您甚至可以使用 AWS 控制台在- 在您测试它是否正确执行时进行编辑。
这个问题已经存在一年了,但我发现一个更简单的从您的工具/部署帐户中检索参数的方法是在您的构建规范文件中将它们指定为环境变量。 CodeBuild 将始终从您的作业运行的任何帐户中提取这些信息(在这个问题的场景中是工具帐户)。
要从目标环境帐户中提取参数,最好使用问题作者建议的CDK SSM 方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.