如何通过CDK TypeScript跨AWS账号部署Lambda函数:使用其他账号的ECR镜像
如何通过CDK TypeScript跨AWS账号部署Lambda函数:使用其他账号的ECR镜像
嘿,我来一步步拆解怎么实现这个需求——用CDK TypeScript把Lambda函数部署到一个AWS账号,同时拉取另一个账号ECR仓库里的镜像。整个流程分两大块:先给ECR所在的账号配置权限,再在部署Lambda的账号里写CDK代码引用镜像。
一、在ECR镜像所在的账号(简称账号A)配置权限
首先得让目标部署账号(简称账号B)能拉取账号A里的ECR镜像,这一步要给ECR仓库加个权限策略,允许账号B的相关角色访问:
1. 用CDK给账号A的ECR仓库添加跨账号权限
如果你的ECR仓库也是用CDK管理的,直接在账号A的CDK栈里给仓库添加如下权限:
import * as ecr from 'aws-cdk-lib/aws-ecr'; import * as iam from 'aws-cdk-lib/aws-iam'; // 假设你已经有了ECR仓库的实例 const ecrRepo = ecr.Repository.fromRepositoryName(this, 'ExistingRepo', 'your-repo-name'); // 允许账号B拉取镜像的核心权限 ecrRepo.addToResourcePolicy(new iam.PolicyStatement({ actions: [ 'ecr:GetDownloadUrlForLayer', 'ecr:BatchGetImage', 'ecr:BatchCheckLayerAvailability' ], principals: [new iam.AccountPrincipal('账号B的AWS账号ID')], resources: [`${ecrRepo.repositoryArn}/*`], })); // 可选:允许账号B查看仓库信息,方便排查问题 ecrRepo.addToResourcePolicy(new iam.PolicyStatement({ actions: ['ecr:DescribeRepositories'], principals: [new iam.AccountPrincipal('账号B的AWS账号ID')], resources: [ecrRepo.repositoryArn], }));
2. 手动配置(如果ECR仓库是手动创建的)
要是你的ECR仓库不是CDK管的,直接去账号A的AWS控制台,找到对应ECR仓库,在「权限」标签页添加如下JSON策略:
{ "Version": "2008-10-17", "Statement": [ { "Sid": "AllowCrossAccountPull", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::账号B的账号ID:root" }, "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ] } ] }
二、在Lambda部署的账号(账号B)用CDK编写部署代码
接下来在账号B的CDK项目里,引用账号A的ECR镜像,然后创建Lambda函数:
1. 引用账号A的ECR仓库
在账号B的CDK栈里,通过仓库ARN或者「名称+账号ID+区域」来引用跨账号的ECR仓库,两种方式选一种就行:
import * as ecr from 'aws-cdk-lib/aws-ecr'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as cdk from 'aws-cdk-lib'; export class LambdaCrossAccountStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 方式1:通过ARN引用(最准确) const crossAccountEcrRepo = ecr.Repository.fromRepositoryAttributes(this, 'CrossAccountRepo', { repositoryName: 'your-repo-name', repositoryArn: 'arn:aws:ecr:你的ECR区域:账号A的账号ID:repository/your-repo-name', }); // 方式2:通过名称+账号+区域引用(更简洁) // const crossAccountEcrRepo = ecr.Repository.fromRepositoryName(this, 'CrossAccountRepo', 'your-repo-name', { // repositoryAccount: '账号A的账号ID', // region: '你的ECR区域' // });
2. 用跨账号镜像创建Lambda函数
现在就可以用这个跨账号的ECR镜像来定义Lambda函数了,记得替换成你实际使用的镜像tag:
// 创建Lambda函数,使用账号A的ECR镜像 const crossAccountLambda = new lambda.DockerImageFunction(this, 'CrossAccountLambda', { functionName: 'CrossAccountLambdaDemo', code: lambda.DockerImageCode.fromEcr(crossAccountEcrRepo, { tag: 'latest', // 换成你要使用的镜像版本tag }), // 按需配置Lambda的其他参数 memorySize: 512, timeout: cdk.Duration.seconds(30), }); } }
3. 配置CDK的部署环境
最后要确保CDK能正确访问账号B,在bin目录的主文件(比如你提供的ApisecDataScienceInfra.ts)里指定账号B的环境信息:
import "source-map-support/register"; import * as cdk from "aws-cdk-lib"; import { LambdaCrossAccountStack } from "../lib/lambda-cross-account-stack"; const app = new cdk.App(); new LambdaCrossAccountStack(app, 'LambdaCrossAccountStack', { env: { account: '账号B的账号ID', region: '你要部署Lambda的区域' } });
三、几个关键注意事项
- 权限排查:如果遇到拉取镜像失败的错误,先去账号A的ECR仓库检查权限策略是否生效,再确认本地AWS凭证是对应账号B的。
- 区域匹配:如果ECR仓库和Lambda不在同一个AWS区域,镜像拉取速度会变慢,建议尽量同区域部署。
- 执行角色:不需要给账号B的Lambda执行角色额外加ECR权限,因为我们已经在账号A的ECR仓库里授权了整个账号B,只要执行角色属于账号B就自动有权限。
备注:内容来源于stack exchange,提问作者devops-admin
相关产品推荐
相关产品推荐

