-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(aws-ecs): add support for Event Targets (#1571)
EC2 task definitions can now be used as CloudWatch event targets. ALSO IN THIS COMMIT * Improve hash calculation of Docker images. * Add `grantPassRole()` method to iam.Role Fixes #1370.
- Loading branch information
Showing
14 changed files
with
1,412 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
packages/@aws-cdk/aws-ecs/lib/ec2/ec2-event-rule-target.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import events = require ('@aws-cdk/aws-events'); | ||
import iam = require('@aws-cdk/aws-iam'); | ||
import cdk = require('@aws-cdk/cdk'); | ||
import { TaskDefinition } from '../base/task-definition'; | ||
import { ICluster } from '../cluster'; | ||
import { isEc2Compatible } from '../util'; | ||
|
||
/** | ||
* Properties to define an EC2 Event Task | ||
*/ | ||
export interface Ec2EventRuleTargetProps { | ||
/** | ||
* Cluster where service will be deployed | ||
*/ | ||
cluster: ICluster; | ||
|
||
/** | ||
* Task Definition of the task that should be started | ||
*/ | ||
taskDefinition: TaskDefinition; | ||
|
||
/** | ||
* How many tasks should be started when this event is triggered | ||
* | ||
* @default 1 | ||
*/ | ||
taskCount?: number; | ||
} | ||
|
||
/** | ||
* Start a service on an EC2 cluster | ||
*/ | ||
export class Ec2EventRuleTarget extends cdk.Construct implements events.IEventRuleTarget { | ||
private readonly cluster: ICluster; | ||
private readonly taskDefinition: TaskDefinition; | ||
private readonly taskCount: number; | ||
|
||
constructor(scope: cdk.Construct, id: string, props: Ec2EventRuleTargetProps) { | ||
super(scope, id); | ||
|
||
if (!isEc2Compatible(props.taskDefinition.compatibility)) { | ||
throw new Error('Supplied TaskDefinition is not configured for compatibility with EC2'); | ||
} | ||
|
||
this.cluster = props.cluster; | ||
this.taskDefinition = props.taskDefinition; | ||
this.taskCount = props.taskCount !== undefined ? props.taskCount : 1; | ||
} | ||
|
||
/** | ||
* Allows using containers as target of CloudWatch events | ||
*/ | ||
public asEventRuleTarget(_ruleArn: string, _ruleUniqueId: string): events.EventRuleTargetProps { | ||
const role = this.eventsRole; | ||
|
||
role.addToPolicy(new iam.PolicyStatement() | ||
.addAction('ecs:RunTask') | ||
.addResource(this.taskDefinition.taskDefinitionArn) | ||
.addCondition('ArnEquals', { "ecs:cluster": this.cluster.clusterArn })); | ||
|
||
return { | ||
id: this.node.id, | ||
arn: this.cluster.clusterArn, | ||
roleArn: role.roleArn, | ||
ecsParameters: { | ||
taskCount: this.taskCount, | ||
taskDefinitionArn: this.taskDefinition.taskDefinitionArn | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* Create or get the IAM Role used to start this Task Definition. | ||
* | ||
* We create it under the TaskDefinition object so that if we have multiple EventTargets | ||
* they can reuse the same role. | ||
*/ | ||
public get eventsRole(): iam.IRole { | ||
let role = this.taskDefinition.node.tryFindChild('EventsRole') as iam.IRole; | ||
if (role === undefined) { | ||
role = new iam.Role(this.taskDefinition, 'EventsRole', { | ||
assumedBy: new iam.ServicePrincipal('events.amazonaws.com') | ||
}); | ||
} | ||
|
||
return role; | ||
} | ||
|
||
/** | ||
* Prepare the Event Rule Target | ||
*/ | ||
protected prepare() { | ||
// If it so happens that a Task Execution Role was created for the TaskDefinition, | ||
// then the CloudWatch Events Role must have permissions to pass it (otherwise it doesn't). | ||
// | ||
// It never needs permissions to the Task Role. | ||
if (this.taskDefinition.executionRole !== undefined) { | ||
this.taskDefinition.taskRole.grantPassRole(this.eventsRole); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.