Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to not rebuild a DockerImageAsset at every deploy using aws-cdk in TypeScript?

My app is a Python API that I package as a Docker image and use with ECS Fargate (Spot Instances). The code below works.

My issue is that it rebuilds the entire image every time I deploy this – which is very time-consuming (downloads all dependencies, makes the image, uploads, etc). I want it to reuse the exact same image uploaded to ECR by aws-cdk itself.

Is there a way (env variable or else) for me to skip this when I don't touch the app's code and just make changes to the stack?

#!/usr/bin/env node
import * as cdk from "@aws-cdk/core"
import * as ecs from "@aws-cdk/aws-ecs"
import * as ec2 from "@aws-cdk/aws-ec2"
import * as ecrassets from "@aws-cdk/aws-ecr-assets"

// See https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ecs-readme.html
export class Stack extends cdk.Stack {
    constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
        super(scope, id, props)

        /**
         * Repository & Image
         */

        const apiDockerImage = new ecrassets.DockerImageAsset(
            this,
            `my-api-image`,
            {
                directory: `.`,
                exclude: [`cdk.out`, `cdk`, `.git`]
            }
        )

        /**
         * Cluster
         */

        const myCluster = new ecs.Cluster(this, "Cluster", {})

        // Add Spot Capacity to the Cluster
        myCluster.addCapacity(`spot-auto-scaling-group-capacity`, {
            maxCapacity: 2,
            minCapacity: 1,
            instanceType: new ec2.InstanceType(`r5a.large`),
            spotPrice: `0.0400`,
            spotInstanceDraining: true
        })

        // A task Definition describes what a single copy of a task should look like
        const myApiFargateTaskDefinition = new ecs.FargateTaskDefinition(
            this,
            `api-fargate-task-definition`,
            {
                cpu: 2048,
                memoryLimitMiB: 8192,
            }
        )

        // Add image to task def
        myApiFargateTaskDefinition.addContainer(`api-container`, {
            image: ecs.ContainerImage.fromEcrRepository(
                apiDockerImage.repository,
                `latest`
            ),
        })

        // And the service attaching the task def to the cluster
        const myApiService = new ecs.FargateService(
            this,
            `my-api-fargate-service`,
            {
                cluster: myCluster,
                taskDefinition: myApiFargateTaskDefinition,
                desiredCount: 1,
                assignPublicIp: true,
            }
        )
    }
}

like image 875
Lazhar Avatar asked Nov 07 '22 10:11

Lazhar


1 Answers

The proper solution is to build your image outside of this deployment process and just get a reference to that image in ECR.

like image 186
Griffin Hammer Avatar answered Dec 11 '22 05:12

Griffin Hammer