diff --git a/API.md b/API.md
index b5d1470e..aec2b357 100644
--- a/API.md
+++ b/API.md
@@ -75,6 +75,7 @@ new ECRDeployment(scope: Construct, id: string, props: ECRDeploymentProps)
* **props** ([ECRDeploymentProps](#cdk-ecr-deployment-ecrdeploymentprops)
) *No description*
* **dest** ([IImageName](#cdk-ecr-deployment-iimagename)
) The destination of the docker image.
* **src** ([IImageName](#cdk-ecr-deployment-iimagename)
) The source of the docker image.
+ * **architecture** (string
) The architecture of the docker images to copy. __*Optional*__
* **buildImage** (string
) Image to use to build Golang lambda for custom resource, if download fails or is not wanted. __*Default*__: public.ecr.aws/sam/build-go1.x:latest
* **environment** (Map
) The environment variable to set. __*Optional*__
* **memoryLimit** (number
) The amount of memory (in MiB) to allocate to the AWS Lambda function which replicates the files from the CDK bucket to the destination bucket. __*Default*__: 512
@@ -144,6 +145,7 @@ Name | Type | Description
-----|------|-------------
**dest** | [IImageName](#cdk-ecr-deployment-iimagename)
| The destination of the docker image.
**src** | [IImageName](#cdk-ecr-deployment-iimagename)
| The source of the docker image.
+**architecture**? | string
| The architecture of the docker images to copy.
__*Optional*__
**buildImage**? | string
| Image to use to build Golang lambda for custom resource, if download fails or is not wanted.
__*Default*__: public.ecr.aws/sam/build-go1.x:latest
**environment**? | Map
| The environment variable to set.
__*Optional*__
**memoryLimit**? | number
| The amount of memory (in MiB) to allocate to the AWS Lambda function which replicates the files from the CDK bucket to the destination bucket.
__*Default*__: 512
diff --git a/lambda/Dockerfile b/lambda/Dockerfile
index 1e6c581d..913949d4 100644
--- a/lambda/Dockerfile
+++ b/lambda/Dockerfile
@@ -18,9 +18,9 @@ COPY go.mod go.sum ./
RUN go env
-# RUN go mod download -x
-
COPY . /ws
RUN mkdir -p /asset/ && \
make OUTPUT=/asset/bootstrap
+
+ENTRYPOINT [ "/asset/bootstrap" ]
\ No newline at end of file
diff --git a/lambda/main.go b/lambda/main.go
index 639d52c6..a9fe646b 100644
--- a/lambda/main.go
+++ b/lambda/main.go
@@ -71,7 +71,12 @@ func handler(ctx context.Context, event cfn.Event) (physicalResourceID string, d
return physicalResourceID, data, err
}
- log.Printf("SrcImage: %v DestImage: %v", srcImage, destImage)
+ arch, err := getStrPropsDefault(event.ResourceProperties, ARCHITECTURE, "")
+ if err != nil {
+ return physicalResourceID, data, err
+ }
+
+ log.Printf("SrcImage: %v DestImage: %v Architecture: %v", srcImage, destImage, arch)
srcRef, err := alltransports.ParseImageName(srcImage)
if err != nil {
@@ -82,13 +87,13 @@ func handler(ctx context.Context, event cfn.Event) (physicalResourceID string, d
return physicalResourceID, data, err
}
- srcOpts := NewImageOpts(srcImage)
+ srcOpts := NewImageOpts(srcImage, arch)
srcOpts.SetCreds(srcCreds)
srcCtx, err := srcOpts.NewSystemContext()
if err != nil {
return physicalResourceID, data, err
}
- destOpts := NewImageOpts(destImage)
+ destOpts := NewImageOpts(destImage, arch)
destOpts.SetCreds(destCreds)
destCtx, err := destOpts.NewSystemContext()
if err != nil {
diff --git a/lambda/main_test.go b/lambda/main_test.go
index a28b323f..036f4bc6 100644
--- a/lambda/main_test.go
+++ b/lambda/main_test.go
@@ -33,10 +33,10 @@ func TestMain(t *testing.T) {
destRef, err := alltransports.ParseImageName(destImage)
assert.NoError(t, err)
- srcOpts := NewImageOpts(srcImage)
+ srcOpts := NewImageOpts(srcImage, "arm64")
srcCtx, err := srcOpts.NewSystemContext()
assert.NoError(t, err)
- destOpts := NewImageOpts(destImage)
+ destOpts := NewImageOpts(destImage, "arm64")
destCtx, err := destOpts.NewSystemContext()
assert.NoError(t, err)
diff --git a/lambda/utils.go b/lambda/utils.go
index 461c3807..6cc51f27 100644
--- a/lambda/utils.go
+++ b/lambda/utils.go
@@ -21,10 +21,11 @@ import (
)
const (
- SRC_IMAGE string = "SrcImage"
- DEST_IMAGE string = "DestImage"
- SRC_CREDS string = "SrcCreds"
- DEST_CREDS string = "DestCreds"
+ SRC_IMAGE string = "SrcImage"
+ DEST_IMAGE string = "DestImage"
+ SRC_CREDS string = "SrcCreds"
+ DEST_CREDS string = "DestCreds"
+ ARCHITECTURE string = "Architecture"
)
type ECRAuth struct {
@@ -35,6 +36,33 @@ type ECRAuth struct {
ExpiresAt time.Time
}
+var validArchs = []string{
+ "386",
+ "amd64",
+ "amd64p32",
+ "arm",
+ "arm64",
+ "arm64be",
+ "armbe",
+ "loong64",
+ "mips",
+ "mips64",
+ "mips64le",
+ "mips64p32",
+ "mips64p32le",
+ "mipsle",
+ "ppc",
+ "ppc64",
+ "ppc64le",
+ "riscv",
+ "riscv64",
+ "s390",
+ "s390x",
+ "sparc",
+ "sparc64",
+ "wasm",
+}
+
func GetECRRegion(uri string) string {
re := regexp.MustCompile(`dkr\.ecr\.(.+?)\.`)
m := re.FindStringSubmatch(uri)
@@ -86,14 +114,15 @@ type ImageOpts struct {
requireECRLogin bool
region string
creds string
+ architecture string
}
-func NewImageOpts(uri string) *ImageOpts {
+func NewImageOpts(uri string, arch string) *ImageOpts {
requireECRLogin := strings.Contains(uri, "dkr.ecr")
if requireECRLogin {
- return &ImageOpts{uri, requireECRLogin, GetECRRegion(uri), ""}
+ return &ImageOpts{uri, requireECRLogin, GetECRRegion(uri), "", arch}
} else {
- return &ImageOpts{uri, requireECRLogin, "", ""}
+ return &ImageOpts{uri, requireECRLogin, "", "", arch}
}
}
@@ -109,6 +138,7 @@ func (s *ImageOpts) NewSystemContext() (*types.SystemContext, error) {
ctx := &types.SystemContext{
DockerRegistryUserAgent: "ecr-deployment",
DockerAuthConfig: &types.DockerAuthConfig{},
+ ArchitectureChoice: s.architecture,
}
if s.creds != "" {
@@ -184,3 +214,13 @@ func GetSecret(secretId string) (secret string, err error) {
}
return *resp.SecretString, nil
}
+
+func IsValidGOARCH(arch string) bool {
+ for _, validArch := range validArchs {
+ if arch == validArch {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/package.json b/package.json
index 809997ce..a21363d0 100644
--- a/package.json
+++ b/package.json
@@ -90,7 +90,7 @@
],
"main": "lib/index.js",
"license": "Apache-2.0",
- "version": "0.0.0",
+ "version": "3.0.0",
"jest": {
"testMatch": [
"/src/**/__tests__/**/*.ts?(x)",
diff --git a/publish-ark-image.sh b/publish-ark-image.sh
new file mode 100755
index 00000000..d2afd42d
--- /dev/null
+++ b/publish-ark-image.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+ECR_URI="758920976184.dkr.ecr.us-east-1.amazonaws.com"
+ECR_REPO_URI=$ECR_URI/cdk-ecr-deployment
+# Authenticate with AWS ECR
+aws ecr get-login-password --profile "$AWS_PROFILE" --region "$AWS_REGION" | docker login --username AWS --password-stdin "$ECR_URI"
+
+# Get the current Git commit hash
+GIT_COMMIT_HASH=$(git rev-parse --short HEAD)
+
+# push to registry
+# --provenance=true necessary to avoid the error https://stackoverflow.com/a/75149347/4820648
+docker buildx build \
+ --provenance=false \
+ --file lambda/Dockerfile \
+ --push \
+ --tag $ECR_REPO_URI:latest \
+ --tag $ECR_REPO_URI:$GIT_COMMIT_HASH \
+ --platform linux/amd64 \
+ --progress=plain \
+ lambda/.
+
diff --git a/src/index.ts b/src/index.ts
index 388ed888..34560afc 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -31,6 +31,11 @@ export interface ECRDeploymentProps {
*/
readonly dest: IImageName;
+ /**
+ * The architecture of the docker images to copy.
+ */
+ readonly architecture?: string;
+
/**
* The amount of memory (in MiB) to allocate to the AWS Lambda function which
* replicates the files from the CDK bucket to the destination bucket.
@@ -192,6 +197,7 @@ export class ECRDeployment extends Construct {
SrcCreds: props.src.creds,
DestImage: props.dest.uri,
DestCreds: props.dest.creds,
+ Architecture: props.architecture,
},
});
}
diff --git a/test/example.ecr-deployment.ts b/test/example.ecr-deployment.ts
index 2d5bd7c8..d7ea87aa 100644
--- a/test/example.ecr-deployment.ts
+++ b/test/example.ecr-deployment.ts
@@ -32,11 +32,13 @@ class TestECRDeployment extends Stack {
new ecrDeploy.ECRDeployment(this, 'DeployECRImage', {
src: new ecrDeploy.DockerImageName(image.imageUri),
dest: new ecrDeploy.DockerImageName(`${repo.repositoryUri}:latest`),
+ architecture: 'arm64',
});
new ecrDeploy.ECRDeployment(this, 'DeployDockerImage', {
src: new ecrDeploy.DockerImageName('javacs3/javacs3:latest', 'dockerhub'),
dest: new ecrDeploy.DockerImageName(`${repo.repositoryUri}:dockerhub`),
+ architecture: 'arm64',
}).addToPrincipalPolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [