From dde0ef52cc0cdbc40fd212f518f3cee4f30450b9 Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Tue, 23 Jun 2020 23:19:23 +0800 Subject: [PATCH] feat(efs): access point (#8631) This PR adds the [Amazon EFS Access Point ](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html)construct support. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-efs/README.md | 21 + packages/@aws-cdk/aws-efs/lib/access-point.ts | 164 +++++ packages/@aws-cdk/aws-efs/lib/index.ts | 1 + packages/@aws-cdk/aws-efs/package.json | 6 + .../aws-efs/test/access-point.test.ts | 79 +++ .../aws-efs/test/integ.efs.expected.json | 566 ++++++++++++++++++ packages/@aws-cdk/aws-efs/test/integ.efs.ts | 26 + 7 files changed, 863 insertions(+) create mode 100644 packages/@aws-cdk/aws-efs/lib/access-point.ts create mode 100644 packages/@aws-cdk/aws-efs/test/access-point.test.ts create mode 100644 packages/@aws-cdk/aws-efs/test/integ.efs.expected.json create mode 100644 packages/@aws-cdk/aws-efs/test/integ.efs.ts diff --git a/packages/@aws-cdk/aws-efs/README.md b/packages/@aws-cdk/aws-efs/README.md index 40329a9803780..ec2ff3352755a 100644 --- a/packages/@aws-cdk/aws-efs/README.md +++ b/packages/@aws-cdk/aws-efs/README.md @@ -37,6 +37,27 @@ const fileSystem = new FileSystem(this, 'EfsFileSystem', { }); ``` +### Access Point + +An access point is an application-specific view into an EFS file system that applies an operating system user and +group, and a file system path, to any file system request made through the access point. The operating system user +and group override any identity information provided by the NFS client. The file system path is exposed as the +access point's root directory. Applications using the access point can only access data in its own directory and +below. To learn more, see [Mounting a File System Using EFS Access Points](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html). + +Use `AccessPoint` to create an access point: + +```ts +new AccessPoint(stack, 'AccessPoint', { + fileSystem +}); +``` + +By default, when you create an access point, the root(`/`) directory is exposed to the client connecting to +the access point. You may specify custom path with the `path` property. If `path` does not exist, it will be +created with the settings defined in the `creationInfo`. See +[Creating Access Points](https://docs.aws.amazon.com/efs/latest/ug/create-access-point.html) for more details. + ### Connecting To control who can access the EFS, use the `.connections` attribute. EFS has diff --git a/packages/@aws-cdk/aws-efs/lib/access-point.ts b/packages/@aws-cdk/aws-efs/lib/access-point.ts new file mode 100644 index 0000000000000..39c9fabb68a04 --- /dev/null +++ b/packages/@aws-cdk/aws-efs/lib/access-point.ts @@ -0,0 +1,164 @@ +import { Construct, IResource, Resource, Stack } from '@aws-cdk/core'; +import { IFileSystem } from './efs-file-system'; +import { CfnAccessPoint } from './efs.generated'; + +/** + * Represents an EFS AccessPoint + */ +export interface IAccessPoint extends IResource { + /** + * The ID of the AccessPoint + * + * @attribute + */ + readonly accessPointId: string; + + /** + * The ARN of the AccessPoint + * + * @attribute + */ + readonly accessPointArn: string; +} + +/** + * Permissions as POSIX ACL + */ +export interface Acl { + /** + * Specifies the POSIX user ID to apply to the RootDirectory. Accepts values from 0 to 2^32 (4294967295). + */ + readonly ownerUid: string; + + /** + * Specifies the POSIX group ID to apply to the RootDirectory. Accepts values from 0 to 2^32 (4294967295). + */ + readonly ownerGid: string; + + /** + * Specifies the POSIX permissions to apply to the RootDirectory, in the format of an octal number representing + * the file's mode bits. + */ + readonly permissions: string; +} + +/** + * Represents the PosixUser + */ +export interface PosixUser { + /** + * The POSIX user ID used for all file system operations using this access point. + */ + readonly uid: string; + + /** + * The POSIX group ID used for all file system operations using this access point. + */ + readonly gid: string; + + /** + * Secondary POSIX group IDs used for all file system operations using this access point. + * + * @default - None + */ + readonly secondaryGids?: string[]; +} + +/** + * Properties for the AccessPoint + */ +export interface AccessPointProps { + /** + * The efs filesystem + */ + readonly fileSystem: IFileSystem; + + /** + * Specifies the POSIX IDs and permissions to apply when creating the access point's root directory. If the + * root directory specified by `path` does not exist, EFS creates the root directory and applies the + * permissions specified here. If the specified `path` does not exist, you must specify `createAcl`. + * + * @default - None. The directory specified by `path` must exist. + */ + readonly createAcl?: Acl; + + /** + * Specifies the path on the EFS file system to expose as the root directory to NFS clients using the access point + * to access the EFS file system + * + * @default '/' + */ + readonly path?: string; + + /** + * The full POSIX identity, including the user ID, group ID, and any secondary group IDs, on the access point + * that is used for all file system operations performed by NFS clients using the access point. + * + * Specify this to enforce a user identity using an access point. + * + * @see - [Enforcing a User Identity Using an Access Point](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html) + * + * @default - user identity not enforced + */ + readonly posixUser?: PosixUser; +} + +/** + * Represents the AccessPoint + */ +export class AccessPoint extends Resource implements IAccessPoint { + /** + * Import an existing Access Point + */ + public static fromAccessPointId(scope: Construct, id: string, accessPointId: string): IAccessPoint { + class Import extends Resource implements IAccessPoint { + public readonly accessPointId = accessPointId; + public readonly accessPointArn = Stack.of(scope).formatArn({ + service: 'elasticfilesystem', + resource: 'access-point', + resourceName: accessPointId, + }); + } + return new Import(scope, id); + } + + /** + * The ARN of the Access Point + * @attribute + */ + public readonly accessPointArn: string; + + /** + * The ID of the Access Point + * @attribute + */ + public readonly accessPointId: string; + + constructor(scope: Construct, id: string, props: AccessPointProps) { + super(scope, id); + + const resource = new CfnAccessPoint(scope, 'Resource', { + fileSystemId: props.fileSystem.fileSystemId, + rootDirectory: { + creationInfo: props.createAcl ? { + ownerGid: props.createAcl.ownerGid, + ownerUid: props.createAcl.ownerUid, + permissions: props.createAcl.permissions, + } : undefined, + path: props.path, + }, + posixUser: props.posixUser ? { + uid: props.posixUser.uid, + gid: props.posixUser.gid, + secondaryGids: props.posixUser.secondaryGids, + } : undefined, + }); + + this.accessPointId = resource.ref; + this.accessPointArn = Stack.of(scope).formatArn({ + service: 'elasticfilesystem', + resource: 'access-point', + resourceName: this.accessPointId, + }); + } +} diff --git a/packages/@aws-cdk/aws-efs/lib/index.ts b/packages/@aws-cdk/aws-efs/lib/index.ts index 808b7a1162e5f..91aec43b31ea8 100644 --- a/packages/@aws-cdk/aws-efs/lib/index.ts +++ b/packages/@aws-cdk/aws-efs/lib/index.ts @@ -1,3 +1,4 @@ // AWS::EFS CloudFormation Resources: +export * from './access-point'; export * from './efs-file-system'; export * from './efs.generated'; diff --git a/packages/@aws-cdk/aws-efs/package.json b/packages/@aws-cdk/aws-efs/package.json index f17fa315f03a2..0710626c4c7e2 100644 --- a/packages/@aws-cdk/aws-efs/package.json +++ b/packages/@aws-cdk/aws-efs/package.json @@ -65,6 +65,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "cdk-build-tools": "0.0.0", + "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" }, @@ -88,6 +89,11 @@ "engines": { "node": ">= 10.13.0 <13 || >=13.7.0" }, + "awslint": { + "exclude": [ + "props-physical-name:@aws-cdk/aws-efs.AccessPointProps" + ] + }, "stability": "experimental", "maturity": "experimental", "awscdkio": { diff --git a/packages/@aws-cdk/aws-efs/test/access-point.test.ts b/packages/@aws-cdk/aws-efs/test/access-point.test.ts new file mode 100644 index 0000000000000..6b7343b1e5f52 --- /dev/null +++ b/packages/@aws-cdk/aws-efs/test/access-point.test.ts @@ -0,0 +1,79 @@ +import { expect as expectCDK, haveResource } from '@aws-cdk/assert'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import { Stack } from '@aws-cdk/core'; +import { AccessPoint, FileSystem } from '../lib'; + +let stack: Stack; +let vpc: ec2.Vpc; +let fileSystem: FileSystem; + +beforeEach(() => { + stack = new Stack(); + vpc = new ec2.Vpc(stack, 'VPC'); + fileSystem = new FileSystem(stack, 'EfsFileSystem', { + vpc, + }); +}); + +test('default access point is created correctly', () => { + // WHEN + new AccessPoint(stack, 'MyAccessPoint', { + fileSystem, + }); + // THEN + expectCDK(stack).to(haveResource('AWS::EFS::AccessPoint')); +}); + +test('import correctly', () => { + // WHEN + const ap = new AccessPoint(stack, 'MyAccessPoint', { + fileSystem, + }); + const imported = AccessPoint.fromAccessPointId(stack, 'ImportedAccessPoint', ap.accessPointId); + // THEN + expect(imported.accessPointId).toEqual(ap.accessPointId); +}); + +test('custom access point is created correctly', () => { + // WHEN + new AccessPoint(stack, 'MyAccessPoint', { + fileSystem, + createAcl: { + ownerGid: '1000', + ownerUid: '1000', + permissions: '755', + }, + path: '/export/share', + posixUser: { + gid: '1000', + uid: '1000', + secondaryGids: [ + '1001', + '1002', + ], + }, + + }); + // THEN + expectCDK(stack).to(haveResource('AWS::EFS::AccessPoint', { + FileSystemId: { + Ref: 'EfsFileSystem37910666', + }, + PosixUser: { + Gid: '1000', + SecondaryGids: [ + '1001', + '1002', + ], + Uid: '1000', + }, + RootDirectory: { + CreationInfo: { + OwnerGid: '1000', + OwnerUid: '1000', + Permissions: '755', + }, + Path: '/export/share', + }, + })); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json b/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json new file mode 100644 index 0000000000000..f5eeff3153703 --- /dev/null +++ b/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json @@ -0,0 +1,566 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.32.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet3SubnetBE12F0B6": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.64.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1c", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet3" + } + ] + } + }, + "VpcPublicSubnet3RouteTable93458DBB": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PublicSubnet3" + } + ] + } + }, + "VpcPublicSubnet3RouteTableAssociation1F1EDF02": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet3RouteTable93458DBB" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" + } + } + }, + "VpcPublicSubnet3DefaultRoute4697774F": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet3RouteTable93458DBB" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.96.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcPrivateSubnet2Subnet3788AAA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "VpcPrivateSubnet2DefaultRoute060D2087": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcPrivateSubnet3SubnetF258B56E": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.160.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1c", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PrivateSubnet3" + } + ] + } + }, + "VpcPrivateSubnet3RouteTableD98824C7": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc/PrivateSubnet3" + } + ] + } + }, + "VpcPrivateSubnet3RouteTableAssociation16BDDC43": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet3RouteTableD98824C7" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet3SubnetF258B56E" + } + } + }, + "VpcPrivateSubnet3DefaultRoute94B74F0D": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet3RouteTableD98824C7" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "FileSystem8A8E25C0": { + "Type": "AWS::EFS::FileSystem", + "Properties": { + "FileSystemTags": [ + { + "Key": "Name", + "Value": "test-efs-integ/FileSystem" + } + ] + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "FileSystemEfsSecurityGroup212D3ACB": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "test-efs-integ/FileSystem/EfsSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "test-efs-integ/FileSystem" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "FileSystemEfsMountTarget1586453F0": { + "Type": "AWS::EFS::MountTarget", + "Properties": { + "FileSystemId": { + "Ref": "FileSystem8A8E25C0" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FileSystemEfsSecurityGroup212D3ACB", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "FileSystemEfsMountTarget24B8EBB43": { + "Type": "AWS::EFS::MountTarget", + "Properties": { + "FileSystemId": { + "Ref": "FileSystem8A8E25C0" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FileSystemEfsSecurityGroup212D3ACB", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "FileSystemEfsMountTarget37C2F9139": { + "Type": "AWS::EFS::MountTarget", + "Properties": { + "FileSystemId": { + "Ref": "FileSystem8A8E25C0" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FileSystemEfsSecurityGroup212D3ACB", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPrivateSubnet3SubnetF258B56E" + } + } + }, + "Resource": { + "Type": "AWS::EFS::AccessPoint", + "Properties": { + "FileSystemId": { + "Ref": "FileSystem8A8E25C0" + }, + "PosixUser": { + "Gid": "1000", + "Uid": "1000" + }, + "RootDirectory": { + "CreationInfo": { + "OwnerGid": "1000", + "OwnerUid": "1000", + "Permissions": "755" + }, + "Path": "/custom-path" + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-efs/test/integ.efs.ts b/packages/@aws-cdk/aws-efs/test/integ.efs.ts new file mode 100644 index 0000000000000..3906e374b8130 --- /dev/null +++ b/packages/@aws-cdk/aws-efs/test/integ.efs.ts @@ -0,0 +1,26 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as cdk from '@aws-cdk/core'; +import { AccessPoint, FileSystem } from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'test-efs-integ'); + +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 3, natGateways: 1}); + +const fileSystem = new FileSystem(stack, 'FileSystem', { + vpc, +}); + +new AccessPoint(stack, 'AccessPoint', { + fileSystem, + createAcl: { + ownerGid: '1000', + ownerUid: '1000', + permissions: '755', + }, + path: '/custom-path', + posixUser: { + gid: '1000', + uid: '1000', + }, +});