Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(aws-events-targets): The EcsTask target for the L2 EventBridge Rule construct needs to have a "launch type" parameter #28990

Closed
2 tasks
sabiiiq opened this issue Feb 5, 2024 · 5 comments · Fixed by #29069
Labels
@aws-cdk/aws-events-targets effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2

Comments

@sabiiiq
Copy link

sabiiiq commented Feb 5, 2024

Describe the feature

When setting an ECS task as a target for an EventBridge rule via the AWS console or AWS SDKs, you are given the option to select the launch type for the compute that the task will run on.

image

However, the EcsTask target for the L2 EventBridge Rule construct does not provide a means to select the launch type.

As a result, I've had to use the more verbose L1 CfnRule construct and EcsParameters interface, which does provide a launchType parameter.

Use Case

I was trying to create an EventBridge rule that runs an ECS task when triggered. While I intend for this task to run on Fargate, I'd added both EC2 and Fargate compatibilities for the task definition so that I could run it on EC2 in case I ever needed visibility into the compute environment for troubleshooting.

I used the L2 EventBridge Rule construct and its associated EcsTask target which provided a relatively simple interface:

import * as cdk from 'aws-cdk-lib';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import { Construct } from 'constructs';

export class exampleStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    const ecsCluster = new ecs.Cluster(this, 'ECSCluster', {
	...
	enableFargateCapacityProviders: true,
	...
    });
    const ecsTaskDefinition = new ecs.TaskDefinition(this, 'ECSTaskDefinition', {
	...
	compatibility: ecs.Compatibility.EC2_AND_FARGATE,
	...
    });
    const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {...});

    const eventBridgeRule = new events.Rule(this, 'EventBridgeRule', {
      eventPattern: {...}
      }
    });
    eventBridgeRule.addTarget(
      new targets.EcsTask({
        cluster: ecsCluster,
        taskDefinition: ecsTaskDefinition,
        taskCount: 1,
        subnetSelection: {subnetType: ec2.SubnetType.PRIVATE_ISOLATED},
        securityGroups: [securityGroup]
      })
    );
  }
}

However, after running cdk deploy and triggering the EventBridge rule, the ECS task failed to run because the launch type had implicitly been set to EC2 and only Fargate compute was available for the cluster. Looking at the configuration of the EventBridge rule and target in the AWS console, and running cdk synth, I confirmed that the launch type had somehow been set to EC2.

image

...
EcsParameters: 
	LaunchType: EC2
...

Looking through the code for the EcsTask target class, the launchType property is set implicitly by invoking the ecs.taskDefinition.isEc2Compatible() method:

In other words, if the task definition has any EC2 compatibility at all, the launch type of the EcsTask EventBridge target is automatically set to EC2, even you are trying to run the task in a cluster that has only Fargate compute available.

As a result, I had to rewrite my CDK code to use the much more verbose L1 CfnRule construct and EcsParameters interface, just because this one parameter was missing. This involved writing out a lot more code than I would have preferred to.

Proposed Solution

Adding a launchType parameter for the EcsTask target would make the L2 EventBridge Rule construct and EcsTask target more usable. I could then use the same code I showed above, just with the addition of the launchType parameter:

import * as cdk from 'aws-cdk-lib';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import { Construct } from 'constructs';

export class exampleStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    const ecsCluster = new ecs.Cluster(this, 'ECSCluster', {
	...
	enableFargateCapacityProviders: true,
	...
    });
    const ecsTaskDefinition = new ecs.TaskDefinition(this, 'ECSTaskDefinition', {
	...
	compatibility: ecs.Compatibility.EC2_AND_FARGATE,
	...
    });
    const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {...});

    const eventBridgeRule = new events.Rule(this, 'EventBridgeRule', {
      eventPattern: {...}
      }
    });
    eventBridgeRule.addTarget(
      new targets.EcsTask({
        cluster: ecsCluster,
        taskDefinition: ecsTaskDefinition,
        taskCount: 1,
        subnetSelection: {subnetType: ec2.SubnetType.PRIVATE_ISOLATED},
        securityGroups: [securityGroup],
        launchType: 'FARGATE'
      })
    );
  }
}

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

2.121.1

Environment details (OS name and version, etc.)

Amazon Linux 2

@sabiiiq sabiiiq added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Feb 5, 2024
@pahud
Copy link
Contributor

pahud commented Feb 5, 2024

Did you mean your compatibility could be Compatibility.EC2_AND_FARGATE but your cluster is a FARGATE only cluster and you need to set the LaunchType as Fargate?

Yes looks like EcsTask should have an optional prop for launchType which is implicitly determined if undefined.

I guess you still can use L2 and addPropertyOverride() to override the auto-generated launch type prop.

@sabiiiq
Copy link
Author

sabiiiq commented Feb 5, 2024

Yes, exactly. That's what I want to be able to do with the L2 Rule construct and EcsTask target.

@pahud
Copy link
Contributor

pahud commented Feb 5, 2024

Before we have a PR for that, you can work it around like this:

    const eventBridgeRule = new events.Rule(this, 'EventBridgeRule', {
      schedule,
    });

    eventBridgeRule.addTarget(
      new targets.EcsTask({
        cluster: ecsCluster,
        taskDefinition: ecsTaskDefinition,
        taskCount: 1,
        subnetSelection: {subnetType: ec2.SubnetType.PRIVATE_ISOLATED},
        // launchType: 'FARGATE'
      })
    );

    const cfnRule = eventBridgeRule.node.tryFindChild('Resource') as events.CfnRule;
    cfnRule.addPropertyOverride('Targets.0.EcsParameters.LaunchType', 'FARGATE');

Let me know if it works for you.

@pahud pahud added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. p2 effort/medium Medium work item – several days of effort and removed needs-triage This issue or PR still needs to be triaged. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Feb 5, 2024
@mergify mergify bot closed this as completed in #29069 Feb 15, 2024
@mergify mergify bot closed this as completed in b4daf84 Feb 15, 2024
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

1 similar comment
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

GavinZZ pushed a commit that referenced this issue Feb 22, 2024
### Issue # (if applicable)

Closes #28990.

### Reason for this change

There are cases where a task definition is created to be compatible with both EC2 and Fargate, and then we want to run the task in Fargate.

### Description of changes

I created the `launchType` property. The `launchType` is overridden if the property is specified.

### Description of how you validated changes

Both unit and integ tests

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-events-targets effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants