From 7b3d3813124c6c1dfa912c4fbe20772c84a0ffc6 Mon Sep 17 00:00:00 2001
From: Jack Boynton <42498462+JackWBoynton@users.noreply.github.com>
Date: Fri, 4 Aug 2023 11:25:23 -0400
Subject: [PATCH] feat(core): support ssh build arg in DockerImageAsset
(#26356)
Adds support for the docker build --ssh flag for specifying ssh agent socket or ssh keys for ecr DockerImageAsset
----
*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
.../test/demo-image-ssh/Dockerfile | 10 ++
.../test/demo-image-ssh/index.py | 35 +++++
.../Dockerfile | 7 +
.../index.py | 35 +++++
.../integ.assets-docker.js.snapshot/cdk.out | 2 +-
.../integ-assets-docker.assets.json | 18 ++-
.../integ-assets-docker.template.json | 5 +
.../integ.json | 2 +-
.../manifest.json | 16 ++-
.../integ.assets-docker.js.snapshot/tree.json | 130 +++++++++++++-----
.../test/integ.assets-docker.ts | 7 +
packages/aws-cdk-lib/aws-ecr-assets/README.md | 2 +
.../aws-ecr-assets/lib/image-asset.ts | 26 ++++
.../aws-ecr-assets/test/image-asset.test.ts | 3 +-
.../lib/assets/docker-image-asset.ts | 11 +-
.../lib/cloud-assembly/metadata-schema.ts | 7 +
.../schema/assets.schema.json | 4 +
.../schema/cloud-assembly.schema.json | 4 +
packages/aws-cdk-lib/core/lib/assets.ts | 8 ++
packages/aws-cdk-lib/cx-api/lib/assets.ts | 1 +
packages/aws-cdk/lib/assets.ts | 1 +
packages/cdk-assets/lib/private/docker.ts | 2 +
22 files changed, 296 insertions(+), 40 deletions(-)
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/Dockerfile
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/index.py
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/Dockerfile
create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/index.py
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/Dockerfile b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/Dockerfile
new file mode 100644
index 0000000000000..1eed2e5bafea9
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/Dockerfile
@@ -0,0 +1,10 @@
+FROM public.ecr.aws/lambda/python:3.6
+RUN yum makecache fast
+RUN yum install -y openssh-clients
+RUN ssh-keygen -t rsa -b 2048 -f /root/.ssh/id_rsa -q -N ""
+RUN ssh-keygen -y -f /root/.ssh/id_rsa > /root/.ssh/id_rsa.pub
+RUN cat /root/.ssh/id_rsa.pub >> out.pub
+WORKDIR /app
+EXPOSE 8000
+ADD . /app
+CMD python3 index.py
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/index.py b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/index.py
new file mode 100644
index 0000000000000..b5f3849ed5299
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/demo-image-ssh/index.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+import os
+import sys
+import textwrap
+import http.server
+import socketserver
+
+PORT = 8000
+
+class Handler(http.server.SimpleHTTPRequestHandler):
+ def do_GET(self):
+ with open('/root/.ssh/id_rsa.pub', 'r') as file:
+ data = file.read()
+
+ self.send_response(200)
+ self.send_header('Content-Type', 'text/html')
+ self.end_headers()
+ self.wfile.write(textwrap.dedent(f'''\
+
+
It works
+
+ Hello from the integ test container
+ This container got built and started as part of the integ test.
+ Public key: {data}
+
+
+ ''').encode('utf-8'))
+
+def main():
+ httpd = http.server.HTTPServer(("", PORT), Handler)
+ print("serving at port", PORT)
+ httpd.serve_forever()
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/Dockerfile b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/Dockerfile
new file mode 100644
index 0000000000000..0071fd74d1cea
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/Dockerfile
@@ -0,0 +1,7 @@
+FROM public.ecr.aws/lambda/python:3.6
+RUN yum makecache fast
+RUN yum install -y openssh-clients
+RUN ssh-keygen -t rsa -b 2048 -f /root/.ssh/id_rsa -q -N ""
+RUN ssh-keygen -y -f /root/.ssh/id_rsa > /root/.ssh/id_rsa.pub
+WORKDIR /app
+CMD python3 index.py
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/index.py b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/index.py
new file mode 100644
index 0000000000000..b5f3849ed5299
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17/index.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+import os
+import sys
+import textwrap
+import http.server
+import socketserver
+
+PORT = 8000
+
+class Handler(http.server.SimpleHTTPRequestHandler):
+ def do_GET(self):
+ with open('/root/.ssh/id_rsa.pub', 'r') as file:
+ data = file.read()
+
+ self.send_response(200)
+ self.send_header('Content-Type', 'text/html')
+ self.end_headers()
+ self.wfile.write(textwrap.dedent(f'''\
+
+ It works
+
+ Hello from the integ test container
+ This container got built and started as part of the integ test.
+ Public key: {data}
+
+
+ ''').encode('utf-8'))
+
+def main():
+ httpd = http.server.HTTPServer(("", PORT), Handler)
+ print("serving at port", PORT)
+ httpd.serve_forever()
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/cdk.out
index d8b441d447f8a..560dae10d018f 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/cdk.out
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/cdk.out
@@ -1 +1 @@
-{"version":"29.0.0"}
\ No newline at end of file
+{"version":"33.0.0"}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.assets.json
index 9e78ad767b944..fa5d0aa9091a1 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.assets.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.assets.json
@@ -1,7 +1,7 @@
{
- "version": "29.0.0",
+ "version": "33.0.0",
"files": {
- "b1025f887a56783d23c02c714067f4e119f3a3393c9db47c7ce05076e52e58bd": {
+ "edc1ba041db81671404e8a861496095ba07bd672d374473e59818e6cb877af42": {
"source": {
"path": "integ-assets-docker.template.json",
"packaging": "file"
@@ -9,7 +9,7 @@
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
- "objectKey": "b1025f887a56783d23c02c714067f4e119f3a3393c9db47c7ce05076e52e58bd.json",
+ "objectKey": "edc1ba041db81671404e8a861496095ba07bd672d374473e59818e6cb877af42.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
@@ -70,6 +70,18 @@
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-image-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
+ },
+ "6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17": {
+ "source": {
+ "directory": "asset.6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17"
+ },
+ "destinations": {
+ "current_account-current_region": {
+ "repositoryName": "cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}",
+ "imageTag": "6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17",
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-image-publishing-role-${AWS::AccountId}-${AWS::Region}"
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json
index ac306d4d02d70..2605676354e1c 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ-assets-docker.template.json
@@ -86,6 +86,11 @@
"Value": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:0a3355be12051c9984bf2b0b2bba4e6ea535968e5b6e7396449701732fe5ed14"
}
+ },
+ "ImageUri7": {
+ "Value": {
+ "Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:6308cecadfac022764e8f3e3272baeab95b48a260cae3978b7ef93bd3ff2be17"
+ }
}
},
"Parameters": {
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ.json
index f4aed5a9c37d0..e01a0b89535ed 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/integ.json
@@ -1,5 +1,5 @@
{
- "version": "29.0.0",
+ "version": "33.0.0",
"testCases": {
"integ.assets-docker": {
"stacks": [
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/manifest.json
index cd31c93490241..b9200ffed8e84 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/manifest.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/manifest.json
@@ -1,5 +1,5 @@
{
- "version": "29.0.0",
+ "version": "33.0.0",
"artifacts": {
"integ-assets-docker.assets": {
"type": "cdk:asset-manifest",
@@ -17,7 +17,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
- "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b1025f887a56783d23c02c714067f4e119f3a3393c9db47c7ce05076e52e58bd.json",
+ "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/edc1ba041db81671404e8a861496095ba07bd672d374473e59818e6cb877af42.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
@@ -75,6 +75,18 @@
"data": "ImageUri5"
}
],
+ "/integ-assets-docker/ImageUri6": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ImageUri6"
+ }
+ ],
+ "/integ-assets-docker/ImageUri7": [
+ {
+ "type": "aws:cdk:logicalId",
+ "data": "ImageUri7"
+ }
+ ],
"/integ-assets-docker/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json
index 06c8f34bf353e..2db7b2e5e5f20 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.js.snapshot/tree.json
@@ -16,7 +16,7 @@
"id": "Staging",
"path": "integ-assets-docker/DockerImage/Staging",
"constructInfo": {
- "fqn": "@aws-cdk/core.AssetStaging",
+ "fqn": "aws-cdk-lib.AssetStaging",
"version": "0.0.0"
}
},
@@ -24,13 +24,13 @@
"id": "Repository",
"path": "integ-assets-docker/DockerImage/Repository",
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr.RepositoryBase",
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr-assets.DockerImageAsset",
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
"version": "0.0.0"
}
},
@@ -42,7 +42,7 @@
"id": "Staging",
"path": "integ-assets-docker/DockerImage2/Staging",
"constructInfo": {
- "fqn": "@aws-cdk/core.AssetStaging",
+ "fqn": "aws-cdk-lib.AssetStaging",
"version": "0.0.0"
}
},
@@ -50,13 +50,13 @@
"id": "Repository",
"path": "integ-assets-docker/DockerImage2/Repository",
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr.RepositoryBase",
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr-assets.DockerImageAsset",
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
"version": "0.0.0"
}
},
@@ -68,7 +68,7 @@
"id": "Staging",
"path": "integ-assets-docker/DockerImage3/Staging",
"constructInfo": {
- "fqn": "@aws-cdk/core.AssetStaging",
+ "fqn": "aws-cdk-lib.AssetStaging",
"version": "0.0.0"
}
},
@@ -76,13 +76,13 @@
"id": "Repository",
"path": "integ-assets-docker/DockerImage3/Repository",
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr.RepositoryBase",
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr-assets.DockerImageAsset",
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
"version": "0.0.0"
}
},
@@ -94,7 +94,7 @@
"id": "Staging",
"path": "integ-assets-docker/DockerImage4/Staging",
"constructInfo": {
- "fqn": "@aws-cdk/core.AssetStaging",
+ "fqn": "aws-cdk-lib.AssetStaging",
"version": "0.0.0"
}
},
@@ -102,13 +102,13 @@
"id": "Repository",
"path": "integ-assets-docker/DockerImage4/Repository",
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr.RepositoryBase",
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr-assets.DockerImageAsset",
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
"version": "0.0.0"
}
},
@@ -120,7 +120,7 @@
"id": "Staging",
"path": "integ-assets-docker/DockerImage5/Staging",
"constructInfo": {
- "fqn": "@aws-cdk/core.AssetStaging",
+ "fqn": "aws-cdk-lib.AssetStaging",
"version": "0.0.0"
}
},
@@ -128,13 +128,65 @@
"id": "Repository",
"path": "integ-assets-docker/DockerImage5/Repository",
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr.RepositoryBase",
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-ecr-assets.DockerImageAsset",
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
+ "version": "0.0.0"
+ }
+ },
+ "DockerImage6": {
+ "id": "DockerImage6",
+ "path": "integ-assets-docker/DockerImage6",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "integ-assets-docker/DockerImage6/Staging",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Repository": {
+ "id": "Repository",
+ "path": "integ-assets-docker/DockerImage6/Repository",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
+ "version": "0.0.0"
+ }
+ },
+ "DockerImage7": {
+ "id": "DockerImage7",
+ "path": "integ-assets-docker/DockerImage7",
+ "children": {
+ "Staging": {
+ "id": "Staging",
+ "path": "integ-assets-docker/DockerImage7/Staging",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.AssetStaging",
+ "version": "0.0.0"
+ }
+ },
+ "Repository": {
+ "id": "Repository",
+ "path": "integ-assets-docker/DockerImage7/Repository",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ecr.RepositoryBase",
+ "version": "0.0.0"
+ }
+ }
+ },
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.aws_ecr_assets.DockerImageAsset",
"version": "0.0.0"
}
},
@@ -150,7 +202,7 @@
"aws:cdk:cloudformation:props": {}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-iam.CfnUser",
+ "fqn": "aws-cdk-lib.aws_iam.CfnUser",
"version": "0.0.0"
}
},
@@ -214,19 +266,19 @@
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-iam.CfnPolicy",
+ "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-iam.Policy",
+ "fqn": "aws-cdk-lib.aws_iam.Policy",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/aws-iam.User",
+ "fqn": "aws-cdk-lib.aws_iam.User",
"version": "0.0.0"
}
},
@@ -234,7 +286,7 @@
"id": "ImageUri",
"path": "integ-assets-docker/ImageUri",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnOutput",
+ "fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
@@ -242,7 +294,7 @@
"id": "ImageUri2",
"path": "integ-assets-docker/ImageUri2",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnOutput",
+ "fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
@@ -250,7 +302,7 @@
"id": "ImageUri3",
"path": "integ-assets-docker/ImageUri3",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnOutput",
+ "fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
@@ -258,15 +310,31 @@
"id": "ImageUri4",
"path": "integ-assets-docker/ImageUri4",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnOutput",
+ "fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
- "ImageUri4": {
- "id": "ImageUri4",
+ "ImageUri5": {
+ "id": "ImageUri5",
"path": "integ-assets-docker/ImageUri5",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnOutput",
+ "fqn": "aws-cdk-lib.CfnOutput",
+ "version": "0.0.0"
+ }
+ },
+ "ImageUri6": {
+ "id": "ImageUri6",
+ "path": "integ-assets-docker/ImageUri6",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnOutput",
+ "version": "0.0.0"
+ }
+ },
+ "ImageUri7": {
+ "id": "ImageUri7",
+ "path": "integ-assets-docker/ImageUri7",
+ "constructInfo": {
+ "fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
@@ -274,7 +342,7 @@
"id": "BootstrapVersion",
"path": "integ-assets-docker/BootstrapVersion",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnParameter",
+ "fqn": "aws-cdk-lib.CfnParameter",
"version": "0.0.0"
}
},
@@ -282,13 +350,13 @@
"id": "CheckBootstrapVersion",
"path": "integ-assets-docker/CheckBootstrapVersion",
"constructInfo": {
- "fqn": "@aws-cdk/core.CfnRule",
+ "fqn": "aws-cdk-lib.CfnRule",
"version": "0.0.0"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/core.Stack",
+ "fqn": "aws-cdk-lib.Stack",
"version": "0.0.0"
}
},
@@ -297,12 +365,12 @@
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
- "version": "10.1.216"
+ "version": "10.2.69"
}
}
},
"constructInfo": {
- "fqn": "@aws-cdk/core.App",
+ "fqn": "aws-cdk-lib.App",
"version": "0.0.0"
}
}
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.ts
index e0a7369b2d70b..3981b408577a0 100644
--- a/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.ts
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecr-assets/test/integ.assets-docker.ts
@@ -36,6 +36,11 @@ const asset6 = new assets.DockerImageAsset(stack, 'DockerImage6', {
cacheTo: { type: 'inline' },
});
+const asset7 = new assets.DockerImageAsset(stack, 'DockerImage7', {
+ directory: path.join(__dirname, 'demo-image-ssh'),
+ buildSsh: 'default',
+});
+
const user = new iam.User(stack, 'MyUser');
asset.repository.grantPull(user);
asset2.repository.grantPull(user);
@@ -43,6 +48,7 @@ asset3.repository.grantPull(user);
asset4.repository.grantPull(user);
asset5.repository.grantPull(user);
asset6.repository.grantPull(user);
+asset7.repository.grantPull(user);
new cdk.CfnOutput(stack, 'ImageUri', { value: asset.imageUri });
new cdk.CfnOutput(stack, 'ImageUri2', { value: asset2.imageUri });
@@ -50,5 +56,6 @@ 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 });
+new cdk.CfnOutput(stack, 'ImageUri7', { value: asset7.imageUri });
app.synth();
diff --git a/packages/aws-cdk-lib/aws-ecr-assets/README.md b/packages/aws-cdk-lib/aws-ecr-assets/README.md
index 504f071089199..ee69166717734 100644
--- a/packages/aws-cdk-lib/aws-ecr-assets/README.md
+++ b/packages/aws-cdk-lib/aws-ecr-assets/README.md
@@ -51,6 +51,8 @@ asset hash.
Additionally, you can supply `buildSecrets`. Your system must have Buildkit
enabled, see https://docs.docker.com/build/buildkit/.
+SSH agent sockets or keys may be passed to docker build via `buildSsh`.
+
```ts
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';
diff --git a/packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts b/packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts
index a626c596c814a..663f1306a936f 100644
--- a/packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts
+++ b/packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts
@@ -105,6 +105,13 @@ export interface DockerImageAssetInvalidationOptions {
*/
readonly buildSecrets?: boolean;
+ /**
+ * Use `buildSsh` while calculating the asset hash
+ *
+ * @default true
+ */
+ readonly buildSsh?: boolean;
+
/**
* Use `target` while calculating the asset hash
*
@@ -223,6 +230,17 @@ export interface DockerImageAssetOptions extends FingerprintOptions, FileFingerp
*/
readonly buildSecrets?: { [key: string]: string }
+ /**
+ * SSH agent socket or keys to pass to the `docker build` command.
+ *
+ * Docker BuildKit must be enabled to use the ssh flag
+ *
+ * @see https://docs.docker.com/build/buildkit/
+ *
+ * @default - no --ssh flag
+ */
+ readonly buildSsh?: string;
+
/**
* Docker target to build to
*
@@ -364,6 +382,10 @@ export class DockerImageAsset extends Construct implements IAsset {
*/
private readonly dockerBuildSecrets?: { [key: string]: string };
+ /**
+ * SSH agent socket or keys to pass to the `docker build` command.
+ */
+ private readonly dockerBuildSsh?: string;
/**
* Outputs to pass to the `docker build` command.
*/
@@ -446,6 +468,7 @@ export class DockerImageAsset extends Construct implements IAsset {
if (props.invalidation?.extraHash !== false && props.extraHash) { extraHash.user = props.extraHash; }
if (props.invalidation?.buildArgs !== false && props.buildArgs) { extraHash.buildArgs = props.buildArgs; }
if (props.invalidation?.buildSecrets !== false && props.buildSecrets) { extraHash.buildSecrets = props.buildSecrets; }
+ if (props.invalidation?.buildSsh !== false && props.buildSsh) {extraHash.buildSsh = props.buildSsh; }
if (props.invalidation?.target !== false && props.target) { extraHash.target = props.target; }
if (props.invalidation?.file !== false && props.file) { extraHash.file = props.file; }
if (props.invalidation?.repositoryName !== false && props.repositoryName) { extraHash.repositoryName = props.repositoryName; }
@@ -477,6 +500,7 @@ export class DockerImageAsset extends Construct implements IAsset {
this.assetName = props.assetName;
this.dockerBuildArgs = props.buildArgs;
this.dockerBuildSecrets = props.buildSecrets;
+ this.dockerBuildSsh = props.buildSsh;
this.dockerBuildTarget = props.target;
this.dockerOutputs = props.outputs;
this.dockerCacheFrom = props.cacheFrom;
@@ -487,6 +511,7 @@ export class DockerImageAsset extends Construct implements IAsset {
assetName: this.assetName,
dockerBuildArgs: this.dockerBuildArgs,
dockerBuildSecrets: this.dockerBuildSecrets,
+ dockerBuildSsh: this.dockerBuildSsh,
dockerBuildTarget: this.dockerBuildTarget,
dockerFile: props.file,
sourceHash: staging.assetHash,
@@ -530,6 +555,7 @@ export class DockerImageAsset extends Construct implements IAsset {
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKERFILE_PATH_KEY] = this.dockerfilePath;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_BUILD_ARGS_KEY] = this.dockerBuildArgs;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_BUILD_SECRETS_KEY] = this.dockerBuildSecrets;
+ resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_DOCKER_BUILD_SSH_KEY] = this.dockerBuildSsh;
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;
diff --git a/packages/aws-cdk-lib/aws-ecr-assets/test/image-asset.test.ts b/packages/aws-cdk-lib/aws-ecr-assets/test/image-asset.test.ts
index 12f3a677bf635..294c9797396d7 100644
--- a/packages/aws-cdk-lib/aws-ecr-assets/test/image-asset.test.ts
+++ b/packages/aws-cdk-lib/aws-ecr-assets/test/image-asset.test.ts
@@ -151,6 +151,7 @@ describe('image asset', () => {
const asset6 = new DockerImageAsset(stack, 'Asset6', { directory, extraHash: 'random-extra' });
const asset7 = new DockerImageAsset(stack, 'Asset7', { directory, outputs: ['123'] });
const asset8 = new DockerImageAsset(stack, 'Asset8', { directory, buildSecrets: { mySecret: DockerBuildSecret.fromSrc('abc.txt') } });
+ const asset9 = new DockerImageAsset(stack, 'Asset9', { directory, buildSsh: 'default' });
expect(asset1.assetHash).toEqual('13248c55633f3b198a628bb2ea4663cb5226f8b2801051bd0c725950266fd590');
expect(asset2.assetHash).toEqual('36bf205fb9adc5e45ba1c8d534158a0aed96d190eff433af1d90f3b94f96e751');
@@ -160,7 +161,7 @@ describe('image asset', () => {
expect(asset6.assetHash).toEqual('3528d6838647a5e9011b0f35aec514d03ad11af05a94653cdcf4dacdbb070a06');
expect(asset7.assetHash).toEqual('ced0a3076efe217f9cbdff0943e543f36ecf77f70b9a6fe28b8633deb728a462');
expect(asset8.assetHash).toEqual('ffc2718e616141d18c8f4623d13cdfd68cb8f010ca5db31c916c8b5f10c162be');
-
+ expect(asset9.assetHash).toEqual('52617cbf463d1931a93da1357dfe99687f32e092619fc6d280cee8d9ee31b63b');
});
testDeprecated('repositoryName is included in the asset id', () => {
diff --git a/packages/aws-cdk-lib/cloud-assembly-schema/lib/assets/docker-image-asset.ts b/packages/aws-cdk-lib/cloud-assembly-schema/lib/assets/docker-image-asset.ts
index fd124d683317d..4c1ad6d426a55 100644
--- a/packages/aws-cdk-lib/cloud-assembly-schema/lib/assets/docker-image-asset.ts
+++ b/packages/aws-cdk-lib/cloud-assembly-schema/lib/assets/docker-image-asset.ts
@@ -63,6 +63,15 @@ export interface DockerImageSource {
*/
readonly dockerBuildArgs?: { [name: string]: string };
+ /**
+ * SSH agent socket or keys
+ *
+ * Requires building with docker buildkit.
+ *
+ * @default - No ssh flag is set
+ */
+ readonly dockerBuildSsh?: string;
+
/**
* Additional build secrets
*
@@ -156,4 +165,4 @@ export interface DockerCacheOption {
* };
*/
readonly params?: { [key: string]: string };
-}
\ No newline at end of file
+}
diff --git a/packages/aws-cdk-lib/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts b/packages/aws-cdk-lib/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts
index ba3ab6d87cff2..9354300baa1ba 100644
--- a/packages/aws-cdk-lib/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts
+++ b/packages/aws-cdk-lib/cloud-assembly-schema/lib/cloud-assembly/metadata-schema.ts
@@ -161,6 +161,13 @@ export interface ContainerImageAssetMetadataEntry extends BaseAssetMetadataEntry
*/
readonly buildArgs?: { [key: string]: string };
+ /**
+ * SSH agent socket or keys to pass to the `docker build` command
+ *
+ * @default no ssh arg is passed
+ */
+ readonly buildSsh?: string;
+
/**
* Build secrets to pass to the `docker build` command
*
diff --git a/packages/aws-cdk-lib/cloud-assembly-schema/schema/assets.schema.json b/packages/aws-cdk-lib/cloud-assembly-schema/schema/assets.schema.json
index 6e7f02037f744..f34adb5ef24f5 100644
--- a/packages/aws-cdk-lib/cloud-assembly-schema/schema/assets.schema.json
+++ b/packages/aws-cdk-lib/cloud-assembly-schema/schema/assets.schema.json
@@ -155,6 +155,10 @@
"type": "string"
}
},
+ "dockerBuildSsh": {
+ "description": "SSH agent socket or keys\n\nRequires building with docker buildkit. (Default - No ssh flag is set)",
+ "type": "string"
+ },
"dockerBuildSecrets": {
"description": "Additional build secrets\n\nOnly allowed when `directory` is set. (Default - No additional build secrets)",
"type": "object",
diff --git a/packages/aws-cdk-lib/cloud-assembly-schema/schema/cloud-assembly.schema.json b/packages/aws-cdk-lib/cloud-assembly-schema/schema/cloud-assembly.schema.json
index 45da2861cd9d8..ada87b31af985 100644
--- a/packages/aws-cdk-lib/cloud-assembly-schema/schema/cloud-assembly.schema.json
+++ b/packages/aws-cdk-lib/cloud-assembly-schema/schema/cloud-assembly.schema.json
@@ -216,6 +216,10 @@
"type": "string"
}
},
+ "buildSsh": {
+ "description": "SSH agent socket or keys to pass to the `docker build` command (Default no ssh arg is passed)",
+ "type": "string"
+ },
"buildSecrets": {
"description": "Build secrets to pass to the `docker build` command (Default no build secrets are passed)",
"type": "object",
diff --git a/packages/aws-cdk-lib/core/lib/assets.ts b/packages/aws-cdk-lib/core/lib/assets.ts
index d4243b6f7a7b7..c9a7d47d98672 100644
--- a/packages/aws-cdk-lib/core/lib/assets.ts
+++ b/packages/aws-cdk-lib/core/lib/assets.ts
@@ -202,6 +202,14 @@ export interface DockerImageAssetSource {
*/
readonly dockerBuildSecrets?: { [key: string]: string };
+ /**
+ * SSH agent socket or keys to pass to the `docker buildx` command.
+ *
+ *
+ * @default - no ssh arg is passed
+ */
+ readonly dockerBuildSsh?: string;
+
/**
* Docker target to build to
*
diff --git a/packages/aws-cdk-lib/cx-api/lib/assets.ts b/packages/aws-cdk-lib/cx-api/lib/assets.ts
index 42461895828be..ca6581548df63 100644
--- a/packages/aws-cdk-lib/cx-api/lib/assets.ts
+++ b/packages/aws-cdk-lib/cx-api/lib/assets.ts
@@ -13,6 +13,7 @@ export const ASSET_RESOURCE_METADATA_PATH_KEY = 'aws:asset:path';
export const ASSET_RESOURCE_METADATA_DOCKERFILE_PATH_KEY = 'aws:asset:dockerfile-path';
export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_ARGS_KEY = 'aws:asset:docker-build-args';
export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_SECRETS_KEY = 'aws:asset:docker-build-secrets';
+export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_SSH_KEY = 'aws:asset:docker-build-ssh';
export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_TARGET_KEY = 'aws:asset:docker-build-target';
export const ASSET_RESOURCE_METADATA_PROPERTY_KEY = 'aws:asset:property';
export const ASSET_RESOURCE_METADATA_IS_BUNDLED_KEY = 'aws:asset:is-bundled';
diff --git a/packages/aws-cdk/lib/assets.ts b/packages/aws-cdk/lib/assets.ts
index 5511e644e933d..ee0db6771fba9 100644
--- a/packages/aws-cdk/lib/assets.ts
+++ b/packages/aws-cdk/lib/assets.ts
@@ -120,6 +120,7 @@ async function prepareDockerImageAsset(
assetManifest.addDockerImageAsset(asset.sourceHash, {
directory: asset.path,
dockerBuildArgs: asset.buildArgs,
+ dockerBuildSsh: asset.buildSsh,
dockerBuildTarget: asset.target,
dockerFile: asset.file,
networkMode: asset.networkMode,
diff --git a/packages/cdk-assets/lib/private/docker.ts b/packages/cdk-assets/lib/private/docker.ts
index 27b7f1ed9b911..12b8ab53a213e 100644
--- a/packages/cdk-assets/lib/private/docker.ts
+++ b/packages/cdk-assets/lib/private/docker.ts
@@ -16,6 +16,7 @@ interface BuildOptions {
readonly file?: string;
readonly buildArgs?: Record;
readonly buildSecrets?: Record;
+ readonly buildSsh?: string;
readonly networkMode?: string;
readonly platform?: string;
readonly outputs?: string[];
@@ -97,6 +98,7 @@ export class Docker {
'build',
...flatten(Object.entries(options.buildArgs || {}).map(([k, v]) => ['--build-arg', `${k}=${v}`])),
...flatten(Object.entries(options.buildSecrets || {}).map(([k, v]) => ['--secret', `id=${k},${v}`])),
+ ...options.buildSsh ? ['--ssh', options.buildSsh] : [],
'--tag', options.tag,
...options.target ? ['--target', options.target] : [],
...options.file ? ['--file', options.file] : [],