2

Goal

I want to be able to create a lambda function with CDK, but then manage the docker image that the lambda uses with a CI/CD pipeline (github actions)

What I have done

I have the following code:

    this.repository =
      this.config.repository ??
      new ecr.Repository(this, 'Repository', {
        repositoryName: this.config.repositoryName,
      });

    this.lambda = new lambda.DockerImageFunction(this, 'DockerLambda', {
      code: lambda.DockerImageCode.fromImageAsset(
        path.join(__dirname, '../docker/minimal'),
        { cmd: this.config.cmd, entrypoint: this.config.entrypoint },
      ),
      functionName: config.functionName ?? this.node.id,
      environment: config.environment,
      timeout: Duration.seconds(config.timeout ?? 600),
      memorySize: config.memorySize ?? 1024,
      vpc: config.vpc,
      vpcSubnets: config.vpcSubnets ?? {
        subnets: config.vpc?.privateSubnets,
      },
    });

I am doing it this way because there doesn't appear to be a way to create a lambda without specifying where the code will come from. The 'minimal' docker is just a generic placeholder, it will eventually get replaced by the real code. That code does not live in the repository where we have our CDK code, so CDK does not have access to build the real docker image.

So, the steps that we follow are:

  1. Use this generic DockerImageLambda construct to create both an ECR repository, and a lambda with a placeholder docker image. This ECR repository is where github will be uploading the real images, but until then, it will be empty (since it was just created).
  2. Use Github actions to upload a real docker image to the ECR repository created in step #1
  3. Use Github actions to update the lambda function with the new image from step #2

The Problem

This method works until you change something in the lambda CDK code. At that point, it will try to reconfigure the lambda to use the placeholder docker image, which essentially "breaks" what was working there.

The question

How can I make it use the placeholder docker image only the first time the lambda is created? OR, is there a better way to do this?

2 Answers 2

4

You can decouple uploading the asset to ECR from the lambda definition.

To upload to the repository you created, use the cdk-ecr-deployment construct. Then create the lambda with the correct ECR repository from the beginning. You will not need to edit the lambda to change the source ECR repository.

You also need to make your Lambda construct depend on the deployment, so that when the lambda is created, the repository contains your dummy image.

It would look like this:

    this.repository =
      this.config.repository ??
      new ecr.Repository(this, 'Repository', {
        repositoryName: this.config.repositoryName,
      });
    const dummyImage = DockerImageAsset(
        path.join(__dirname, '../docker/minimal')
      )

    const dummyDeployment = new ECRDeployment(this, 'DummyImage',
        { src: new DockerImageName(dummyImage.imageUri),
          dest: new DockerImageName(this.repository.repositoryUriForTagOrDigest('latest')
    })
    
    this.lambda = new lambda.DockerImageFunction(this, 'DockerLambda', {
      code: lambda.DockerImageCode.fromEcr(
        this.repository,
        { cmd: this.config.cmd, entrypoint: this.config.entrypoint },
      ),
      functionName: config.functionName ?? this.node.id,
      environment: config.environment,
      timeout: Duration.seconds(config.timeout ?? 600),
      memorySize: config.memorySize ?? 1024,
      vpc: config.vpc,
      vpcSubnets: config.vpcSubnets ?? {
        subnets: config.vpc?.privateSubnets,
      },
    });
    
    this.lambda.node.addDependency(dummyDeployment)

Sign up to request clarification or add additional context in comments.

2 Comments

Hey, thanks for the response. Just dropping in to let you know I'm not ignoring it, just haven't been able to try it yet, work is nuts. I'll give it a roll soon and mark your answer correct
lol, welp, I told you I'd give it a roll and mark the answer. I did one and not the other. This totally works. Thank you!
-1

You could import the real ECR into your CDK stack with the fromXXXXX help methods.

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#static-fromwbrrepositorywbrarnscope-id-repositoryarn

1 Comment

CDK is creating the real ECR, there's just no real image in it until github uploads one

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.