[英]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.