1
+ import events = require ( '@aws-cdk/aws-events' ) ;
2
+ import iam = require( '@aws-cdk/aws-iam' ) ;
3
+ import cdk = require( '@aws-cdk/cdk' ) ;
4
+ import { TaskDefinition } from '../base/task-definition' ;
5
+ import { ICluster } from '../cluster' ;
6
+ import { isEc2Compatible } from '../util' ;
7
+
8
+ /**
9
+ * Properties to define an EC2 Event Task
10
+ */
11
+ export interface Ec2EventRuleTargetProps {
12
+ /**
13
+ * Cluster where service will be deployed
14
+ */
15
+ cluster : ICluster ;
16
+
17
+ /**
18
+ * Task Definition of the task that should be started
19
+ */
20
+ taskDefinition : TaskDefinition ;
21
+
22
+ /**
23
+ * How many tasks should be started when this event is triggered
24
+ *
25
+ * @default 1
26
+ */
27
+ taskCount ?: number ;
28
+ }
29
+
30
+ /**
31
+ * Start a service on an EC2 cluster
32
+ */
33
+ export class Ec2EventRuleTarget extends cdk . Construct implements events . IEventRuleTarget {
34
+ private readonly cluster : ICluster ;
35
+ private readonly taskDefinition : TaskDefinition ;
36
+ private readonly taskCount : number ;
37
+
38
+ constructor ( scope : cdk . Construct , id : string , props : Ec2EventRuleTargetProps ) {
39
+ super ( scope , id ) ;
40
+
41
+ if ( ! isEc2Compatible ( props . taskDefinition . compatibility ) ) {
42
+ throw new Error ( 'Supplied TaskDefinition is not configured for compatibility with EC2' ) ;
43
+ }
44
+
45
+ this . cluster = props . cluster ;
46
+ this . taskDefinition = props . taskDefinition ;
47
+ this . taskCount = props . taskCount !== undefined ? props . taskCount : 1 ;
48
+ }
49
+
50
+ /**
51
+ * Allows using containers as target of CloudWatch events
52
+ */
53
+ public asEventRuleTarget ( _ruleArn : string , _ruleUniqueId : string ) : events . EventRuleTargetProps {
54
+ const role = this . eventsRole ;
55
+
56
+ role . addToPolicy ( new iam . PolicyStatement ( )
57
+ . addAction ( 'ecs:RunTask' )
58
+ . addResource ( this . taskDefinition . taskDefinitionArn )
59
+ . addCondition ( 'ArnEquals' , { "ecs:cluster" : this . cluster . clusterArn } ) ) ;
60
+
61
+ return {
62
+ id : this . node . id ,
63
+ arn : this . cluster . clusterArn ,
64
+ roleArn : role . roleArn ,
65
+ ecsParameters : {
66
+ taskCount : this . taskCount ,
67
+ taskDefinitionArn : this . taskDefinition . taskDefinitionArn
68
+ }
69
+ } ;
70
+ }
71
+
72
+ /**
73
+ * Create or get the IAM Role used to start this Task Definition.
74
+ *
75
+ * We create it under the TaskDefinition object so that if we have multiple EventTargets
76
+ * they can reuse the same role.
77
+ */
78
+ public get eventsRole ( ) : iam . IRole {
79
+ let role = this . taskDefinition . node . tryFindChild ( 'EventsRole' ) as iam . IRole ;
80
+ if ( role === undefined ) {
81
+ role = new iam . Role ( this . taskDefinition , 'EventsRole' , {
82
+ assumedBy : new iam . ServicePrincipal ( 'events.amazonaws.com' )
83
+ } ) ;
84
+ }
85
+
86
+ return role ;
87
+ }
88
+
89
+ /**
90
+ * Prepare the Event Rule Target
91
+ */
92
+ protected prepare ( ) {
93
+ // If it so happens that a Task Execution Role was created for the TaskDefinition,
94
+ // then the CloudWatch Events Role must have permissions to pass it (otherwise it doesn't).
95
+ //
96
+ // It never needs permissions to the Task Role.
97
+ if ( this . taskDefinition . executionRole !== undefined ) {
98
+ this . taskDefinition . taskRole . grantPassRole ( this . eventsRole ) ;
99
+ }
100
+ }
101
+ }
0 commit comments