AWS CDK v2跨账号环境下通过CodePipeline调用Lambda的.NET示例
AWS CDK v2 .NET 实现多账号CodePipeline调用Lambda失效CloudFront
核心逻辑
由于是DevOps账号与资源部署账号分离的多账号环境,需要先确保目标账号(部署CloudFront、Lambda、S3的账号)给DevOps账号的CodePipeline授权,再在DevOps账号的CDK中构建包含部署后调用Lambda步骤的流水线。
代码实现
1. 目标账号的Lambda权限补配(若未配置)
如果目标账号的Lambda还未开放给DevOps账号调用,需在目标账号的CDK中添加以下权限配置:
// 目标账号内为Lambda添加跨账号调用权限 var lambdaInvokePermission = new CfnPermission(this, "LambdaInvokeFromDevOps", new CfnPermissionProps { Action = "lambda:InvokeFunction", FunctionName = existingInvalidationLambda.FunctionArn, // 替换为你的Lambda ARN Principal = "codepipeline.amazonaws.com", SourceAccount = "DevOps账号ID", // 填入你的DevOps账号ID SourceArn = $"arn:aws:codepipeline:{Region}:{DevOps账号ID}:*" });
2. DevOps账号的CodePipeline完整配置
在DevOps账号的CDK项目中,构建包含部署阶段和Lambda调用阶段的流水线:
using Amazon.CDK; using Amazon.CDK.AWS.CodePipeline; using Amazon.CDK.AWS.CodePipeline.Actions; using Amazon.CDK.AWS.IAM; using Amazon.CDK.AWS.Lambda; using Constructs; namespace DevOpsPipelineStack { public class CloudFrontDeploymentPipeline : Stack { public CloudFrontDeploymentPipeline(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // 1. 创建CodePipeline专属角色,添加跨账号调用Lambda的权限 var pipelineRole = new Role(this, "CodePipelineExecutionRole", new RoleProps { AssumedBy = new ServicePrincipal("codepipeline.amazonaws.com"), ManagedPolicies = new[] { ManagedPolicy.FromAwsManagedPolicyName("AWSCodePipelineFullAccess"), new ManagedPolicy(this, "InvokeTargetLambdaPolicy", new ManagedPolicyProps { Statements = new[] { new PolicyStatement(new PolicyStatementProps { Actions = new[] {"lambda:InvokeFunction"}, Resources = new[] {"arn:aws:lambda:目标账号区域:目标账号ID:function:你的Lambda函数名"} }) } }) } }); // 2. 初始化CodePipeline var pipeline = new Pipeline(this, "CloudFrontInvalidationPipeline", new PipelineProps { Role = pipelineRole, PipelineName = "CloudFront-Deployment-Invalidation-Pipeline" }); // 3. 源阶段(示例:GitHub源码,可替换为CodeCommit等) var sourceArtifact = new Artifact(); pipeline.AddStage(new StageOptions { StageName = "Source", Actions = new[] { new GitHubSourceAction(new GitHubSourceActionProps { ActionName = "Pull_Source_Code", Owner = "你的GitHub用户名", Repo = "你的仓库名", Branch = "main", OauthToken = SecretValue.SecretsManager("github-access-token"), Output = sourceArtifact }) } }); // 4. 部署阶段(示例:部署静态资源到S3,根据实际部署逻辑调整) pipeline.AddStage(new StageOptions { StageName = "Deploy_Assets", Actions = new[] { new S3DeployAction(new S3DeployActionProps { ActionName = "Deploy_To_S3", Bucket = Bucket.FromBucketArn(this, "TargetStaticBucket", "arn:aws:s3:::你的目标存储桶名"), Input = sourceArtifact }) } }); // 5. CloudFront失效阶段:调用目标账号的Lambda pipeline.AddStage(new StageOptions { StageName = "Invalidate_CloudFront", Actions = new[] { new LambdaInvokeAction(new LambdaInvokeActionProps { ActionName = "Run_Invalidation_Lambda", Lambda = LambdaFunction.FromFunctionArn(this, "TargetInvalidationLambda", "arn:aws:lambda:目标账号区域:目标账号ID:function:你的Lambda函数名"), // 向Lambda传递参数(比如CloudFront分发ID) UserParameters = new Dictionary<string, object> { {"DistributionId", "你的CloudFront分发ID"} }, ResultPath = "$.LambdaExecutionResult" }) } }); } } public class Program { public static void Main(string[] args) { var app = new App(); new CloudFrontDeploymentPipeline(app, "DevOpsCloudFrontPipelineStack", new StackProps { Env = new Amazon.CDK.Environment { Account = "DevOps账号ID", Region = "DevOps账号所属区域" } }); app.Synth(); } } }
关键注意事项
- 跨账号权限互信:必须确保目标账号的Lambda权限策略允许DevOps账号的CodePipeline调用,同时DevOps账号的CodePipeline角色拥有调用目标Lambda的权限
- 参数传递:Lambda需要的参数(如CloudFront分发ID)可通过
UserParameters传递,Lambda内部可从CodePipeline的事件 payload 中解析这些参数 - 区域一致性:注意CodePipeline与目标Lambda的区域匹配,若Lambda在其他区域,需在ARN和权限配置中指定对应区域
内容的提问来源于stack exchange,提问作者dx4100
相关产品推荐
相关产品推荐

