From 3b95777ee5dae32fd41481d81922d07c804a2c6b Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Sat, 22 Jun 2024 08:43:11 +0900 Subject: [PATCH] feat(fsx): add properties to enable automatic backups for Lustre file system (#30343) ### Issue # (if applicable) Closes #30340. ### Reason for this change Current LustreFileSystem class does not support automatic backups. ### Description of changes Add properties equivalent to those of the L1 construct to the L2 construct. * [automaticBackupRetentionDays](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws%5C_fsx.CfnFileSystem.LustreConfigurationProperty.html#automaticbackupretentiondays) * [copyTagsToBackups](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws%5C_fsx.CfnFileSystem.LustreConfigurationProperty.html#copytagstobackups) * [dailyAutomaticBackupStartTime](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws%5C_fsx.CfnFileSystem.LustreConfigurationProperty.html#dailyautomaticbackupstarttime) Segregated the `dailyAutomaticBackupStartTime` as a class to enable its usage in another file system's L2 construct (for example, Ontap) in the future. ### Description of how you validated changes Add unit tests and integ tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...AwsCdkFsxLustreAutomaticBackup.assets.json | 19 + ...sCdkFsxLustreAutomaticBackup.template.json | 495 ++++++++++ ...efaultTestDeployAssertBED7F3F4.assets.json | 19 + ...aultTestDeployAssertBED7F3F4.template.json | 36 + .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 263 ++++++ .../tree.json | 860 ++++++++++++++++++ ...teg.lustre-file-system-automatic-backup.ts | 31 + packages/aws-cdk-lib/aws-fsx/README.md | 23 +- .../lib/daily-automatic-backup-start-time.ts | 68 ++ packages/aws-cdk-lib/aws-fsx/lib/index.ts | 1 + .../aws-fsx/lib/lustre-file-system.ts | 67 +- .../daily-automatic-backup-start-time.test.ts | 32 + .../aws-fsx/test/lustre-file-system.test.ts | 115 ++- 15 files changed, 2038 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.ts create mode 100644 packages/aws-cdk-lib/aws-fsx/lib/daily-automatic-backup-start-time.ts create mode 100644 packages/aws-cdk-lib/aws-fsx/test/daily-automatic-backup-start-time.test.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.assets.json new file mode 100644 index 0000000000000..cbb3ade1a4e5a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "31f8e9075d8feba06c277f36abd194ec9372fb7253f0b1e3cbe4f4779bc0a868": { + "source": { + "path": "AwsCdkFsxLustreAutomaticBackup.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "31f8e9075d8feba06c277f36abd194ec9372fb7253f0b1e3cbe4f4779bc0a868.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.template.json new file mode 100644 index 0000000000000..bd9ed66f90073 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/AwsCdkFsxLustreAutomaticBackup.template.json @@ -0,0 +1,495 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC" + ] + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "AwsCdkFsxLustreAutomaticBackup/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "FsxLustreFileSystemFsxLustreSecurityGroupfromAwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF69881023BADAE36E": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "Description": "from AwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF6:988-1023", + "FromPort": 988, + "GroupId": { + "Fn::GetAtt": [ + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7", + "GroupId" + ] + }, + "IpProtocol": "tcp", + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7", + "GroupId" + ] + }, + "ToPort": 1023 + } + }, + "FsxLustreFileSystem1F786378": { + "Type": "AWS::FSx::FileSystem", + "Properties": { + "FileSystemType": "LUSTRE", + "LustreConfiguration": { + "AutomaticBackupRetentionDays": 3, + "CopyTagsToBackups": true, + "DailyAutomaticBackupStartTime": "11:30", + "DeploymentType": "PERSISTENT_1", + "PerUnitStorageThroughput": 100 + }, + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7", + "GroupId" + ] + } + ], + "StorageCapacity": 1200, + "SubnetIds": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets.json new file mode 100644 index 0000000000000..015a5d137b850 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/integ.json new file mode 100644 index 0000000000000..6b146aeea3040 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "FsxLustreAutomaticBackup/DefaultTest": { + "stacks": [ + "AwsCdkFsxLustreAutomaticBackup" + ], + "assertionStack": "FsxLustreAutomaticBackup/DefaultTest/DeployAssert", + "assertionStackName": "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/manifest.json new file mode 100644 index 0000000000000..74568c501d3c3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/manifest.json @@ -0,0 +1,263 @@ +{ + "version": "36.0.0", + "artifacts": { + "AwsCdkFsxLustreAutomaticBackup.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "AwsCdkFsxLustreAutomaticBackup.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "AwsCdkFsxLustreAutomaticBackup": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "AwsCdkFsxLustreAutomaticBackup.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/31f8e9075d8feba06c277f36abd194ec9372fb7253f0b1e3cbe4f4779bc0a868.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "AwsCdkFsxLustreAutomaticBackup.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "AwsCdkFsxLustreAutomaticBackup.assets" + ], + "metadata": { + "/AwsCdkFsxLustreAutomaticBackup/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2EIP4947BC00" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2NATGateway3C070193" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup/from AwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF6:988-1023": [ + { + "type": "aws:cdk:logicalId", + "data": "FsxLustreFileSystemFsxLustreSecurityGroupfromAwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF69881023BADAE36E" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "FsxLustreFileSystem1F786378" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/AwsCdkFsxLustreAutomaticBackup/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "AwsCdkFsxLustreAutomaticBackup" + }, + "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "FsxLustreAutomaticBackupDefaultTestDeployAssertBED7F3F4.assets" + ], + "metadata": { + "/FsxLustreAutomaticBackup/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/FsxLustreAutomaticBackup/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "FsxLustreAutomaticBackup/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/tree.json new file mode 100644 index 0000000000000..98aac09675ab6 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.js.snapshot/tree.json @@ -0,0 +1,860 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "AwsCdkFsxLustreAutomaticBackup": { + "id": "AwsCdkFsxLustreAutomaticBackup", + "path": "AwsCdkFsxLustreAutomaticBackup", + "children": { + "VPC": { + "id": "VPC", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "AwsCdkFsxLustreAutomaticBackup/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "AwsCdkFsxLustreAutomaticBackup/VPC/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.Vpc", + "version": "0.0.0" + } + }, + "FsxLustreFileSystem": { + "id": "FsxLustreFileSystem", + "path": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem", + "children": { + "FsxLustreSecurityGroup": { + "id": "FsxLustreSecurityGroup", + "path": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "0.0.0" + } + }, + "from AwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF6:988-1023": { + "id": "from AwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF6:988-1023", + "path": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/FsxLustreSecurityGroup/from AwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF6:988-1023", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroupIngress", + "aws:cdk:cloudformation:props": { + "description": "from AwsCdkFsxLustreAutomaticBackupFsxLustreFileSystemFsxLustreSecurityGroupD80F0EF6:988-1023", + "fromPort": 988, + "groupId": { + "Fn::GetAtt": [ + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7", + "GroupId" + ] + }, + "ipProtocol": "tcp", + "sourceSecurityGroupId": { + "Fn::GetAtt": [ + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7", + "GroupId" + ] + }, + "toPort": 1023 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroupIngress", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "AwsCdkFsxLustreAutomaticBackup/FsxLustreFileSystem/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::FSx::FileSystem", + "aws:cdk:cloudformation:props": { + "fileSystemType": "LUSTRE", + "lustreConfiguration": { + "deploymentType": "PERSISTENT_1", + "perUnitStorageThroughput": 100, + "automaticBackupRetention": { + "amount": 3, + "unit": { + "label": "days", + "isoLabel": "D", + "inMillis": 86400000 + } + }, + "copyTagsToBackups": true, + "dailyAutomaticBackupStartTime": "11:30", + "automaticBackupRetentionDays": 3 + }, + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "FsxLustreFileSystemFsxLustreSecurityGroup1C661EA7", + "GroupId" + ] + } + ], + "storageCapacity": 1200, + "subnetIds": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_fsx.CfnFileSystem", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_fsx.LustreFileSystem", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "AwsCdkFsxLustreAutomaticBackup/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "AwsCdkFsxLustreAutomaticBackup/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "FsxLustreAutomaticBackup": { + "id": "FsxLustreAutomaticBackup", + "path": "FsxLustreAutomaticBackup", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "FsxLustreAutomaticBackup/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "FsxLustreAutomaticBackup/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "FsxLustreAutomaticBackup/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "FsxLustreAutomaticBackup/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "FsxLustreAutomaticBackup/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.ts new file mode 100644 index 0000000000000..125117fbb6320 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-fsx/test/integ.lustre-file-system-automatic-backup.ts @@ -0,0 +1,31 @@ +import { Vpc } from 'aws-cdk-lib/aws-ec2'; +import { App, Duration, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import { LustreDeploymentType, LustreFileSystem, DailyAutomaticBackupStartTime } from 'aws-cdk-lib/aws-fsx'; + +const app = new App(); + +const stack = new Stack(app, 'AwsCdkFsxLustreAutomaticBackup'); + +const vpc = new Vpc(stack, 'VPC', { restrictDefaultSecurityGroup: false }); + +const storageCapacity = 1200; +const lustreConfiguration = { + deploymentType: LustreDeploymentType.PERSISTENT_1, + perUnitStorageThroughput: 100, + automaticBackupRetention: Duration.days(3), + copyTagsToBackups: true, + dailyAutomaticBackupStartTime: new DailyAutomaticBackupStartTime({ hour: 11, minute: 30 }), +}; + +new LustreFileSystem(stack, 'FsxLustreFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet: vpc.privateSubnets[0], + removalPolicy: RemovalPolicy.DESTROY, +}); + +new integ.IntegTest(app, 'FsxLustreAutomaticBackup', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-fsx/README.md b/packages/aws-cdk-lib/aws-fsx/README.md index 373d3753e74c3..61cd2951ef22b 100644 --- a/packages/aws-cdk-lib/aws-fsx/README.md +++ b/packages/aws-cdk-lib/aws-fsx/README.md @@ -194,7 +194,28 @@ const lustreConfiguration = { } ``` -When you turn data compression on for an existing file system, only newly written files are compressed. Existing files are not compressed. For more information, see [Compressing previously written files](https://docs.aws.amazon.com/fsx/latest/LustreGuide/data-compression.html#migrate-compression).``` +When you turn data compression on for an existing file system, only newly written files are compressed. Existing files are not compressed. For more information, see [Compressing previously written files](https://docs.aws.amazon.com/fsx/latest/LustreGuide/data-compression.html#migrate-compression). + + +### Backups +You can take daily automatic backups by setting `automaticBackupRetention` to a non-zero day in the `lustreConfiguration`. + +Additionally, you can set the backup window by specifying the `dailyAutomaticBackupStartTime`. + +```ts +import * as cdk from 'aws-cdk-lib'; + +const lustreConfiguration = { + // ... + automaticBackupRetention: cdk.Duration.days(3), // backup retention + copyTagsToBackups: true, // if true, tags are copied to backups + dailyAutomaticBackupStartTime: new fsx.DailyAutomaticBackupStartTime({ hour: 11, minute: 30 }), // backup window + // ... +} +``` + +For more information, see [Working with backups +](https://docs.aws.amazon.com/fsx/latest/LustreGuide/using-backups-fsx.html). ## FSx for Windows File Server diff --git a/packages/aws-cdk-lib/aws-fsx/lib/daily-automatic-backup-start-time.ts b/packages/aws-cdk-lib/aws-fsx/lib/daily-automatic-backup-start-time.ts new file mode 100644 index 0000000000000..0699caff3eeff --- /dev/null +++ b/packages/aws-cdk-lib/aws-fsx/lib/daily-automatic-backup-start-time.ts @@ -0,0 +1,68 @@ +/** + * Properties required for setting up a daily automatic backup time. + */ +export interface DailyAutomaticBackupStartTimeProps { + /** + * The hour of the day (from 0-23) for automatic backup starts. + */ + readonly hour: number; + /** + * The minute of the hour (from 0-59) for automatic backup starts. + */ + readonly minute: number; +} + +/** + * Class for scheduling a daily automatic backup time. + */ +export class DailyAutomaticBackupStartTime { + /** + * The start hour of the automatic backup time in Coordinated Universal Time (UTC), using 24-hour time. + * For example, 17 refers to 5:00 P.M. UTC. + * + * @default - 22 + */ + private readonly hour: string; + /** + * The start minute of the automatic backup time, in UTC. + * + * @default - 0 + */ + private readonly minute: string; + + constructor(props: DailyAutomaticBackupStartTimeProps) { + this.validate(props.hour, props.minute); + + this.hour = this.getTwoDigitString(props.hour); + this.minute = this.getTwoDigitString(props.minute); + } + /** + * Converts an hour, and minute into HH:MM string. + */ + public toTimestamp(): string { + return `${this.hour}:${this.minute}`; + } + + /** + * Pad an integer so that it always contains at least 2 digits. Assumes the number is a positive integer. + */ + private getTwoDigitString(n: number): string { + const numberString = n.toString(); + if (numberString.length === 1) { + return `0${n}`; + } + return numberString; + } + + /** + * Validation needed for the values of the daily automatic backup time. + */ + private validate(hour: number, minute: number) { + if (!Number.isInteger(hour) || hour < 0 || hour > 23) { + throw new Error(`dailyAutomaticBackupStartTime hour must be an integer between 0 and 24. received: ${hour}`); + } + if (!Number.isInteger(minute) || minute < 0 || minute > 59) { + throw new Error(`dailyAutomaticBackupStartTime minute must be an integer between 0 and 59. received: ${minute}`); + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-fsx/lib/index.ts b/packages/aws-cdk-lib/aws-fsx/lib/index.ts index 4202ee711abd2..a9a33f395f341 100644 --- a/packages/aws-cdk-lib/aws-fsx/lib/index.ts +++ b/packages/aws-cdk-lib/aws-fsx/lib/index.ts @@ -1,3 +1,4 @@ +export * from './daily-automatic-backup-start-time'; export * from './file-system'; export * from './fsx.generated'; export * from './lustre-file-system'; diff --git a/packages/aws-cdk-lib/aws-fsx/lib/lustre-file-system.ts b/packages/aws-cdk-lib/aws-fsx/lib/lustre-file-system.ts index 48328d80c126b..58803107856d5 100644 --- a/packages/aws-cdk-lib/aws-fsx/lib/lustre-file-system.ts +++ b/packages/aws-cdk-lib/aws-fsx/lib/lustre-file-system.ts @@ -1,9 +1,10 @@ import { Construct } from 'constructs'; +import { DailyAutomaticBackupStartTime } from './daily-automatic-backup-start-time'; import { FileSystemAttributes, FileSystemBase, FileSystemProps, IFileSystem } from './file-system'; import { CfnFileSystem } from './fsx.generated'; import { LustreMaintenanceTime } from './maintenance-time'; import { Connections, ISecurityGroup, ISubnet, Port, SecurityGroup } from '../../aws-ec2'; -import { Aws, Token } from '../../core'; +import { Aws, Duration, Token } from '../../core'; /** * The different kinds of file system deployments used by Lustre. @@ -143,6 +144,32 @@ export interface LustreConfiguration { * @default - no preference */ readonly weeklyMaintenanceStartTime?: LustreMaintenanceTime; + + /** + * The number of days to retain automatic backups. + * Setting this property to 0 disables automatic backups. + * You can retain automatic backups for a maximum of 90 days. + * + * Automatic Backups is not supported on scratch file systems. + * + * @default Duration.days(0) + */ + readonly automaticBackupRetention?: Duration; + + /** + * A boolean flag indicating whether tags for the file system should be copied to backups. + * + * @default - false + */ + readonly copyTagsToBackups?: boolean; + + /** + * Start time for 30-minute daily automatic backup window in Coordinated Universal Time (UTC). + * + * @default - no backup window + */ + readonly dailyAutomaticBackupStartTime?: DailyAutomaticBackupStartTime; + } /** @@ -241,6 +268,8 @@ export class LustreFileSystem extends FileSystemBase { const updatedLustureProps = { importedFileChunkSize: props.lustreConfiguration.importedFileChunkSizeMiB, weeklyMaintenanceStartTime: props.lustreConfiguration.weeklyMaintenanceStartTime?.toTimestamp(), + automaticBackupRetentionDays: props.lustreConfiguration.automaticBackupRetention?.toDays(), + dailyAutomaticBackupStartTime: props.lustreConfiguration.dailyAutomaticBackupStartTime?.toTimestamp(), }; const lustreConfiguration = Object.assign({}, props.lustreConfiguration, updatedLustureProps); @@ -283,6 +312,10 @@ export class LustreFileSystem extends FileSystemBase { this.validateAutoImportPolicy(deploymentType, lustreConfiguration.importPath, lustreConfiguration.autoImportPolicy); this.validatePerUnitStorageThroughput(deploymentType, lustreConfiguration.perUnitStorageThroughput); this.validateStorageCapacity(deploymentType, props.storageCapacityGiB); + + this.validateAutomaticBackupRetention(deploymentType, lustreConfiguration.automaticBackupRetention); + + this.validateDailyAutomaticBackupStartTime(lustreConfiguration.automaticBackupRetention, lustreConfiguration.dailyAutomaticBackupStartTime); } /** @@ -385,4 +418,36 @@ export class LustreFileSystem extends FileSystemBase { } } } + + /** + * Validates the automaticBackupRetention with a non-scratch deployment class and an acceptable day value. + */ + private validateAutomaticBackupRetention(deploymentType: LustreDeploymentType, automaticBackupRetention?: Duration): void { + if (automaticBackupRetention) { + const automaticBackupRetentionDays = automaticBackupRetention.toDays(); + + if ([LustreDeploymentType.SCRATCH_1, LustreDeploymentType.SCRATCH_2].includes(deploymentType) && automaticBackupRetentionDays > 0) { + throw new Error('automatic backups is not supported on scratch file systems'); + } + + if (automaticBackupRetentionDays > 90) { + throw new Error(`automaticBackupRetention period must be between 0 and 90 days. received: ${automaticBackupRetentionDays}`); + } + } + } + + /** + * Validates the dailyAutomaticBackupStartTime is set with a non-zero day automaticBackupRetention. + */ + private validateDailyAutomaticBackupStartTime(automaticBackupRetention?: Duration, + dailyAutomaticBackupStartTime?: DailyAutomaticBackupStartTime): void { + if (!dailyAutomaticBackupStartTime) return; + + const automaticBackupDisabled = !automaticBackupRetention || automaticBackupRetention?.toDays() === Duration.days(0).toDays(); + + if (dailyAutomaticBackupStartTime && automaticBackupDisabled) { + throw new Error('automaticBackupRetention period must be set a non-zero day when dailyAutomaticBackupStartTime is set'); + } + + } } diff --git a/packages/aws-cdk-lib/aws-fsx/test/daily-automatic-backup-start-time.test.ts b/packages/aws-cdk-lib/aws-fsx/test/daily-automatic-backup-start-time.test.ts new file mode 100644 index 0000000000000..8a0b3e53c6f2c --- /dev/null +++ b/packages/aws-cdk-lib/aws-fsx/test/daily-automatic-backup-start-time.test.ts @@ -0,0 +1,32 @@ +import { strictEqual } from 'assert'; +import { DailyAutomaticBackupStartTime } from '../lib'; + +test.each([ + [0, 0, '00:00'], + [23, 59, '23:59'], +])('valid maintenance time %s:%d:%d returns %s', (hour: number, minute: number, expected: string) => { + strictEqual( + new DailyAutomaticBackupStartTime({ hour, minute }).toTimestamp(), + expected, + ); +}); + +test.each([ + [-1, 0], + [24, 0], + [1.2, 0], +])('invalid dailyAutomaticBackupStartTime hour %d:%d', ( hour: number, minute: number) => { + expect(() => { + new DailyAutomaticBackupStartTime({ hour, minute }); + }).toThrow(`dailyAutomaticBackupStartTime hour must be an integer between 0 and 24. received: ${hour}`); +}); + +test.each([ + [0, -1], + [0, 60], + [0, 1.2], +])('invalid dailyAutomaticBackupStartTime minute %d:%d', (hour: number, minute: number) => { + expect(() => { + new DailyAutomaticBackupStartTime({ hour, minute }); + }).toThrow(`dailyAutomaticBackupStartTime minute must be an integer between 0 and 59. received: ${minute}`); +}); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-fsx/test/lustre-file-system.test.ts b/packages/aws-cdk-lib/aws-fsx/test/lustre-file-system.test.ts index c73c60b456865..00aeaf10a2d6d 100644 --- a/packages/aws-cdk-lib/aws-fsx/test/lustre-file-system.test.ts +++ b/packages/aws-cdk-lib/aws-fsx/test/lustre-file-system.test.ts @@ -2,8 +2,8 @@ import { strictEqual } from 'assert'; import { Template } from '../../assertions'; import { ISubnet, Port, SecurityGroup, Subnet, Vpc } from '../../aws-ec2'; import { Key } from '../../aws-kms'; -import { Aws, Stack, Token } from '../../core'; -import { LustreConfiguration, LustreDeploymentType, LustreAutoImportPolicy, LustreFileSystem, LustreMaintenanceTime, Weekday, LustreDataCompressionType } from '../lib'; +import { Aws, Duration, Stack, Token } from '../../core'; +import { LustreConfiguration, LustreDeploymentType, LustreAutoImportPolicy, LustreFileSystem, LustreMaintenanceTime, Weekday, LustreDataCompressionType, DailyAutomaticBackupStartTime } from '../lib'; describe('FSx for Lustre File System', () => { let lustreConfiguration: LustreConfiguration; @@ -705,6 +705,96 @@ describe('FSx for Lustre File System', () => { }).toThrowError(/storageCapacity must be 1,200, 2,400, 3,600, or a multiple of 3,600/); }); }); + + describe('automaticBackupRetention', () => { + test.each([0, 10, 90])('valid value for automaticBackupRetention using %d', (validValue: number) => { + lustreConfiguration = { + deploymentType: LustreDeploymentType.PERSISTENT_1, + automaticBackupRetention: Duration.days(validValue), + }; + + new LustreFileSystem(stack, 'FsxFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::FSx::FileSystem', { + LustreConfiguration: { + DeploymentType: LustreDeploymentType.PERSISTENT_1, + AutomaticBackupRetentionDays: validValue, + }, + }); + }); + + test('Scratch file system with a non-zero day automaticBackupRetention throws error', () => { + lustreConfiguration = { + deploymentType: LustreDeploymentType.SCRATCH_1, + automaticBackupRetention: Duration.days(3), + }; + + expect(() => { + new LustreFileSystem(stack, 'FsxFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet, + }); + }).toThrow('automatic backups is not supported on scratch file systems'); + }); + + test('automaticBackupRetention over 90 days throws error', () => { + lustreConfiguration = { + deploymentType: LustreDeploymentType.PERSISTENT_1, + automaticBackupRetention: Duration.days(100), + }; + + expect(() => { + new LustreFileSystem(stack, 'FsxFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet, + }); + }).toThrow('automaticBackupRetention period must be between 0 and 90 days. received: 100'); + }); + }); + + describe('dailyAutomaticBackupStartTime', () => { + test('dailyAutomaticBackupStartTime without an automaticBackupRetention setting throws error', () => { + lustreConfiguration = { + deploymentType: LustreDeploymentType.PERSISTENT_1, + dailyAutomaticBackupStartTime: new DailyAutomaticBackupStartTime({ hour: 10, minute: 0 }), + }; + + expect(() => { + new LustreFileSystem(stack, 'FsxFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet, + }); + }).toThrow('automaticBackupRetention period must be set a non-zero day when dailyAutomaticBackupStartTime is set'); + }); + + test('dailyAutomaticBackupStartTime with automaticBackupRetention 0 day throws error', () => { + lustreConfiguration = { + deploymentType: LustreDeploymentType.PERSISTENT_1, + automaticBackupRetention: Duration.days(0), + dailyAutomaticBackupStartTime: new DailyAutomaticBackupStartTime({ hour: 10, minute: 0 }), + }; + + expect(() => { + new LustreFileSystem(stack, 'FsxFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet, + }); + }).toThrow('automaticBackupRetention period must be set a non-zero day when dailyAutomaticBackupStartTime is set'); + }); + }); }); test('existing file system is imported correctly', () => { @@ -723,4 +813,25 @@ describe('FSx for Lustre File System', () => { GroupId: 'sg-123456789', }); }); + + test.each([true, false])('copyTagsToBackups using %s', (copyTagsToBackups: boolean) => { + lustreConfiguration = { + deploymentType: LustreDeploymentType.PERSISTENT_1, + copyTagsToBackups, + }; + + new LustreFileSystem(stack, 'FsxFileSystem', { + lustreConfiguration, + storageCapacityGiB: storageCapacity, + vpc, + vpcSubnet, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::FSx::FileSystem', { + LustreConfiguration: { + DeploymentType: LustreDeploymentType.PERSISTENT_1, + CopyTagsToBackups: copyTagsToBackups, + }, + }); + }); }); \ No newline at end of file