@@ -9,12 +9,14 @@ Metadata:
99 Parameters :
1010 - AutomaticBackups
1111 - ThroughputMode
12+ - EnforceTLS
1213 - Label :
1314 default : Networking and Access
1415 Parameters :
1516 - VpcId
1617 - SubnetIds
1718 - SubnetCount
19+ - SecurityGroupName
1820
1921Parameters :
2022 VpcId :
@@ -45,6 +47,17 @@ Parameters:
4547 AllowedValues :
4648 - " elastic"
4749 - " bursting"
50+ EnforceTLS :
51+ Description : Enforce TLS for data in transit
52+ Type : String
53+ Default : " true"
54+ AllowedValues :
55+ - " true"
56+ - " false"
57+ SecurityGroupName :
58+ Type : String
59+ Description : (Optional) An existing security group to associate to the file system. If none is provided, a new security group will be created.
60+ Default : " "
4861
4962Conditions :
5063 1AZCondition : !Or
@@ -54,6 +67,9 @@ Conditions:
5467 - !Equals [!Ref 'SubnetCount', '2']
5568 - !Condition ' 3AZCondition'
5669 3AZCondition : !Equals [!Ref 'SubnetCount', '3']
70+ EnforceTLSCondition : !Equals ["true", !Ref EnforceTLS]
71+ CreateSecurityGroup : !Equals ["", !Ref SecurityGroupName]
72+ UseExistingSecurityGroup : !Not [!Equals ["", !Ref SecurityGroupName]]
5773
5874Resources :
5975
@@ -80,14 +96,17 @@ Resources:
8096 Condition :
8197 Bool :
8298 ' elasticfilesystem:AccessedViaMountTarget ' : ' true'
83- - Sid : efs-enforce-tls
84- Effect : Deny
85- Principal :
86- AWS : ' *'
87- Action : ' *'
88- Condition :
89- Bool :
90- ' aws:SecureTransport ' : ' false'
99+ - !If
100+ - EnforceTLSCondition
101+ - Sid : efs-enforce-tls
102+ Effect : Deny
103+ Principal :
104+ AWS : ' *'
105+ Action : ' *'
106+ Condition :
107+ Bool :
108+ ' aws:SecureTransport ' : ' false'
109+ - !Ref ' AWS::NoValue'
91110 BackupPolicy :
92111 Status : !Ref AutomaticBackups
93112 Encrypted : true
@@ -96,6 +115,7 @@ Resources:
96115 # Security group
97116 EfsSecurityGroup :
98117 Type : AWS::EC2::SecurityGroup
118+ Condition : CreateSecurityGroup
99119 Properties :
100120 GroupDescription : !Sub
101121 - ' Allows traffic to EFS filesystem ${FileSystemId}'
@@ -120,7 +140,10 @@ Resources:
120140 Description : Allow incoming traffic to EFS from members of security group
121141 FromPort : 2049
122142 ToPort : 2049
123- GroupId : !Ref EfsSecurityGroup
143+ GroupId : !If
144+ - CreateSecurityGroup
145+ - !Ref EfsSecurityGroup
146+ - !GetAtt SecurityGroupLookup.GroupId
124147 SourceSecurityGroupId : !Ref EfsClientSecurityGroup
125148
126149 EfsClientSecurityGroupOutboundRule :
@@ -131,35 +154,112 @@ Resources:
131154 FromPort : 2049
132155 ToPort : 2049
133156 GroupId : !Ref EfsClientSecurityGroup
134- DestinationSecurityGroupId : !Ref EfsSecurityGroup
157+ DestinationSecurityGroupId : !If
158+ - CreateSecurityGroup
159+ - !Ref EfsSecurityGroup
160+ - !GetAtt SecurityGroupLookup.GroupId
135161
136162 EfsMountTarget1 :
137163 Type : AWS::EFS::MountTarget
138164 Condition : 1AZCondition
139165 Properties :
140166 FileSystemId : !Ref EfsFilesystem
141- SecurityGroups :
142- - !Ref EfsSecurityGroup
167+ SecurityGroups : !If
168+ - CreateSecurityGroup
169+ - [!Ref EfsSecurityGroup]
170+ - [!GetAtt SecurityGroupLookup.GroupId]
143171 SubnetId : !Select [ 0, !Ref SubnetIds ]
144172
145173 EfsMountTarget2 :
146174 Type : AWS::EFS::MountTarget
147175 Condition : 2AZCondition
148176 Properties :
149177 FileSystemId : !Ref EfsFilesystem
150- SecurityGroups :
151- - !Ref EfsSecurityGroup
178+ SecurityGroups : !If
179+ - CreateSecurityGroup
180+ - [!Ref EfsSecurityGroup]
181+ - [!GetAtt SecurityGroupLookup.GroupId]
152182 SubnetId : !Select [ 1, !Ref SubnetIds ]
153183
154184 EfsMountTarget3 :
155185 Type : AWS::EFS::MountTarget
156186 Condition : 3AZCondition
157187 Properties :
158188 FileSystemId : !Ref EfsFilesystem
159- SecurityGroups :
160- - !Ref EfsSecurityGroup
189+ SecurityGroups : !If
190+ - CreateSecurityGroup
191+ - [!Ref EfsSecurityGroup]
192+ - [!GetAtt SecurityGroupLookup.GroupId]
161193 SubnetId : !Select [ 2, !Ref SubnetIds ]
162194
195+ SecurityGroupLookup :
196+ Type : Custom::SecurityGroupLookup
197+ Condition : UseExistingSecurityGroup
198+ Properties :
199+ ServiceToken : !GetAtt SecurityGroupLookupFunction.Arn
200+ VpcId : !Ref VpcId
201+ GroupName : !Ref SecurityGroupName
202+
203+ SecurityGroupLookupRole :
204+ Type : AWS::IAM::Role
205+ Condition : UseExistingSecurityGroup
206+ Properties :
207+ AssumeRolePolicyDocument :
208+ Version : ' 2012-10-17'
209+ Statement :
210+ - Effect : Allow
211+ Principal :
212+ Service : lambda.amazonaws.com
213+ Action : sts:AssumeRole
214+ ManagedPolicyArns :
215+ - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
216+ Policies :
217+ - PolicyName : DescribeSecurityGroups
218+ PolicyDocument :
219+ Version : ' 2012-10-17'
220+ Statement :
221+ - Effect : Allow
222+ Action : ec2:DescribeSecurityGroups
223+ Resource : ' *'
224+
225+ SecurityGroupLookupFunction :
226+ Type : AWS::Lambda::Function
227+ Condition : UseExistingSecurityGroup
228+ Properties :
229+ Runtime : python3.9
230+ Handler : index.handler
231+ Role : !GetAtt SecurityGroupLookupRole.Arn
232+ Code :
233+ ZipFile : |
234+ import boto3
235+ import cfnresponse
236+
237+ def handler(event, context):
238+ try:
239+ if event['RequestType'] in ['Create', 'Update']:
240+ ec2 = boto3.client('ec2')
241+ vpc_id = event['ResourceProperties']['VpcId']
242+ group_name = event['ResourceProperties']['GroupName']
243+
244+ response = ec2.describe_security_groups(
245+ Filters=[
246+ {'Name': 'vpc-id', 'Values': [vpc_id]},
247+ {'Name': 'group-name', 'Values': [group_name]}
248+ ]
249+ )
250+
251+ if len(response['SecurityGroups']) == 0:
252+ raise Exception(f"Security group {group_name} not found in VPC {vpc_id}")
253+
254+ group_id = response['SecurityGroups'][0]['GroupId']
255+ cfnresponse.send(event, context, cfnresponse.SUCCESS,
256+ {'GroupId': group_id})
257+ else:
258+ cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
259+ except Exception as e:
260+ cfnresponse.send(event, context, cfnresponse.FAILED,
261+ {'Error': str(e)})
262+
163263Outputs :
164264 EFSFilesystemId :
165265 Description : The ID of the EFS filesystem that has been created
0 commit comments