aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.66k stars 3.92k forks source link

aws_events_targets: EcsTarget can't be set to latest revision #21782

Open eliyasmeth opened 2 years ago

eliyasmeth commented 2 years ago

Describe the bug

When creating a ECSTarget on a rule, I want the ECS Task to be set to the latest revision, not the specific number of the revision. By researching on the ECS Target documentation I couldn't find a way to set this value, nor a property or parameter.

Expected Behavior

When creating a ECSTarget on a rule, I would like to have a way to tell the ECSTask to use the latest revision, not the specific revision number.

Current Behavior

When creating a ECSTarget on a rule, the ECSTask always takes the specific revision number of the deployment.

Reproduction Steps

  new targets.EcsTask({
    cluster,
    taskDefinition,
    containerOverrides: [
      {
        containerName: container.containerName,
        environment: [
          {
            name: "MEETING",
            value: EventField.fromPath("$.detail.meetingId"),
          },
        ],
      },
    ],
  })
);

Possible Solution

Having a property, flag or some value to represent the latest tag on the ECSTask.

Additional Information/Context

No response

CDK CLI Version

2.13.0

Framework Version

No response

Node.js Version

16

OS

Windows 10 Pro x64

Language

Typescript

Language Version

No response

Other information

No response

pradoz commented 2 years ago

Duplicate of #21711

pradoz commented 2 years ago

@eliyasmeth Could you please provide an example of updating the task definition, and the latest version not running by default? Unless you specify a tag, it will default to the latest release

peterwoodworth commented 2 years ago

I'm not sure how you know this is being set to a specific version number, like @pradoz said I'm pretty sure this should default to latest

eliyasmeth commented 2 years ago

@pradoz @peterwoodworth So let me add some context:

We have a CDK code based on this example from AWS (https://github.com/aws-samples/amazon-chime-media-capture-pipeline-demo). We changed the last lambda of the process video to use an ECS Task for scalability.

Basically we added this code for the ECS part:

const cluster = new ecs.Cluster(this, clusterName, {
      vpc: ec2.Vpc.fromLookup(this, 'external-vpc', {
        vpcName: ecsVpc,
      }),
    });

    cdk.Tags.of(cluster).add("Name", clusterName);

    const taskDefinition = new ecs.FargateTaskDefinition(this, "processVideo", {
      cpu: 2048,
      memoryLimitMiB: 4096,
    });

    cdk.Tags.of(taskDefinition).add("Name", taskName);

    const container = taskDefinition.addContainer("container", {
      image: ecs.ContainerImage.fromAsset(
        "src/<container-image-source>"
      ),
      environment: {
        MEDIA_CAPTURE_BUCKET: mediaCaptureBucket.bucketName,
        MEETINGS_TABLE_NAME: meetingsTable.tableName,
      },
      logging: new ecs.AwsLogDriver({
        streamPrefix: "processVideoLogging",
      }),
    });

    meetingsTable.grantReadWriteData(taskDefinition.taskRole);
    mediaCaptureBucket.grantReadWrite(taskDefinition.taskRole);

    processOutputRule.addTarget(
      new targets.EcsTask({
        cluster,
        taskDefinition,
        containerOverrides: [
          {
            containerName: container.containerName,
            environment: [
              {
                name: "MEETING",
                value: EventField.fromPath("$.detail.meetingId"),
              },
            ],
          },
        ],
      })
    );

When this code is deployed, we get an EventBridge rule pointing to a specific ECS task revision as target. Although the revision being pointed at is indeed the latest one at the time of deployment, we need for the EventBridge rule to always point to the latest revision number and not just the latest one at the time of deployment. This because the ECS task will also get updated outside of the CDK script. Therefore, when the EventBridge rule gets created, we need for it to point to what will be considered the latest revision any time, and not just when running the CDK.

image

And for the same reason we get the policy pointing to the specific revision number on the executionRole.

image

Now, we have a CodeBuild to update only the code from the ECR and register a new task definition revision, but since the ECSTarget and the RolePolicy is linked to the specific revision number, any new task revision will not be executed, only the one that was deployed with the first deploy with CDK.

peterwoodworth commented 2 years ago

Thanks for explaining further,

I think this is determined by the task definition arn. CloudFormation returns the arn with the latest revision attached when referencing a TaskDefinition

Since we need an arn which references latest, but won't know the arn until deploy time, we would have to do string manipulation with intrinsic functions either here just for this use case https://github.com/aws/aws-cdk/blob/4303dca8ab1f690147d6a64d333118ac90297035/packages/%40aws-cdk/aws-events-targets/lib/ecs-task.ts#L160

Or on the TaskDefinition construct itself, and we could expose this modified arn on a new prop

eliyasmeth commented 2 years ago

Thanks for explaining further,

I think this is determined by the task definition arn. CloudFormation returns the arn with the latest revision attached when referencing a TaskDefinition

Since we need an arn which references latest, but won't know the arn until deploy time, we would have to do string manipulation with intrinsic functions either here just for this use case

https://github.com/aws/aws-cdk/blob/4303dca8ab1f690147d6a64d333118ac90297035/packages/%40aws-cdk/aws-events-targets/lib/ecs-task.ts#L160

Or on the TaskDefinition construct itself, and we could expose this modified arn on a new prop

Thank you for the explanation about the ARN from CF, now it makes sense why it takes the revision number.

So question, at first I thought you were recommending us to make some changes on our code, but then I saw you referenced the CDK library which we can't modify, so just confirming if this is a change you will be doing or is something we should do?

Again thank you for your help.

peterwoodworth commented 2 years ago

I'm referencing CDK code for us to fix for all users 🙂

There are a few ways you could do this currently on customer code - what I'd recommend is to do something similar to what I've described regarding intrinsic functions to create a proper arn. Once you have an arn you will have to use escape hatches to access and modify the underlying Cfn resource. overwriting the resource arn on the Event Rule resource Events::Rule.Target.EcsParameters.TaskDefinitionArn to reflect latest instead of the specific version number

hrishikeshdkakkad commented 1 year ago

So I still don’t get the full reference? How do I mark my cfn to point to latest?

based on https://github.com/aws/aws-cdk/issues/21782#issuecomment-1231044822?