@@ -99,6 +99,41 @@ class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
9999 }
100100}
101101
102+ /**
103+ * Represents a group of instance tags.
104+ * An instance will match a group if it has a tag matching
105+ * any of the group's tags by key and any of the provided values -
106+ * in other words, tag groups follow 'or' semantics.
107+ * If the value for a given key is an empty array,
108+ * an instance will match when it has a tag with the given key,
109+ * regardless of the value.
110+ * If the key is an empty string, any tag,
111+ * regardless of its key, with any of the given values, will match.
112+ */
113+ export type InstanceTagGroup = { [ key : string ] : string [ ] } ;
114+
115+ /**
116+ * Represents a set of instance tag groups.
117+ * An instance will match a set if it matches all of the groups in the set -
118+ * in other words, sets follow 'and' semantics.
119+ * You can have a maximum of 3 tag groups inside a set.
120+ */
121+ export class InstanceTagSet {
122+ private readonly _instanceTagGroups : InstanceTagGroup [ ] ;
123+
124+ constructor ( ...instanceTagGroups : InstanceTagGroup [ ] ) {
125+ if ( instanceTagGroups . length > 3 ) {
126+ throw new Error ( 'An instance tag set can have a maximum of 3 instance tag groups, ' +
127+ `but ${ instanceTagGroups . length } were provided` ) ;
128+ }
129+ this . _instanceTagGroups = instanceTagGroups ;
130+ }
131+
132+ public get instanceTagGroups ( ) : InstanceTagGroup [ ] {
133+ return this . _instanceTagGroups . slice ( ) ;
134+ }
135+ }
136+
102137/**
103138 * Construction properties for {@link ServerDeploymentGroup}.
104139 */
@@ -153,6 +188,20 @@ export interface ServerDeploymentGroupProps {
153188 * @default the Deployment Group will not have a load balancer defined
154189 */
155190 loadBalancer ?: codedeploylb . ILoadBalancer ;
191+
192+ /*
193+ * All EC2 instances matching the given set of tags when a deployment occurs will be added to this Deployment Group.
194+ *
195+ * @default no additional EC2 instances will be added to the Deployment Group
196+ */
197+ ec2InstanceTags ?: InstanceTagSet ;
198+
199+ /**
200+ * All on-premise instances matching the given set of tags when a deployment occurs will be added to this Deployment Group.
201+ *
202+ * @default no additional on-premise instances will be added to the Deployment Group
203+ */
204+ onPremiseInstanceTags ?: InstanceTagSet ;
156205}
157206
158207/**
@@ -204,6 +253,8 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
204253 : {
205254 deploymentOption : 'WITH_TRAFFIC_CONTROL' ,
206255 } ,
256+ ec2TagSet : this . ec2TagSet ( props . ec2InstanceTags ) ,
257+ onPremisesTagSet : this . onPremiseTagSet ( props . onPremiseInstanceTags ) ,
207258 } ) ;
208259
209260 this . deploymentGroupName = resource . deploymentGroupName ;
@@ -284,6 +335,75 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
284335 } ;
285336 }
286337 }
338+
339+ private ec2TagSet ( tagSet ?: InstanceTagSet ) :
340+ cloudformation . DeploymentGroupResource . EC2TagSetProperty | undefined {
341+ if ( ! tagSet || tagSet . instanceTagGroups . length === 0 ) {
342+ return undefined ;
343+ }
344+
345+ return {
346+ ec2TagSetList : tagSet . instanceTagGroups . map ( tagGroup => {
347+ return {
348+ ec2TagGroup : this . tagGroup2TagsArray ( tagGroup ) as
349+ cloudformation . DeploymentGroupResource . EC2TagFilterProperty [ ] ,
350+ } ;
351+ } ) ,
352+ } ;
353+ }
354+
355+ private onPremiseTagSet ( tagSet ?: InstanceTagSet ) :
356+ cloudformation . DeploymentGroupResource . OnPremisesTagSetProperty | undefined {
357+ if ( ! tagSet || tagSet . instanceTagGroups . length === 0 ) {
358+ return undefined ;
359+ }
360+
361+ return {
362+ onPremisesTagSetList : tagSet . instanceTagGroups . map ( tagGroup => {
363+ return {
364+ onPremisesTagGroup : this . tagGroup2TagsArray ( tagGroup ) as
365+ cloudformation . DeploymentGroupResource . TagFilterProperty [ ] ,
366+ } ;
367+ } ) ,
368+ } ;
369+ }
370+
371+ private tagGroup2TagsArray ( tagGroup : InstanceTagGroup ) : any [ ] {
372+ const tagsInGroup = [ ] ;
373+ for ( const tagKey in tagGroup ) {
374+ if ( tagGroup . hasOwnProperty ( tagKey ) ) {
375+ const tagValues = tagGroup [ tagKey ] ;
376+ if ( tagKey . length > 0 ) {
377+ if ( tagValues . length > 0 ) {
378+ for ( const tagValue of tagValues ) {
379+ tagsInGroup . push ( {
380+ key : tagKey ,
381+ value : tagValue ,
382+ type : 'KEY_AND_VALUE' ,
383+ } ) ;
384+ }
385+ } else {
386+ tagsInGroup . push ( {
387+ key : tagKey ,
388+ type : 'KEY_ONLY' ,
389+ } ) ;
390+ }
391+ } else {
392+ if ( tagValues . length > 0 ) {
393+ for ( const tagValue of tagValues ) {
394+ tagsInGroup . push ( {
395+ value : tagValue ,
396+ type : 'VALUE_ONLY' ,
397+ } ) ;
398+ }
399+ } else {
400+ throw new Error ( 'Cannot specify both an empty key and no values for an instance tag filter' ) ;
401+ }
402+ }
403+ }
404+ }
405+ return tagsInGroup ;
406+ }
287407}
288408
289409function deploymentGroupName2Arn ( applicationName : string , deploymentGroupName : string ) : string {
0 commit comments