You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CDK打包Java Lambda函数时跨账号访问CodeArtifact?

跨AWS账号CodeArtifact访问解决方案

问题根源

CDK打包Lambda时,容器环境默认没有AWS凭证,导致无法调用aws codeartifact get-authorization-token命令获取权限,进而无法拉取账号A的commons包。以下是三种可行的解决方法:


方法1:容器内通过STS AssumeRole获取临时凭证(推荐开发/测试环境)

步骤1:更新账号A的角色信任策略

修改账号A的CDK代码,允许账号B的实体Assume此角色:

const codeArtifactAccessRole = new Role(this, "CodeArtifactAccessRole", {
  assumedBy: new CompositePrincipal(
    new ServicePrincipal("codebuild.amazonaws.com"),
    new AccountPrincipal("账号B的AWS账号ID") // 新增:允许账号B的主体Assume该角色
  ),
});

部署账号A的Stack以生效。

步骤2:修改账号B的Lambda打包命令

在打包容器内先Assume账号A的角色,获取临时凭证后再执行CodeArtifact和Maven命令:

command: [
  // 安装jq用于解析STS返回的JSON(Java 11镜像默认无jq)
  "apk add --no-cache jq && " +
  // Assume账号A的角色并保存凭证
  "aws sts assume-role --role-arn 账号A的CodeArtifactAccessRoleArn --role-session-name codeartifact-bundling --query 'Credentials' --output json > /tmp/creds.json " +
  // 导出临时凭证环境变量
  "&& export AWS_ACCESS_KEY_ID=$(jq -r '.AccessKeyId' /tmp/creds.json) " +
  "&& export AWS_SECRET_ACCESS_KEY=$(jq -r '.SecretAccessKey' /tmp/creds.json) " +
  "&& export AWS_SESSION_TOKEN=$(jq -r '.SessionToken' /tmp/creds.json) " +
  // 获取CodeArtifact令牌
  "&& export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain domain --domain-owner 账号A的账号ID --region 区域 --query authorizationToken --output text` " +
  // 执行Maven打包
  "&& mvn -s .mvn/settings.xml clean install " +
  "&& cp target/custom-email-sender-1.0.jar /asset-output/",
]

同时确保账号B中执行CDK的用户/角色拥有sts:AssumeRole权限,允许访问账号A的CodeArtifactAccessRole。


方法2:使用CodeBuild完成Lambda打包(适合CI/CD生产环境)

利用账号A已配置的CodeBuild信任角色,将打包逻辑转移到CodeBuild中,避免本地凭证问题:

步骤1:在账号B的CDK中定义CodeBuild项目

import * as codebuild from 'aws-cdk-lib/aws-codebuild';

// 创建CodeBuild项目,负责打包Lambda代码
const buildProject = new codebuild.Project(this, "LambdaBuildProject", {
  environment: {
    buildImage: codebuild.LinuxBuildImage.fromDockerRegistry("maven:3.8-openjdk-11"),
  },
  source: codebuild.Source.fromAsset(path.join(__dirname, "..", "..", "functions/custom-email-sender")),
  // 定义CodeBuild角色,允许Assume账号A的角色
  role: new Role(this, "CodeBuildRole", {
    assumedBy: new ServicePrincipal("codebuild.amazonaws.com"),
    inlinePolicies: {
      AssumeCodeArtifactRole: new PolicyDocument({
        statements: [
          new PolicyStatement({
            actions: ["sts:AssumeRole"],
            resources: ["账号A的CodeArtifactAccessRoleArn"],
          }),
        ],
      }),
    },
  }),
  buildSpec: codebuild.BuildSpec.fromObject({
    version: "0.2",
    phases: {
      install: {
        commands: [
          "aws sts assume-role --role-arn 账号A的CodeArtifactAccessRoleArn --role-session-name codebuild-codeartifact --query 'Credentials' --output json > /tmp/creds.json",
          "export AWS_ACCESS_KEY_ID=$(jq -r '.AccessKeyId' /tmp/creds.json)",
          "export AWS_SECRET_ACCESS_KEY=$(jq -r '.SecretAccessKey' /tmp/creds.json)",
          "export AWS_SESSION_TOKEN=$(jq -r '.SessionToken' /tmp/creds.json)",
          "export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token --domain domain --domain-owner 账号A的账号ID --region 区域 --query authorizationToken --output text)",
        ],
      },
      build: {
        commands: ["mvn -s .mvn/settings.xml clean install"],
      },
    },
    artifacts: {
      files: ["target/custom-email-sender-1.0.jar"],
    },
  }),
});

// 获取CodeBuild打包产物
const buildOutput = buildProject.getArtifact("artifact");

// 基于CodeBuild产物创建Lambda函数
const customEmailSenderFunction = new Function(
  this,
  customEmailSenderFunctionName,
  {
    runtime: Runtime.JAVA_11,
    timeout: Duration.minutes(3),
    memorySize: 1024,
    handler: "com.example.entrypoint.CustomEmailSenderHandlerEntrypoint::handleRequest",
    code: Code.fromBucket(buildOutput.s3Bucket, buildOutput.s3ObjectKey),
    environment: {
      QUEUE_URL: emailQueue.queueUrl,
    },
    logRetention: RetentionDays.THREE_MONTHS,
  }
);

步骤2:更新账号A的角色信任策略

允许账号B的CodeBuild角色Assume:

const codeArtifactAccessRole = new Role(this, "CodeArtifactAccessRole", {
  assumedBy: new CompositePrincipal(
    new ServicePrincipal("codebuild.amazonaws.com"),
    new ArnPrincipal("账号B的CodeBuildRoleArn") // 新增:允许指定CodeBuild角色访问
  ),
});

方法3:本地打包传递凭证(仅开发环境临时使用)

将本地AWS凭证传递给打包容器,仅适合本地开发场景:

bundling: {
  // ...其他配置
  environment: {
    AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID || "",
    AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY || "",
    AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN || "",
  },
}

执行CDK前先在本地导出凭证:

export AWS_ACCESS_KEY_ID="你的本地AK"
export AWS_SECRET_ACCESS_KEY="你的本地SK"
npx cdk synth -- -v -o dist

此方法不适合CI/CD环境,存在凭证泄露风险。


关键注意事项

  1. 确保账号B的实体(用户/角色/CodeBuild角色)拥有sts:AssumeRole权限,允许访问账号A的CodeArtifactAccessRole。
  2. Maven的settings.xml需正确配置CodeArtifact仓库地址,使用获取到的endpoint和token。

内容的提问来源于stack exchange,提问作者Alexiz Hernandez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:54:57