1
+ import { EOL } from 'os' ;
1
2
import * as events from '@aws-cdk/aws-events' ;
2
3
import * as iam from '@aws-cdk/aws-iam' ;
3
4
import * as kms from '@aws-cdk/aws-kms' ;
4
5
import { Construct , Fn , IResource , Lazy , RemovalPolicy , Resource , Stack , Token } from '@aws-cdk/core' ;
5
- import { EOL } from 'os' ;
6
6
import { BucketPolicy } from './bucket-policy' ;
7
7
import { IBucketNotificationDestination } from './destination' ;
8
8
import { BucketNotifications } from './notifications-resource' ;
@@ -828,6 +828,130 @@ export interface RedirectTarget {
828
828
readonly protocol ?: RedirectProtocol ;
829
829
}
830
830
831
+ /**
832
+ * All supported inventory list formats.
833
+ */
834
+ export enum InventoryFormat {
835
+ /**
836
+ * Generate the inventory list as CSV.
837
+ */
838
+ CSV = 'CSV' ,
839
+ /**
840
+ * Generate the inventory list as Parquet.
841
+ */
842
+ PARQUET = 'Parquet' ,
843
+ /**
844
+ * Generate the inventory list as Parquet.
845
+ */
846
+ ORC = 'ORC' ,
847
+ }
848
+
849
+ /**
850
+ * All supported inventory frequencies.
851
+ */
852
+ export enum InventoryFrequency {
853
+ /**
854
+ * A report is generated every day.
855
+ */
856
+ DAILY = 'Daily' ,
857
+ /**
858
+ * A report is generated every Sunday (UTC timezone) after the initial report.
859
+ */
860
+ WEEKLY = 'Weekly'
861
+ }
862
+
863
+ /**
864
+ * Inventory version support.
865
+ */
866
+ export enum InventoryObjectVersion {
867
+ /**
868
+ * Includes all versions of each object in the report.
869
+ */
870
+ ALL = 'All' ,
871
+ /**
872
+ * Includes only the current version of each object in the report.
873
+ */
874
+ CURRENT = 'Current' ,
875
+ }
876
+
877
+ /**
878
+ * The destination of the inventory.
879
+ */
880
+ export interface InventoryDestination {
881
+ /**
882
+ * Bucket where all inventories will be saved in.
883
+ */
884
+ readonly bucket : IBucket ;
885
+ /**
886
+ * The prefix to be used when saving the inventory.
887
+ *
888
+ * @default - No prefix.
889
+ */
890
+ readonly prefix ?: string ;
891
+ /**
892
+ * The account ID that owns the destination S3 bucket.
893
+ * If no account ID is provided, the owner is not validated before exporting data.
894
+ * It's recommended to set an account ID to prevent problems if the destination bucket ownership changes.
895
+ *
896
+ * @default - No account ID.
897
+ */
898
+ readonly bucketOwner ?: string ;
899
+ }
900
+
901
+ /**
902
+ * Specifies the inventory configuration of an S3 Bucket.
903
+ *
904
+ * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html
905
+ */
906
+ export interface Inventory {
907
+ /**
908
+ * The destination of the inventory.
909
+ */
910
+ readonly destination : InventoryDestination ;
911
+ /**
912
+ * The inventory will only include objects that meet the prefix filter criteria.
913
+ *
914
+ * @default - No objects prefix
915
+ */
916
+ readonly objectsPrefix ?: string ;
917
+ /**
918
+ * The format of the inventory.
919
+ *
920
+ * @default InventoryFormat.CSV
921
+ */
922
+ readonly format ?: InventoryFormat ;
923
+ /**
924
+ * Whether the inventory is enabled or disabled.
925
+ *
926
+ * @default true
927
+ */
928
+ readonly enabled ?: boolean ;
929
+ /**
930
+ * The inventory configuration ID.
931
+ *
932
+ * @default - generated ID.
933
+ */
934
+ readonly inventoryId ?: string ;
935
+ /**
936
+ * Frequency at which the inventory should be generated.
937
+ *
938
+ * @default InventoryFrequency.WEEKLY
939
+ */
940
+ readonly frequency ?: InventoryFrequency ;
941
+ /**
942
+ * If the inventory should contain all the object versions or only the current one.
943
+ *
944
+ * @default InventoryObjectVersion.ALL
945
+ */
946
+ readonly includeObjectVersions ?: InventoryObjectVersion ;
947
+ /**
948
+ * A list of optional fields to be included in the inventory result.
949
+ *
950
+ * @default - No optional fields.
951
+ */
952
+ readonly optionalFields ?: string [ ] ;
953
+ }
954
+
831
955
export interface BucketProps {
832
956
/**
833
957
* The kind of server-side encryption to apply to this bucket.
@@ -966,6 +1090,15 @@ export interface BucketProps {
966
1090
* @default - No log file prefix
967
1091
*/
968
1092
readonly serverAccessLogsPrefix ?: string ;
1093
+
1094
+ /**
1095
+ * The inventory configuration of the bucket.
1096
+ *
1097
+ * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html
1098
+ *
1099
+ * @default - No inventory configuration
1100
+ */
1101
+ readonly inventories ?: Inventory [ ] ;
969
1102
}
970
1103
971
1104
/**
@@ -1055,6 +1188,7 @@ export class Bucket extends BucketBase {
1055
1188
private readonly notifications : BucketNotifications ;
1056
1189
private readonly metrics : BucketMetrics [ ] = [ ] ;
1057
1190
private readonly cors : CorsRule [ ] = [ ] ;
1191
+ private readonly inventories : Inventory [ ] = [ ] ;
1058
1192
1059
1193
constructor ( scope : Construct , id : string , props : BucketProps = { } ) {
1060
1194
super ( scope , id , {
@@ -1079,6 +1213,7 @@ export class Bucket extends BucketBase {
1079
1213
corsConfiguration : Lazy . anyValue ( { produce : ( ) => this . parseCorsConfiguration ( ) } ) ,
1080
1214
accessControl : Lazy . stringValue ( { produce : ( ) => this . accessControl } ) ,
1081
1215
loggingConfiguration : this . parseServerAccessLogs ( props ) ,
1216
+ inventoryConfigurations : Lazy . anyValue ( { produce : ( ) => this . parseInventoryConfiguration ( ) } ) ,
1082
1217
} ) ;
1083
1218
1084
1219
resource . applyRemovalPolicy ( props . removalPolicy ) ;
@@ -1107,6 +1242,10 @@ export class Bucket extends BucketBase {
1107
1242
props . serverAccessLogsBucket . allowLogDelivery ( ) ;
1108
1243
}
1109
1244
1245
+ for ( const inventory of props . inventories ?? [ ] ) {
1246
+ this . addInventory ( inventory ) ;
1247
+ }
1248
+
1110
1249
// Add all bucket metric configurations rules
1111
1250
( props . metrics || [ ] ) . forEach ( this . addMetric . bind ( this ) ) ;
1112
1251
// Add all cors configuration rules
@@ -1204,6 +1343,15 @@ export class Bucket extends BucketBase {
1204
1343
return this . addEventNotification ( EventType . OBJECT_REMOVED , dest , ...filters ) ;
1205
1344
}
1206
1345
1346
+ /**
1347
+ * Add an inventory configuration.
1348
+ *
1349
+ * @param inventory configuration to add
1350
+ */
1351
+ public addInventory ( inventory : Inventory ) : void {
1352
+ this . inventories . push ( inventory ) ;
1353
+ }
1354
+
1207
1355
private validateBucketName ( physicalName : string ) : void {
1208
1356
const bucketName = physicalName ;
1209
1357
if ( ! bucketName || Token . isUnresolved ( bucketName ) ) {
@@ -1460,6 +1608,50 @@ export class Bucket extends BucketBase {
1460
1608
1461
1609
this . accessControl = BucketAccessControl . LOG_DELIVERY_WRITE ;
1462
1610
}
1611
+
1612
+ private parseInventoryConfiguration ( ) : CfnBucket . InventoryConfigurationProperty [ ] | undefined {
1613
+ if ( ! this . inventories || this . inventories . length === 0 ) {
1614
+ return undefined ;
1615
+ }
1616
+
1617
+ return this . inventories . map ( ( inventory , index ) => {
1618
+ const format = inventory . format ?? InventoryFormat . CSV ;
1619
+ const frequency = inventory . frequency ?? InventoryFrequency . WEEKLY ;
1620
+ const id = inventory . inventoryId ?? `${ this . node . id } Inventory${ index } ` ;
1621
+
1622
+ if ( inventory . destination . bucket instanceof Bucket ) {
1623
+ inventory . destination . bucket . addToResourcePolicy ( new iam . PolicyStatement ( {
1624
+ effect : iam . Effect . ALLOW ,
1625
+ actions : [ 's3:PutObject' ] ,
1626
+ resources : [
1627
+ inventory . destination . bucket . bucketArn ,
1628
+ inventory . destination . bucket . arnForObjects ( `${ inventory . destination . prefix ?? '' } *` ) ,
1629
+ ] ,
1630
+ principals : [ new iam . ServicePrincipal ( 's3.amazonaws.com' ) ] ,
1631
+ conditions : {
1632
+ ArnLike : {
1633
+ 'aws:SourceArn' : this . bucketArn ,
1634
+ } ,
1635
+ } ,
1636
+ } ) ) ;
1637
+ }
1638
+
1639
+ return {
1640
+ id,
1641
+ destination : {
1642
+ bucketArn : inventory . destination . bucket . bucketArn ,
1643
+ bucketAccountId : inventory . destination . bucketOwner ,
1644
+ prefix : inventory . destination . prefix ,
1645
+ format,
1646
+ } ,
1647
+ enabled : inventory . enabled ?? true ,
1648
+ includedObjectVersions : inventory . includeObjectVersions ?? InventoryObjectVersion . ALL ,
1649
+ scheduleFrequency : frequency ,
1650
+ optionalFields : inventory . optionalFields ,
1651
+ prefix : inventory . objectsPrefix ,
1652
+ } ;
1653
+ } ) ;
1654
+ }
1463
1655
}
1464
1656
1465
1657
/**
0 commit comments