Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ecr-assets): Support cache-from and cache-to flags #24024

Merged
merged 13 commits into from Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-ecr-assets/README.md
Expand Up @@ -121,6 +121,18 @@ const asset = new DockerImageAsset(this, 'MyBuildImage', {
})
```

You can optionally pass cache from and cache to options to cache images:

```ts
import { DockerImageAsset, Platform } from '@aws-cdk/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
directory: path.join(__dirname, 'my-image'),
cacheFrom: [{ type: 'registry', params: { ref: 'ghcr.io/myorg/myimage:cache' }}],
cacheTo: { type: 'registry', params: { ref: 'ghcr.io/myorg/myimage:cache', mode: 'max', compression: 'zstd' }}
})
```

## Images from Tarball

Images are loaded from a local tarball, uploaded to ECR by the CDK toolkit and/or your app's CI-CD pipeline, and can be
Expand Down
54 changes: 54 additions & 0 deletions packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts
Expand Up @@ -148,6 +148,28 @@ export interface DockerImageAssetInvalidationOptions {
readonly outputs?: boolean;
}

/**
* Options for configuring the Docker cache backend
*/
export interface DockerCacheOption {
/**
* The type of cache to use.
* Refer to https://docs.docker.com/build/cache/backends/ for full list of backends.
* @default - unspecified
*
* @example 'registry'
*/
readonly type: string;
/**
* Any parameters to pass into the docker cache backend configuration.
* Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration.
* @default {} No options provided
*
* @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" }
*/
readonly params?: { [key: string]: string };
}

/**
* Options for DockerImageAsset
*/
Expand Down Expand Up @@ -236,6 +258,22 @@ export interface DockerImageAssetOptions extends FingerprintOptions, FileFingerp
* @see https://docs.docker.com/engine/reference/commandline/build/#custom-build-outputs
*/
readonly outputs?: string[];

/**
* Cache from options to pass to the `docker build` command.
*
* @default - no cache from options are passed to the build command
* @see https://docs.docker.com/build/cache/backends/
*/
readonly cacheFrom?: DockerCacheOption[];

/**
* Cache to options to pass to the `docker build` command.
*
* @default - no cache to options are passed to the build command
* @see https://docs.docker.com/build/cache/backends/
*/
readonly cacheTo?: DockerCacheOption;
}

/**
Expand Down Expand Up @@ -316,6 +354,16 @@ export class DockerImageAsset extends Construct implements IAsset {
*/
private readonly dockerOutputs?: string[];

/**
* Cache from options to pass to the `docker build` command.
*/
private readonly dockerCacheFrom?: DockerCacheOption[];

/**
* Cache to options to pass to the `docker build` command.
*/
private readonly dockerCacheTo?: DockerCacheOption;

/**
* Docker target to build to
*/
Expand Down Expand Up @@ -407,6 +455,8 @@ export class DockerImageAsset extends Construct implements IAsset {
this.dockerBuildSecrets = props.buildSecrets;
this.dockerBuildTarget = props.target;
this.dockerOutputs = props.outputs;
this.dockerCacheFrom = props.cacheFrom;
this.dockerCacheTo = props.cacheTo;

const location = stack.synthesizer.addDockerImageAsset({
directoryName: this.assetPath,
Expand All @@ -418,6 +468,8 @@ export class DockerImageAsset extends Construct implements IAsset {
networkMode: props.networkMode?.mode,
platform: props.platform?.platform,
dockerOutputs: this.dockerOutputs,
dockerCacheFrom: this.dockerCacheFrom,
dockerCacheTo: this.dockerCacheTo,
});

this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName);
Expand Down Expand Up @@ -456,6 +508,8 @@ export class DockerImageAsset extends Construct implements IAsset {
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_BUILD_TARGET_KEY] = this.dockerBuildTarget;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY] = resourceProperty;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_OUTPUTS_KEY] = this.dockerOutputs;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_CACHE_FROM_KEY] = this.dockerCacheFrom;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_CACHE_TO_KEY] = this.dockerCacheTo;
}

}
Expand Down
Expand Up @@ -81,6 +81,11 @@
"Value": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:60dea2e16e94d1977b92fe03fa7085fea446233f1fe499702b69593438baa59f"
}
},
"ImageUri6": {
"Value": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:0a3355be12051c9984bf2b0b2bba4e6ea535968e5b6e7396449701732fe5ed14"
}
}
},
"Parameters": {
Expand Down
Expand Up @@ -262,8 +262,8 @@
"version": "0.0.0"
}
},
"ImageUri5": {
"id": "ImageUri5",
"ImageUri4": {
"id": "ImageUri4",
"path": "integ-assets-docker/ImageUri5",
"constructInfo": {
"fqn": "@aws-cdk/core.CfnOutput",
Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-ecr-assets/test/integ.assets-docker.ts
Expand Up @@ -31,17 +31,24 @@ const asset5 = new assets.DockerImageAsset(stack, 'DockerImage5', {
},
});

const asset6 = new assets.DockerImageAsset(stack, 'DockerImage6', {
directory: path.join(__dirname, 'demo-image'),
cacheTo: { type: 'inline' },
});

const user = new iam.User(stack, 'MyUser');
asset.repository.grantPull(user);
asset2.repository.grantPull(user);
asset3.repository.grantPull(user);
asset4.repository.grantPull(user);
asset5.repository.grantPull(user);
asset6.repository.grantPull(user);

new cdk.CfnOutput(stack, 'ImageUri', { value: asset.imageUri });
new cdk.CfnOutput(stack, 'ImageUri2', { value: asset2.imageUri });
new cdk.CfnOutput(stack, 'ImageUri3', { value: asset3.imageUri });
new cdk.CfnOutput(stack, 'ImageUri4', { value: asset4.imageUri });
new cdk.CfnOutput(stack, 'ImageUri5', { value: asset5.imageUri });
new cdk.CfnOutput(stack, 'ImageUri6', { value: asset6.imageUri });

app.synth();
Expand Up @@ -97,6 +97,22 @@ export interface DockerImageSource {
* @see https://docs.docker.com/engine/reference/commandline/build/#custom-build-outputs
*/
readonly dockerOutputs?: string[];

/**
* Cache from options to pass to the `docker build` command.
*
* @default - no cache from options are passed to the build command
* @see https://docs.docker.com/build/cache/backends/
*/
readonly cacheFrom?: DockerCacheOption[];

/**
* Cache to options to pass to the `docker build` command.
*
* @default - no cache to options are passed to the build command
* @see https://docs.docker.com/build/cache/backends/
*/
readonly cacheTo?: DockerCacheOption;
}

/**
Expand All @@ -113,3 +129,25 @@ export interface DockerImageDestination extends AwsDestination {
*/
readonly imageTag: string;
}

/**
* Options for configuring the Docker cache backend
*/
export interface DockerCacheOption {
/**
* The type of cache to use.
* Refer to https://docs.docker.com/build/cache/backends/ for full list of backends.
* @default - unspecified
*
* @example 'registry'
*/
readonly type: string;
/**
* Any parameters to pass into the docker cache backend configuration.
* Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration.
* @default {} No options provided
*
* @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" }
*/
readonly params?: { [key: string]: string };
}
Expand Up @@ -71,6 +71,28 @@ export interface Tag {
readonly value: string
}

/**
* Options for configuring the Docker cache backend
*/
export interface ContainerImageAssetCacheOption {
/**
* The type of cache to use.
* Refer to https://docs.docker.com/build/cache/backends/ for full list of backends.
* @default - unspecified
*
* @example 'registry'
*/
readonly type: string;
/**
* Any parameters to pass into the docker cache backend configuration.
* Refer to https://docs.docker.com/build/cache/backends/ for cache backend configuration.
* @default {} No options provided
*
* @example { ref: `12345678.dkr.ecr.us-west-2.amazonaws.com/cache:${branch}`, mode: "max" }
*/
readonly params?: { [key: string]: string };
}

/**
* Metadata Entry spec for container images.
*/
Expand Down Expand Up @@ -160,6 +182,22 @@ export interface ContainerImageAssetMetadataEntry extends BaseAssetMetadataEntry
* @see https://docs.docker.com/engine/reference/commandline/build/#custom-build-outputs
*/
readonly outputs?: string[];

/**
* Cache from options to pass to the `docker build` command.
*
* @default - no cache from options are passed to the build command
* @see https://docs.docker.com/build/cache/backends/
*/
readonly cacheFrom?: ContainerImageAssetCacheOption[];

/**
* Cache to options to pass to the `docker build` command.
*
* @default - no cache to options are passed to the build command
* @see https://docs.docker.com/build/cache/backends/
*/
readonly cacheTo?: ContainerImageAssetCacheOption;
}

/**
Expand Down
31 changes: 31 additions & 0 deletions packages/@aws-cdk/cloud-assembly-schema/schema/assets.schema.json
Expand Up @@ -176,9 +176,40 @@
"items": {
"type": "string"
}
},
"cacheFrom": {
"description": "Cache from options to pass to the `docker build` command. (Default - no cache from options are passed to the build command)",
"type": "array",
"items": {
"$ref": "#/definitions/DockerCacheOption"
}
},
"cacheTo": {
"description": "Cache to options to pass to the `docker build` command. (Default - no cache to options are passed to the build command)",
"$ref": "#/definitions/DockerCacheOption"
}
}
},
"DockerCacheOption": {
"description": "Options for configuring the Docker cache backend",
"type": "object",
"properties": {
"type": {
"description": "The type of cache to use.\nRefer to https://docs.docker.com/build/cache/backends/ for full list of backends. (Default - unspecified)",
"type": "string"
},
"params": {
"description": "Any parameters to pass into the docker cache backend configuration.\nRefer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. (Default {} No options provided)",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": [
"type"
]
},
"DockerImageDestination": {
"description": "Where to publish docker images",
"type": "object",
Expand Down
Expand Up @@ -248,6 +248,17 @@
"type": "string"
}
},
"cacheFrom": {
"description": "Cache from options to pass to the `docker build` command. (Default - no cache from options are passed to the build command)",
"type": "array",
"items": {
"$ref": "#/definitions/ContainerImageAssetCacheOption"
}
},
"cacheTo": {
"description": "Cache to options to pass to the `docker build` command. (Default - no cache to options are passed to the build command)",
"$ref": "#/definitions/ContainerImageAssetCacheOption"
},
"id": {
"description": "Logical identifier for the asset",
"type": "string"
Expand All @@ -268,6 +279,26 @@
"sourceHash"
]
},
"ContainerImageAssetCacheOption": {
"description": "Options for configuring the Docker cache backend",
"type": "object",
"properties": {
"type": {
"description": "The type of cache to use.\nRefer to https://docs.docker.com/build/cache/backends/ for full list of backends. (Default - unspecified)",
"type": "string"
},
"params": {
"description": "Any parameters to pass into the docker cache backend configuration.\nRefer to https://docs.docker.com/build/cache/backends/ for cache backend configuration. (Default {} No options provided)",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": [
"type"
]
},
"Tag": {
"description": "Metadata Entry spec for stack tag.",
"type": "object",
Expand Down
@@ -1,3 +1 @@
{
"version": "30.1.0"
}
{"version":"31.0.0"}