AWS CDK - DockerImageAsset - 如何在下游图像中使用已发布的 ECR 图像?

AWS CDK - DockerImageAsset - How to use published ECR image in a downstream image?

我们目前拥有下游容器从中提取的“基础映像”,我们正在使用 aws-cdk-lib/aws-ecr-assets 从定制 CDK 管道升级到简单的 CDK 管道。我们一直通过使用 SSM 共享这些基础图像的 URI 来做到这一点,因为它们位于不同的项目和堆栈中。

我一直在尝试通过将 SSM 导入下游堆栈并将 URI 作为 Buildarg 传递来执行此操作,但我 运行 进入“无法在“buildArgs”的键或值中使用标记”因为在部署之前需要它们”,根据问题 #3981 是预期的。

这让我觉得我做错了,但我不确定实现这一目标的最佳做法是什么?我正在通过对存储在 SSM 中的 URL 进行硬编码来解决这个问题,显然我可以预取它并在运行时传递它,但这看起来很笨重。

我试图实现的架构是这样的:

上游堆栈:

const pythonDocker = new DockerImageAsset(this, 'python-3-base-image', {
    directory: join(thisDirectoryInSrc, '/python-3'),
    ignoreMode: IgnoreMode.DOCKER,
});

new StringParameter(this, 'python3-ecr-arn-ssm', {
    stringValue: pythonDocker.imageUri,
    description: 'Python 3 image repository URI',
    parameterName: '/docker-images/python-3/image-uri',
});

下游堆栈:

const baseImage = StringParameter.fromStringParameterName(this, 'python-3-base-image', '/docker-images/python-3/image-uri');

const feedReaderDocker = ContainerImage.fromAsset('src/feed-reader', {
    ignoreMode: IgnoreMode.DOCKER,
    buildArgs: {
        BASE_IMAGE: baseImage.stringValue
    },
});

下游 Dockerfile:

ARG BASE_IMAGE
FROM BASE_IMAGE

# Install dependencies, declare entry point, etc

TL;DR 使用上下文。 StringParameter.valueFromLookup“上下文方法”可以在synth-time.

检索和缓存先前部署的参数值

如您所见,StringParameter.fromStringParameterName 解析为 deploy-time。但是 ContainerImage.fromAsset 需要在 synth-time 处解析的基本图像值。 CDK 为我们提供了此用例的 Runtime Context

The AWS CDK supports several context methods that enable AWS CDK apps to obtain contextual information from the AWS environment... If a required context value isn't available, the AWS CDK app notifies the CDK Toolkit that the context information is missing. The CLI then queries the current AWS account for the information, stores the resulting context information in the cdk.context.json file

StringParameter.valueFromLookup 就是这样一种“上下文方法”。下面是一个比较两种方法的 synth-time 值的示例:

const paramName = '/cdk-bootstrap/hnb659fds/version';
const fromName: ssm.IStringParameter = ssm.StringParameter.fromStringParameterName(this, 'FromName', paramName);
const fromLookup: string = ssm.StringParameter.valueFromLookup(this, paramName);

console.dir({ fromName: fromName.stringValue, fromLookup });

// -> { fromName: '${Token[TOKEN.196]}', fromLookup: '12' }

valueFromLookup 通过 SDK 调用获取一次值并将其缓存在 cdk.context.json 中。 CDK 建议您提交此文件以遵守 deterministic deploy best practice.