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

在CDK的CodePipeline阶段配置Docker构建密钥的问题

解决CDK CodePipeline中DockerImageAsset访问私有Git依赖的问题

在CodePipeline构建流程中,Docker镜像构建需要通过poetry install拉取私有GitHub仓库的依赖。本地通过docker build --secret注入私钥可以正常构建,但在CDK配置时,无法让DockerImageAsset访问前置ShellStep生成的私钥文件,导致构建失败。

核心思路

DockerImageAsset默认使用源码目录作为构建上下文,无法直接访问Pipeline中ShellStep生成的临时文件。需要通过Pipeline Workspace实现步骤间的文件共享,将私钥写入共享Workspace后,让DockerImageAsset将该Workspace纳入构建上下文,再在Dockerfile中引用密钥。

具体实现步骤

1. 创建共享Pipeline Workspace

在Pipeline中定义一个共享的Workspace,用于存放私钥文件:

from aws_cdk import (
    pipelines,
    aws_codebuild as codebuild,
    aws_secretsmanager as secretsmanager,
    aws_ecr_assets as ecr_assets,
)

# 创建共享工作空间
secret_workspace = pipelines.Workspace(name="git-secret-workspace")

2. 编写ShellStep获取私钥并写入Workspace

添加前置ShellStep,从Secrets Manager拉取私钥,写入Workspace的文件中,并设置正确的文件权限(Git要求私钥权限为600):

# 从Secrets Manager获取私钥的ShellStep
fetch_secret_step = pipelines.ShellStep(
    "FetchGitPrivateKey",
    commands=[
        # 获取私钥并写入临时文件
        'aws secretsmanager get-secret-value --secret-id "github-private-key" --query SecretString --output text > /tmp/git_private_key',
        # 复制到共享工作空间并设置权限
        'cp /tmp/git_private_key $CODEBUILD_SRC_DIR_git-secret-workspace/id_rsa',
        'chmod 600 $CODEBUILD_SRC_DIR_git-secret-workspace/id_rsa'
    ],
    # 授予CodeBuild角色读取Secrets Manager的权限
    role_policy_statements=[
        secretsmanager.Secret.from_secret_name_v2(self, "GitSecret", "github-private-key").grant_read()
    ],
    # 指定使用的共享工作空间
    additional_workspaces=[secret_workspace]
)

3. 修改Dockerfile以使用共享的私钥

更新Dockerfile,在poetry install前通过--secret引用共享Workspace中的私钥文件:

FROM python:3.11-slim

WORKDIR /app

# 复制依赖配置文件
COPY pyproject.toml poetry.lock ./

# 构建时注入私钥,拉取私有Git依赖
RUN --mount=type=secret,id=git_private_key,target=/root/.ssh/id_rsa \
    chmod 600 /root/.ssh/id_rsa && \
    ssh-keyscan github.com >> /root/.ssh/known_hosts && \
    poetry install --no-root --no-dev && \
    rm /root/.ssh/id_rsa

# 复制应用代码
COPY . .

CMD ["python", "app.py"]

4. 配置DockerImageAsset引用共享Workspace

创建DockerImageAsset时,将共享Workspace添加到构建上下文,并通过CodeBuild的Secret机制引用私钥:

# 创建Docker镜像资产
docker_asset = ecr_assets.DockerImageAsset(
    self, "AppImage",
    directory="./app",  # 主源码目录
    extra_hash=secret_workspace.path,  # 私钥变化时触发镜像重构
    # 关联共享工作空间中的私钥文件
    build_secrets={
        "git_private_key": codebuild.Secret.from_file_in_workspace("git-secret-workspace", "id_rsa")
    }
)

5. 在Pipeline中编排步骤依赖

确保Docker镜像构建步骤依赖于私钥获取步骤,保证私钥文件已生成:

# 创建Pipeline
pipeline = pipelines.CodePipeline(
    self, "MyPipeline",
    synth=pipelines.ShellStep("Synth",
        input=pipelines.CodePipelineSource.git_hub("your/repo", "main"),
        commands=["npm ci", "npm run synth"]
    )
)

# 添加镜像构建阶段
build_stage = pipelines.Stage(self, "BuildImageStage")
build_stage.add_post(
    pipelines.CodeBuildStep(
        "BuildDockerImage",
        commands=[
            f'docker build --secret id=git_private_key,src={secret_workspace.path}/id_rsa -t {docker_asset.image_uri} ./app',
            f'docker push {docker_asset.image_uri}'
        ],
        additional_workspaces=[secret_workspace],
        # 授予推送镜像到ECR的权限
        role_policy_statements=[
            docker_asset.repository.grant_push()
        ]
    )
)

# 设置阶段依赖,确保先获取私钥再构建镜像
pipeline.add_stage(build_stage, pre=[fetch_secret_step])

关键注意事项

  • 权限配置:确保CodePipeline和CodeBuild的执行角色拥有Secrets Manager读取权限、ECR推送权限。
  • 私钥权限:必须将私钥文件权限设置为600,否则Git会拒绝使用该密钥。
  • Workspace关联:通过additional_workspaces将共享Workspace传递给需要的步骤,确保文件可访问。
  • 重构触发:使用extra_hash关联Workspace内容,私钥更新时自动触发镜像重构。

内容的提问来源于stack exchange,提问作者Jaygee Lastname

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:06:03