@@ -2,7 +2,7 @@ import { Names, Stack, Tags } from 'aws-cdk-lib/core';
22import { Effect , PolicyStatement , ServicePrincipal } from 'aws-cdk-lib/aws-iam' ;
33import * as logs from 'aws-cdk-lib/aws-logs' ;
44import * as s3 from 'aws-cdk-lib/aws-s3' ;
5- import type { IConstruct } from 'constructs' ;
5+ import { Construct , type IConstruct } from 'constructs' ;
66import type { IDeliveryStreamRef } from 'aws-cdk-lib/aws-kinesisfirehose' ;
77import { tryFindBucketPolicyForBucket } from '../../mixins/private/reflections' ;
88import { ConstructSelector , Mixins } from '../../core' ;
@@ -63,7 +63,7 @@ export interface S3LogsDeliveryProps {
6363 * The permissions version ('V1' or 'V2') to be used for this delivery.
6464 * Depending on the source of the logs, different permissions are required.
6565 *
66- * @default "V2
66+ * @default "V2"
6767 */
6868 readonly permissionsVersion ?: S3LogsDeliveryPermissionsVersion ;
6969}
@@ -73,37 +73,42 @@ export interface S3LogsDeliveryProps {
7373 */
7474export class S3LogsDelivery implements ILogsDelivery {
7575 private readonly bucket : s3 . IBucketRef ;
76- private readonly permissions : 'V1' | 'V2' ;
76+ private readonly permissions : S3LogsDeliveryPermissionsVersion ;
7777
7878 /**
7979 * Creates a new S3 Bucket delivery.
8080 */
8181 constructor ( bucket : s3 . IBucketRef , props : S3LogsDeliveryProps = { } ) {
8282 this . bucket = bucket ;
83- this . permissions = props . permissionsVersion ?? 'V2' ;
83+ this . permissions = props . permissionsVersion ?? S3LogsDeliveryPermissionsVersion . V2 ;
8484 }
8585
8686 /**
8787 * Binds the S3 destination to a delivery source and creates a delivery connection between them.
8888 */
8989 public bind ( scope : IConstruct , deliverySource : logs . IDeliverySourceRef , _sourceResourceArn : string ) : ILogsDeliveryConfig {
90- const bucketPolicy = this . getOrCreateBucketPolicy ( scope ) ;
90+ const container = new Construct ( scope , deliveryId ( 'S3' , scope , this . bucket ) ) ;
91+
92+ const bucketPolicy = this . getOrCreateBucketPolicy ( container ) ;
9193 this . grantLogsDelivery ( bucketPolicy ) ;
9294
93- const destinationNamePrefix = 'cdk-s3-dest-' ;
94- const deliveryDestination = new logs . CfnDeliveryDestination ( scope , `CDKS3Dest${ Names . uniqueId ( this . bucket ) } ${ Names . uniqueId ( scope ) } ` , {
95+ const deliveryDestination = new logs . CfnDeliveryDestination ( container , 'Dest' , {
9596 destinationResourceArn : this . bucket . bucketRef . bucketArn ,
96- name : ` ${ destinationNamePrefix } ${ Names . uniqueResourceName ( scope , { maxLength : 60 - destinationNamePrefix . length } ) } ` ,
97+ name : deliveryDestName ( 's3' , container ) ,
9798 deliveryDestinationType : 'S3' ,
9899 } ) ;
99- deliveryDestination . node . addDependency ( bucketPolicy ) ;
100100
101- const delivery = new logs . CfnDelivery ( scope , `CDKS3Delivery ${ Names . uniqueId ( this . bucket ) } ${ Names . uniqueId ( scope ) } ` , {
101+ const delivery = new logs . CfnDelivery ( container , 'Delivery' , {
102102 deliveryDestinationArn : deliveryDestination . attrArn ,
103103 deliverySourceName : deliverySource . deliverySourceRef . deliverySourceName ,
104104 } ) ;
105- delivery . addDependency ( deliveryDestination ) ;
105+
106+ delivery . node . addDependency ( bucketPolicy ) ;
107+ deliveryDestination . node . addDependency ( bucketPolicy ) ;
108+ deliverySource . node . addDependency ( bucketPolicy ) ;
109+
106110 delivery . node . addDependency ( deliverySource ) ;
111+ delivery . node . addDependency ( deliveryDestination ) ;
107112
108113 return {
109114 deliverySource,
@@ -120,7 +125,7 @@ export class S3LogsDelivery implements ILogsDelivery {
120125 private getOrCreateBucketPolicy ( scope : IConstruct ) : s3 . CfnBucketPolicy {
121126 const existingPolicy = tryFindBucketPolicyForBucket ( this . bucket ) ;
122127
123- return existingPolicy ?? new s3 . CfnBucketPolicy ( scope , `CDKS3DestPolicy ${ Names . uniqueId ( this . bucket ) } ` , {
128+ return existingPolicy ?? new s3 . CfnBucketPolicy ( scope , 'BucketPolicy' , {
124129 bucket : this . bucket . bucketRef . bucketName ,
125130 policyDocument : { // needed to create an empty policy document, otherwise a validation error is thrown
126131 Version : '2012-10-17' ,
@@ -195,23 +200,25 @@ export class FirehoseLogsDelivery implements ILogsDelivery {
195200 * Binds the Firehose destination to a delivery source and creates a delivery connection between them.
196201 */
197202 public bind ( scope : IConstruct , deliverySource : logs . IDeliverySourceRef , _sourceResourceArn : string ) : ILogsDeliveryConfig {
203+ const container = new Construct ( scope , deliveryId ( 'Firehose' , scope , this . deliveryStream ) ) ;
204+
198205 // Firehose uses a service-linked role to deliver logs
199206 // This tag marks the destination stream as an allowed destination for the service-linked role
200207 Tags . of ( this . deliveryStream ) . add ( 'LogDeliveryEnabled' , 'true' ) ;
201208
202- const destinationNamePrefix = 'cdk-fh-dest-' ;
203- const deliveryDestination = new logs . CfnDeliveryDestination ( scope , `CDKFHDest${ Names . uniqueId ( this . deliveryStream ) } ${ Names . uniqueId ( scope ) } ` , {
209+ const deliveryDestination = new logs . CfnDeliveryDestination ( container , 'Dest' , {
204210 destinationResourceArn : this . deliveryStream . deliveryStreamRef . deliveryStreamArn ,
205- name : ` ${ destinationNamePrefix } ${ Names . uniqueResourceName ( scope , { maxLength : 60 - destinationNamePrefix . length } ) } ` ,
211+ name : deliveryDestName ( 'fh' , container ) ,
206212 deliveryDestinationType : 'FH' ,
207213 } ) ;
208214
209- const delivery = new logs . CfnDelivery ( scope , `CDKFHDelivery ${ Names . uniqueId ( this . deliveryStream ) } ${ Names . uniqueId ( scope ) } ` , {
215+ const delivery = new logs . CfnDelivery ( container , 'Delivery' , {
210216 deliveryDestinationArn : deliveryDestination . attrArn ,
211217 deliverySourceName : deliverySource . deliverySourceRef . deliverySourceName ,
212218 } ) ;
213- delivery . addDependency ( deliveryDestination ) ;
219+
214220 delivery . node . addDependency ( deliverySource ) ;
221+ delivery . node . addDependency ( deliveryDestination ) ;
215222
216223 return {
217224 deliverySource,
@@ -239,23 +246,28 @@ export class LogGroupLogsDelivery implements ILogsDelivery {
239246 * Binds the log group destination to a delivery source and creates a delivery connection between them.
240247 */
241248 public bind ( scope : IConstruct , deliverySource : logs . IDeliverySourceRef , _sourceResourceArn : string ) : ILogsDeliveryConfig {
242- const logGroupPolicy = this . getOrCreateLogsResourcePolicy ( scope ) ;
249+ const container = new Construct ( scope , deliveryId ( 'LogGroup' , scope , this . logGroup ) ) ;
250+
251+ const logGroupPolicy = this . getOrCreateLogsResourcePolicy ( container ) ;
243252 this . grantLogsDelivery ( logGroupPolicy ) ;
244253
245- const destinationNamePrefix = 'cdk-cwl-dest-' ;
246- const deliveryDestination = new logs . CfnDeliveryDestination ( scope , `CDKCWLDest${ Names . uniqueId ( this . logGroup ) } ${ Names . uniqueId ( scope ) } ` , {
254+ const deliveryDestination = new logs . CfnDeliveryDestination ( container , 'Dest' , {
247255 destinationResourceArn : this . logGroup . logGroupRef . logGroupArn ,
248- name : ` ${ destinationNamePrefix } ${ Names . uniqueResourceName ( scope , { maxLength : 60 - destinationNamePrefix . length } ) } ` ,
256+ name : deliveryDestName ( 'cwl' , container ) ,
249257 deliveryDestinationType : 'CWL' ,
250258 } ) ;
251- deliveryDestination . node . addDependency ( logGroupPolicy ) ;
252259
253- const delivery = new logs . CfnDelivery ( scope , `CDKCWLDelivery ${ Names . uniqueId ( this . logGroup ) } ${ Names . uniqueId ( scope ) } ` , {
254- deliveryDestinationArn : deliveryDestination . attrArn ,
260+ const delivery = new logs . CfnDelivery ( container , 'Delivery' , {
261+ deliveryDestinationArn : deliveryDestination . deliveryDestinationRef . deliveryDestinationArn ,
255262 deliverySourceName : deliverySource . deliverySourceRef . deliverySourceName ,
256263 } ) ;
257- delivery . addDependency ( deliveryDestination ) ;
264+
265+ delivery . node . addDependency ( logGroupPolicy ) ;
258266 delivery . node . addDependency ( deliverySource ) ;
267+ delivery . node . addDependency ( deliveryDestination ) ;
268+
269+ deliverySource . node . addDependency ( logGroupPolicy ) ;
270+ deliveryDestination . node . addDependency ( logGroupPolicy ) ;
259271
260272 return {
261273 deliverySource,
@@ -271,13 +283,13 @@ export class LogGroupLogsDelivery implements ILogsDelivery {
271283 */
272284 private getOrCreateLogsResourcePolicy ( scope : IConstruct ) : logs . ResourcePolicy {
273285 const stack = Stack . of ( scope ) ;
274- const policyId = 'CDKCWLDestPolicy ' ;
286+ const policyId = 'CdkLogGroupLogsDeliveryPolicy ' ;
275287
276288 // Singleton policy per stack
277289 const existingPolicy = stack . node . tryFindChild ( policyId ) as logs . ResourcePolicy ;
278290
279291 return existingPolicy ?? new logs . ResourcePolicy ( stack , policyId , {
280- resourcePolicyName : 'LogGroupLogsDeliveryPolicy' ,
292+ resourcePolicyName : Names . uniqueResourceName ( scope , { maxLength : 255 } ) ,
281293 } ) ;
282294 }
283295
@@ -318,21 +330,27 @@ export class XRayLogsDelivery implements ILogsDelivery {
318330 * Binds the X-Ray destination to a delivery source and creates a delivery connection between them.
319331 */
320332 public bind ( scope : IConstruct , deliverySource : logs . IDeliverySourceRef , sourceResourceArn : string ) : ILogsDeliveryConfig {
321- const xrayResourcePolicy = this . getOrCreateResourcePolicy ( scope ) ;
333+ const container = new Construct ( scope , deliveryId ( 'XRay' , scope , deliverySource ) ) ;
334+
335+ const xrayResourcePolicy = this . getOrCreateResourcePolicy ( container ) ;
322336 this . grantLogsDelivery ( xrayResourcePolicy , sourceResourceArn ) ;
323337
324- const destinationNamePrefix = 'cdk-xray-dest-' ;
325- const deliveryDestination = new logs . CfnDeliveryDestination ( scope , `CDKXRayDest${ Names . uniqueId ( scope ) } ` , {
326- name : `${ destinationNamePrefix } ${ Names . uniqueResourceName ( scope , { maxLength : 60 - destinationNamePrefix . length } ) } ` ,
338+ const deliveryDestination = new logs . CfnDeliveryDestination ( container , 'Dest' , {
339+ name : deliveryDestName ( 'xray' , container ) ,
327340 deliveryDestinationType : 'XRAY' ,
328341 } ) ;
329342
330- const delivery = new logs . CfnDelivery ( scope , `CDKXRAYDelivery ${ Names . uniqueId ( scope ) } ` , {
343+ const delivery = new logs . CfnDelivery ( container , 'Delivery' , {
331344 deliveryDestinationArn : deliveryDestination . attrArn ,
332345 deliverySourceName : deliverySource . deliverySourceRef . deliverySourceName ,
333346 } ) ;
334- delivery . addDependency ( deliveryDestination ) ;
347+
348+ delivery . node . addDependency ( xrayResourcePolicy ) ;
349+ deliveryDestination . node . addDependency ( xrayResourcePolicy ) ;
350+ deliverySource . node . addDependency ( xrayResourcePolicy ) ;
351+
335352 delivery . node . addDependency ( deliverySource ) ;
353+ delivery . node . addDependency ( deliveryDestination ) ;
336354
337355 return {
338356 deliverySource,
@@ -349,14 +367,12 @@ export class XRayLogsDelivery implements ILogsDelivery {
349367 */
350368 private getOrCreateResourcePolicy ( scope : IConstruct ) : xray . ResourcePolicy {
351369 const stack = Stack . of ( scope ) ;
352- const policyId = 'CDKXRAYDestPolicy ' ;
370+ const policyId = 'CdkXRayLogsDeliveryPolicy ' ;
353371
354372 // Singleton policy per stack
355373 const existingPolicy = stack . node . tryFindChild ( policyId ) as xray . ResourcePolicy ;
356374
357- return existingPolicy ?? new xray . ResourcePolicy ( stack , policyId , {
358- resourcePolicyName : 'XRayLogsDeliveryPolicy' ,
359- } ) ;
375+ return existingPolicy ?? new xray . ResourcePolicy ( stack , policyId ) ;
360376 }
361377
362378 /**
@@ -386,3 +402,12 @@ export class XRayLogsDelivery implements ILogsDelivery {
386402 } ) ) ;
387403 }
388404}
405+
406+ function deliveryId ( type : string , ...scopes : IConstruct [ ] ) {
407+ return `Cdk${ type } Delivery${ scopes . map ( s => Names . uniqueId ( s ) ) . join ( '' ) } ` ;
408+ }
409+
410+ function deliveryDestName ( type : string , scope : IConstruct ) {
411+ const prefix = `cdk-${ type } -dest-` ;
412+ return `${ prefix } ${ Names . uniqueResourceName ( scope , { maxLength : 60 - prefix . length } ) } ` ;
413+ }
0 commit comments