1
+ import * as ec2 from '@aws-cdk/aws-ec2' ;
2
+ import * as kms from '@aws-cdk/aws-kms' ;
3
+ import { Construct , Resource , Tag } from "@aws-cdk/core" ;
4
+ import { CfnFileSystem , CfnMountTarget } from "./efs.generated" ;
5
+ import { FileSystemProps , IFileSystem } from "./file-system" ;
6
+
7
+ /**
8
+ * EFS Lifecycle Policy, if a file is not accessed for given days, it will move to EFS Infrequent Access.
9
+ *
10
+ * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-efs-filesystem-performancemode
11
+ */
12
+ export enum EfsLifecyclePolicyProperty {
13
+ /**
14
+ * After 7 days of inaccessibility.
15
+ */
16
+ AFTER_7_DAYS ,
17
+
18
+ /**
19
+ * After 14 days of inaccessibility.
20
+ */
21
+ AFTER_14_DAYS ,
22
+
23
+ /**
24
+ * After 30 days of inaccessibility.
25
+ */
26
+ AFTER_30_DAYS ,
27
+
28
+ /**
29
+ * After 60 days of inaccessibility.
30
+ */
31
+ AFTER_60_DAYS ,
32
+
33
+ /**
34
+ * After 90 days of inaccessibility.
35
+ */
36
+ AFTER_90_DAYS
37
+ }
38
+
39
+ /**
40
+ * EFS Performance mode.
41
+ *
42
+ * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-efs-filesystem-performancemode
43
+ */
44
+ export enum EfsPerformanceMode {
45
+ /**
46
+ * This is the general purpose performance mode for most file systems.
47
+ */
48
+ GENERAL_PURPOSE = "generalPurpose" ,
49
+
50
+ /**
51
+ * This performance mode can scale to higher levels of aggregate throughput and operations per second with a
52
+ * tradeoff of slightly higher latencies.
53
+ */
54
+ MAX_IO = "maxIO"
55
+ }
56
+
57
+ /**
58
+ * EFS Throughput mode.
59
+ *
60
+ * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-elasticfilesystem-filesystem-throughputmode
61
+ */
62
+ export enum EfsThroughputMode {
63
+ /**
64
+ * This mode on Amazon EFS scales as the size of the file system in the standard storage class grows.
65
+ */
66
+ BURSTING = "bursting" ,
67
+
68
+ /**
69
+ * This mode can instantly provision the throughput of the file system (in MiB/s) independent of the amount of data stored.
70
+ */
71
+ PROVISIONED = "provisioned"
72
+ }
73
+
74
+ /**
75
+ * Properties of EFS FileSystem.
76
+ */
77
+ export interface EfsFileSystemProps extends FileSystemProps {
78
+ /**
79
+ * Defines if the data at rest in the file system is encrypted or not.
80
+ *
81
+ * @default - false
82
+ */
83
+ readonly encrypted ?: boolean ;
84
+
85
+ /**
86
+ * The KMS key used for encryption. This is required to encrypt the data at rest if @encrypted is set to true.
87
+ *
88
+ * @default - if @encrypted is true, the default key for EFS (/aws/elasticfilesystem) is used
89
+ */
90
+ readonly kmsKey ?: kms . IKey ;
91
+
92
+ /**
93
+ * The key value pair added to the File system.
94
+ *
95
+ * @default - no tags will be added
96
+ */
97
+ readonly fileSystemTags ?: Tag [ ] ;
98
+
99
+ /**
100
+ * A policy used by EFS lifecycle management to transition files to the Infrequent Access (IA) storage class.
101
+ *
102
+ * @default - none
103
+ */
104
+ readonly lifecyclePolicy ?: EfsLifecyclePolicyProperty ;
105
+
106
+ /**
107
+ * Enum to mention the performance mode of the file system.
108
+ *
109
+ * @default - GENERAL_PURPOSE
110
+ */
111
+ readonly performanceMode ?: EfsPerformanceMode ;
112
+
113
+ /**
114
+ * Enum to mention the throughput mode of the file system.
115
+ *
116
+ * @default - BURSTING
117
+ */
118
+ readonly throughputMode ?: EfsThroughputMode ;
119
+
120
+ /**
121
+ * Provisioned throughput for the file system. This is a required property if the throughput mode is set to PROVISIONED.
122
+ * Valid values are 1-1024.
123
+ *
124
+ * @default - None, errors out
125
+ */
126
+ readonly provisionedThroughputInMibps ?: number ;
127
+ }
128
+
129
+ /**
130
+ * A new or imported EFS File System.
131
+ */
132
+ abstract class EFSFileSystemBase extends Resource implements IFileSystem {
133
+
134
+ /**
135
+ * The security groups/rules used to allow network connections to the file system.
136
+ */
137
+ public abstract readonly connections : ec2 . Connections ;
138
+
139
+ /**
140
+ * @attribute
141
+ */
142
+ public abstract readonly fileSystemID : string ;
143
+ }
144
+
145
+ /**
146
+ * Properties that describe an existing EFS file system.
147
+ */
148
+ export interface EfsFileSystemAttributes {
149
+ /**
150
+ * The security group of the file system
151
+ */
152
+ readonly securityGroup : ec2 . ISecurityGroup ;
153
+
154
+ /**
155
+ * The File System's ID.
156
+ */
157
+ readonly fileSystemID : string ;
158
+ }
159
+
160
+ /**
161
+ * The Elastic File System implementation of IFileSystem.
162
+ * It creates a new, empty file system in Amazon Elastic File System (Amazon EFS).
163
+ * It also creates mount target (AWS::EFS::MountTarget) implicitly to mount the
164
+ * EFS file system on an Amazon Elastic Compute Cloud (Amazon EC2) instance or another resource.
165
+ *
166
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html
167
+ *
168
+ * @resource AWS::EFS::FileSystem
169
+ */
170
+ export class EfsFileSystem extends EFSFileSystemBase {
171
+
172
+ /**
173
+ * Import an existing File System from the given properties.
174
+ */
175
+ public static fromEfsFileSystemAttributes ( scope : Construct , id : string , attrs : EfsFileSystemAttributes ) : IFileSystem {
176
+ class Import extends EFSFileSystemBase implements IFileSystem {
177
+ public readonly fileSystemID = attrs . fileSystemID ;
178
+ public readonly connections = new ec2 . Connections ( {
179
+ securityGroups : [ attrs . securityGroup ] ,
180
+ defaultPort : ec2 . Port . tcp ( EfsFileSystem . DEFAULT_PORT )
181
+ } ) ;
182
+ }
183
+
184
+ return new Import ( scope , id ) ;
185
+ }
186
+
187
+ /**
188
+ * The default port File System listens on.
189
+ */
190
+ private static readonly DEFAULT_PORT : number = 2049 ;
191
+
192
+ /**
193
+ * The security groups/rules used to allow network connections to the file system.
194
+ */
195
+ public readonly connections : ec2 . Connections ;
196
+
197
+ /**
198
+ * @attribute
199
+ */
200
+ public readonly fileSystemID : string ;
201
+
202
+ private readonly mountTargets : CfnMountTarget [ ] = [ ] ;
203
+ private readonly efsFileSystem : CfnFileSystem ;
204
+
205
+ /**
206
+ * Constructor for creating a new EFS FileSystem.
207
+ */
208
+ constructor ( scope : Construct , id : string , props : EfsFileSystemProps ) {
209
+ super ( scope , id ) ;
210
+
211
+ if ( props . throughputMode === EfsThroughputMode . PROVISIONED ) {
212
+ if ( props . provisionedThroughputInMibps === undefined ) {
213
+ throw new Error ( 'Property provisionedThroughputInMibps is required when throughputMode is PROVISIONED' ) ;
214
+ } else if ( ! Number . isInteger ( props . provisionedThroughputInMibps ) ) {
215
+ throw new Error ( "Invalid input for provisionedThroughputInMibps" ) ;
216
+ } else if ( props . provisionedThroughputInMibps < 1 || props . provisionedThroughputInMibps > 1024 ) {
217
+ this . node . addWarning ( "Valid values for throughput are 1-1024 MiB/s. You can get this limit increased by contacting AWS Support." ) ;
218
+ }
219
+ }
220
+
221
+ this . efsFileSystem = new CfnFileSystem ( this , "FileSystem" , {
222
+ encrypted : props . encrypted ,
223
+ kmsKeyId : ( props . kmsKey ? props . kmsKey . keyId : undefined ) ,
224
+ fileSystemTags : props . fileSystemTags ,
225
+ lifecyclePolicies : ( props . lifecyclePolicy ? Array . of ( {
226
+ transitionToIa : EfsLifecyclePolicyProperty [ props . lifecyclePolicy ]
227
+ } as CfnFileSystem . LifecyclePolicyProperty ) : undefined ) ,
228
+ performanceMode : props . performanceMode ,
229
+ throughputMode : props . throughputMode ,
230
+ provisionedThroughputInMibps : props . provisionedThroughputInMibps
231
+ } ) ;
232
+
233
+ this . fileSystemID = this . efsFileSystem . ref ;
234
+ this . node . defaultChild = this . efsFileSystem ;
235
+
236
+ const securityGroup = ( props . securityGroup || new ec2 . SecurityGroup ( this , 'EfsSecurityGroup' , {
237
+ vpc : props . vpc
238
+ } ) ) ;
239
+
240
+ this . connections = new ec2 . Connections ( {
241
+ securityGroups : [ securityGroup ] ,
242
+ defaultPort : ec2 . Port . tcp ( EfsFileSystem . DEFAULT_PORT )
243
+ } ) ;
244
+
245
+ const subnets = props . vpc . selectSubnets ( props . vpcSubnets ) ;
246
+
247
+ // We now have to create the mount target for each of the mentioned subnet
248
+ let mountTargetCount = 0 ;
249
+ subnets . subnetIds . forEach ( ( subnetId : string ) => {
250
+ const efsMountTarget = new CfnMountTarget ( this ,
251
+ "EfsMountTarget" + ( ++ mountTargetCount ) ,
252
+ {
253
+ fileSystemId : this . fileSystemID ,
254
+ securityGroups : Array . of ( securityGroup . securityGroupId ) ,
255
+ subnetId
256
+ } ) ;
257
+ this . mountTargets . push ( efsMountTarget ) ;
258
+ } ) ;
259
+ }
260
+ }
0 commit comments