├── diagram
├── diagram.png
└── diagram.drawio
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── CONTRIBUTING.md
└── main.yml
/diagram/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/access-internal-alb-through-aws-global-accelerator/main/diagram/diagram.png
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 |
16 |
--------------------------------------------------------------------------------
/diagram/diagram.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Access Internal Application Load Balancer through AWS Global Accelerator
2 | The purpose of this repository is to demo how to access an internal Application Load Balancer (ALB) through AWS Global Accelerator.
3 |
4 | AWS CloudFormation template (main.yml) will deploy a Virtual Private Cloud(VPC) with 2 Public and 2 Private subnets within the VPC. Later it will create an Internal Application Load Balancer attached to an Auto Scaling Group where it will serve a simple PHP application and echo real-client IP using HTTP_X_FORWARDED_FOR header. The access to this PHP application is done through AWS Global Accelerator.
5 |
6 | You can read more in this [blog post](https://aws.amazon.com/blogs/networking-and-content-delivery/accessing-private-application-load-balancers-and-instances-through-aws-global-accelerator/).
7 |
8 | ### Architecture
9 | 
10 |
11 | ### Launch the AWS CloudFormation Stack
12 |
13 | Click on the **Launch Stack** button below to launch the CloudFormation Stack to set up the AWS Global Accelerator Demo in the region of your preference, by default this demo will be deployed in us-west-2 (Oregon) region.
14 |
15 | [](https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/quickcreate?templateUrl=https%3A%2F%2Faws-global-accelerator-with-internal-alb-demo.s3-us-west-2.amazonaws.com%2Fmain.yml&stackName=int-alb-with-aws-ga)
16 |
17 | Provide a stack name eg **int-alb-with-aws-ga**.
18 |
19 | You can launch the same stack using the AWS CLI. Here's an example:
20 |
21 | ```
22 | aws cloudformation create-stack --stack-name int-alb-with-aws-ga \
23 | --template-body file://main.yml \
24 | --capabilities CAPABILITY_NAMED_IAM \
25 | --region us-west-2
26 | ```
27 | ### How to Access Your Application
28 | Once stack creation is completed, it will output the AWS Global Accelerator DNS Name under "Outputs" tab of your stack. Another way of accessing via CLI:
29 |
30 | ```
31 | aws cloudformation describe-stacks --stack-name int-alb-with-aws-ga \
32 | --query "Stacks[0].Outputs[0].OutputValue" \
33 | --region us-west-2
34 | ```
35 |
36 | ### Clean up
37 | After completing your demo, delete AWS CloudFormation Stack using AWS Console or AWS CLI:
38 | ```
39 | aws cloudformation delete-stack --stack-name int-alb-with-aws-ga --region us-west-2
40 | ```
41 |
42 | ## Security
43 |
44 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
45 |
46 | ## License
47 |
48 | This library is licensed under the MIT-0 License. See the LICENSE file.
49 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *main* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
--------------------------------------------------------------------------------
/main.yml:
--------------------------------------------------------------------------------
1 | Parameters:
2 |
3 | VpcCIDR:
4 | Description: Please enter the IP range (CIDR notation) for this VPC
5 | Type: String
6 | Default: 10.10.0.0/16
7 |
8 | PublicSubnet1CIDR:
9 | Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
10 | Type: String
11 | Default: 10.10.10.0/24
12 |
13 | PublicSubnet2CIDR:
14 | Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
15 | Type: String
16 | Default: 10.10.11.0/24
17 |
18 | PrivateSubnet1CIDR:
19 | Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
20 | Type: String
21 | Default: 10.10.20.0/24
22 |
23 | PrivateSubnet2CIDR:
24 | Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
25 | Type: String
26 | Default: 10.10.21.0/24
27 |
28 | AllowedIP:
29 | Description: Allowed IP range
30 | Type: String
31 | Default: 0.0.0.0/0
32 |
33 | LatestLinux2AmiId:
34 | Description: Region specific image from the Parameter Store
35 | Type: 'AWS::SSM::Parameter::Value'
36 | Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
37 |
38 | ResourceName:
39 | Type: String
40 | Default: int-alb-with-aws-ga
41 | Description: Prefix of Resources created for this workshop.
42 |
43 | Metadata:
44 | AWS::CloudFormation::Interface:
45 | ParameterGroups:
46 | -
47 | Label:
48 | default: "Resource Configuration"
49 | Parameters:
50 | - ResourceName
51 | ParameterLabels:
52 | ResourceName:
53 | default: "Resource Prefix"
54 |
55 | Resources:
56 | VPC:
57 | Type: AWS::EC2::VPC
58 | Properties:
59 | CidrBlock: !Ref VpcCIDR
60 | EnableDnsSupport: true
61 | EnableDnsHostnames: true
62 | Tags:
63 | - Key: Name
64 | Value: !Join [ -, [!Ref ResourceName, 'VPC'] ]
65 |
66 | InternetGateway:
67 | Type: AWS::EC2::InternetGateway
68 | Properties:
69 | Tags:
70 | - Key: Name
71 | Value: !Join [ -, [!Ref ResourceName, 'IGW'] ]
72 |
73 | InternetGatewayAttachment:
74 | Type: AWS::EC2::VPCGatewayAttachment
75 | Properties:
76 | InternetGatewayId: !Ref InternetGateway
77 | VpcId: !Ref VPC
78 |
79 | PublicSubnet1:
80 | Type: AWS::EC2::Subnet
81 | Properties:
82 | VpcId: !Ref VPC
83 | AvailabilityZone: !Select [ 0, !GetAZs '' ]
84 | CidrBlock: !Ref PublicSubnet1CIDR
85 | MapPublicIpOnLaunch: true
86 | Tags:
87 | - Key: Name
88 | Value: Public Subnet (AZ1)
89 |
90 | PublicSubnet2:
91 | Type: AWS::EC2::Subnet
92 | Properties:
93 | VpcId: !Ref VPC
94 | AvailabilityZone: !Select [ 1, !GetAZs '' ]
95 | CidrBlock: !Ref PublicSubnet2CIDR
96 | MapPublicIpOnLaunch: true
97 | Tags:
98 | - Key: Name
99 | Value: Public Subnet (AZ2)
100 |
101 | PrivateSubnet1:
102 | Type: AWS::EC2::Subnet
103 | Properties:
104 | VpcId: !Ref VPC
105 | AvailabilityZone: !Select [ 0, !GetAZs '' ]
106 | CidrBlock: !Ref PrivateSubnet1CIDR
107 | MapPublicIpOnLaunch: false
108 | Tags:
109 | - Key: Name
110 | Value: Private Subnet (AZ1)
111 |
112 | PrivateSubnet2:
113 | Type: AWS::EC2::Subnet
114 | Properties:
115 | VpcId: !Ref VPC
116 | AvailabilityZone: !Select [ 1, !GetAZs '' ]
117 | CidrBlock: !Ref PrivateSubnet2CIDR
118 | MapPublicIpOnLaunch: false
119 | Tags:
120 | - Key: Name
121 | Value: Private Subnet (AZ2)
122 |
123 | NatGateway1EIP:
124 | Type: AWS::EC2::EIP
125 | DependsOn: InternetGatewayAttachment
126 | Properties:
127 | Domain: vpc
128 |
129 | NatGateway2EIP:
130 | Type: AWS::EC2::EIP
131 | DependsOn: InternetGatewayAttachment
132 | Properties:
133 | Domain: vpc
134 |
135 | NatGateway1:
136 | Type: AWS::EC2::NatGateway
137 | Properties:
138 | AllocationId: !GetAtt NatGateway1EIP.AllocationId
139 | SubnetId: !Ref PublicSubnet1
140 |
141 | NatGateway2:
142 | Type: AWS::EC2::NatGateway
143 | Properties:
144 | AllocationId: !GetAtt NatGateway2EIP.AllocationId
145 | SubnetId: !Ref PublicSubnet2
146 |
147 | PublicRouteTable:
148 | Type: AWS::EC2::RouteTable
149 | Properties:
150 | VpcId: !Ref VPC
151 | Tags:
152 | - Key: Name
153 | Value: Public Routes
154 |
155 | DefaultPublicRoute:
156 | Type: AWS::EC2::Route
157 | DependsOn: InternetGatewayAttachment
158 | Properties:
159 | RouteTableId: !Ref PublicRouteTable
160 | DestinationCidrBlock: 0.0.0.0/0
161 | GatewayId: !Ref InternetGateway
162 |
163 | PublicSubnet1RouteTableAssociation:
164 | Type: AWS::EC2::SubnetRouteTableAssociation
165 | Properties:
166 | RouteTableId: !Ref PublicRouteTable
167 | SubnetId: !Ref PublicSubnet1
168 |
169 | PublicSubnet2RouteTableAssociation:
170 | Type: AWS::EC2::SubnetRouteTableAssociation
171 | Properties:
172 | RouteTableId: !Ref PublicRouteTable
173 | SubnetId: !Ref PublicSubnet2
174 |
175 |
176 | PrivateRouteTable1:
177 | Type: AWS::EC2::RouteTable
178 | Properties:
179 | VpcId: !Ref VPC
180 | Tags:
181 | - Key: Name
182 | Value: Private Routes (AZ1)
183 |
184 | DefaultPrivateRoute1:
185 | Type: AWS::EC2::Route
186 | Properties:
187 | RouteTableId: !Ref PrivateRouteTable1
188 | DestinationCidrBlock: 0.0.0.0/0
189 | NatGatewayId: !Ref NatGateway1
190 |
191 | PrivateSubnet1RouteTableAssociation:
192 | Type: AWS::EC2::SubnetRouteTableAssociation
193 | Properties:
194 | RouteTableId: !Ref PrivateRouteTable1
195 | SubnetId: !Ref PrivateSubnet1
196 |
197 | PrivateRouteTable2:
198 | Type: AWS::EC2::RouteTable
199 | Properties:
200 | VpcId: !Ref VPC
201 | Tags:
202 | - Key: Name
203 | Value: Private Routes (AZ2)
204 |
205 | DefaultPrivateRoute2:
206 | Type: AWS::EC2::Route
207 | Properties:
208 | RouteTableId: !Ref PrivateRouteTable2
209 | DestinationCidrBlock: 0.0.0.0/0
210 | NatGatewayId: !Ref NatGateway2
211 |
212 | PrivateSubnet2RouteTableAssociation:
213 | Type: AWS::EC2::SubnetRouteTableAssociation
214 | Properties:
215 | RouteTableId: !Ref PrivateRouteTable2
216 | SubnetId: !Ref PrivateSubnet2
217 |
218 | WebServerPrefixList:
219 | Type: AWS::EC2::PrefixList
220 | Properties:
221 | PrefixListName: "WebServerPrefixList"
222 | AddressFamily: "IPv4"
223 | MaxEntries: 10
224 | Entries:
225 | - Cidr: !Ref AllowedIP
226 | Description: "AllowedIP"
227 |
228 | WebServerSecurityGroup:
229 | Type: AWS::EC2::SecurityGroup
230 | Properties:
231 | GroupName: "web-server-sg"
232 | GroupDescription: "Security Group for Web Servers"
233 | VpcId: !Ref VPC
234 | SecurityGroupIngress:
235 | - IpProtocol: tcp
236 | SourceSecurityGroupId: !Ref ALBSecurityGroup
237 | FromPort: 80
238 | ToPort: 80
239 |
240 | # Internal ALB
241 | InternalALBListener:
242 | Type: AWS::ElasticLoadBalancingV2::Listener
243 | Properties:
244 | DefaultActions:
245 | - Type: forward
246 | TargetGroupArn:
247 | Ref: WebServerTargetGroup
248 | LoadBalancerArn:
249 | Ref: InternalApplicationLoadBalancer
250 | Port: 80
251 | Protocol: HTTP
252 |
253 | InternalApplicationLoadBalancer:
254 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer
255 | Properties:
256 | Scheme: internal
257 | Subnets:
258 | - Ref: PrivateSubnet1
259 | - Ref: PrivateSubnet2
260 | SecurityGroups:
261 | - Ref: ALBSecurityGroup
262 |
263 | # Internal ALB Security Group with Allowed IP prefix
264 | ALBSecurityGroup:
265 | Type: AWS::EC2::SecurityGroup
266 | Properties:
267 | GroupDescription: 'int-alb-with-ga-sg'
268 | VpcId:
269 | Ref: VPC
270 | SecurityGroupIngress:
271 | - IpProtocol: tcp
272 | SourcePrefixListId: !Ref WebServerPrefixList
273 | FromPort: 80
274 | ToPort: 80
275 |
276 | WebServerTargetGroup:
277 | Type: AWS::ElasticLoadBalancingV2::TargetGroup
278 | Properties:
279 | HealthCheckIntervalSeconds: 5
280 | HealthCheckProtocol: HTTP
281 | HealthCheckTimeoutSeconds: 3
282 | HealthyThresholdCount: 3
283 | Matcher:
284 | HttpCode: '200'
285 | Name: WebServerTargetGroup
286 | Port: 80
287 | Protocol: HTTP
288 | TargetGroupAttributes:
289 | - Key: deregistration_delay.timeout_seconds
290 | Value: '10'
291 | UnhealthyThresholdCount: 3
292 | VpcId:
293 | Ref: 'VPC'
294 |
295 | LaunchConfigWebServer:
296 | Type: AWS::AutoScaling::LaunchConfiguration
297 | Properties:
298 | ImageId: !Ref LatestLinux2AmiId
299 | IamInstanceProfile: !Ref WebServerInstanceProfile
300 | SecurityGroups:
301 | - Ref: WebServerSecurityGroup
302 | InstanceType: t3.micro
303 | UserData: !Base64 |
304 | #!/bin/bash -x
305 | yum update -y
306 | yum install httpd -y
307 | sudo amazon-linux-extras install -y php7.2
308 | service httpd start
309 | chkconfig httpd on
310 | cd /var/www/html
311 | cat <<'EOT' >> /var/www/html/index.php
312 | ';
314 | echo 'HTTP_X_FORWARDED_FOR: ';
315 | print_r($_SERVER['HTTP_X_FORWARDED_FOR']);
316 | echo '';
317 | exit;
318 | ?>
319 | EOT
320 | EbsOptimized: "true"
321 |
322 |
323 | AutoScalingWebServer:
324 | Type: AWS::AutoScaling::AutoScalingGroup
325 | Properties:
326 | VPCZoneIdentifier:
327 | - !Ref PrivateSubnet1
328 | - !Ref PrivateSubnet2
329 | LaunchConfigurationName: !Ref LaunchConfigWebServer
330 | MinSize: '1'
331 | MaxSize: '1'
332 | HealthCheckGracePeriod: 300
333 | MaxInstanceLifetime: 2592000
334 | TargetGroupARNs:
335 | - !Ref WebServerTargetGroup
336 |
337 | ### WebServer IAM Role
338 | WebServerRole:
339 | Type: AWS::IAM::Role
340 | Properties:
341 | RoleName:
342 | Fn::Join:
343 | - '-'
344 | - ['webserver-role', !Ref "AWS::Region"]
345 | AssumeRolePolicyDocument:
346 | Version: 2012-10-17
347 | Statement:
348 | -
349 | Effect: Allow
350 | Principal:
351 | Service:
352 | - ec2.amazonaws.com
353 | Action:
354 | - sts:AssumeRole
355 | Path: /
356 | ManagedPolicyArns:
357 | - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM
358 | Policies:
359 | -
360 | PolicyName: !Join [ -, ['webserver-policy', !Ref "AWS::Region"] ]
361 | PolicyDocument:
362 | Version: 2012-10-17
363 | Statement:
364 | -
365 | Effect: Allow
366 | Action:
367 | - ssm:GetParameter
368 | - ssm:GetParameters
369 | - ssm:DescribeParameters
370 | Resource:
371 | Fn::Join:
372 | - ':'
373 | - ["arn:aws:ssm", !Ref "AWS::Region", !Ref "AWS::AccountId", "*"]
374 |
375 | WebServerInstanceProfile:
376 | Type: AWS::IAM::InstanceProfile
377 | Properties:
378 | InstanceProfileName:
379 | Fn::Join:
380 | - '-'
381 | - ['webserver-profile', !Ref "AWS::Region"]
382 | Path: /
383 | Roles:
384 | - !Ref WebServerRole
385 |
386 | GlobalAccelerator:
387 | Type: AWS::GlobalAccelerator::Accelerator
388 | Properties:
389 | Name: WebGlobalAccelerator
390 | Enabled: true
391 |
392 | WebGAListener:
393 | Type: AWS::GlobalAccelerator::Listener
394 | Properties:
395 | AcceleratorArn: !Ref GlobalAccelerator
396 | Protocol: TCP
397 | PortRanges:
398 | - FromPort: 80
399 | ToPort: 80
400 |
401 | GlobalAcceleratorEndpointGroup:
402 | Type: AWS::GlobalAccelerator::EndpointGroup
403 | Properties:
404 | ListenerArn:
405 | Ref: WebGAListener
406 | EndpointGroupRegion:
407 | Ref: "AWS::Region"
408 | TrafficDialPercentage: 100
409 | EndpointConfigurations:
410 | - EndpointId: !Ref InternalApplicationLoadBalancer
411 | ClientIPPreservationEnabled: true
412 | Weight: 100
413 |
414 | GlobalAcceleratorSGCleanUp:
415 | Type: Custom::GlobalAcceleratorSGCleanUp
416 | Properties:
417 | ServiceToken:
418 | Fn::GetAtt:
419 | - "GlobalAcceleratorSGCleanUpLambda"
420 | - "Arn"
421 |
422 | GlobalAcceleratorSGCleanUpLambdaLogGroup:
423 | Type: AWS::Logs::LogGroup
424 | Properties:
425 | LogGroupName: /aws/lambda/GlobalAcceleratorSGCleanUpLambda
426 | RetentionInDays: 30
427 |
428 | GlobalAcceleratorSGCleanUpLambdaRole:
429 | Type: AWS::IAM::Role
430 | Properties:
431 | AssumeRolePolicyDocument:
432 | Version: '2012-10-17'
433 | Statement:
434 | - Effect: Allow
435 | Principal:
436 | Service:
437 | - lambda.amazonaws.com
438 | Action:
439 | - sts:AssumeRole
440 | Path: "/"
441 | Policies:
442 | - PolicyName: !Join [ -, ['cleanup-lambda-policy', !Ref "AWS::Region"] ]
443 | PolicyDocument:
444 | Version: '2012-10-17'
445 | Statement:
446 | - Effect: Allow
447 | Action:
448 | - logs:DescribeLogStreams
449 | - logs:CreateLogStream
450 | - logs:PutLogEvents
451 | - ec2:DescribeSecurityGroups
452 | - ec2:DeleteSecurityGroup
453 | - ec2:DescribeNetworkInterfaces
454 | Resource: '*'
455 |
456 | GlobalAcceleratorSGCleanUpLambda:
457 | Type: AWS::Lambda::Function
458 | Properties:
459 | FunctionName: GlobalAcceleratorSGCleanUpLambda
460 | Handler: "index.lambda_handler"
461 | Runtime: python3.7
462 | MemorySize: 128
463 | Timeout: 60
464 | Role: !GetAtt GlobalAcceleratorSGCleanUpLambdaRole.Arn
465 | Code:
466 | ZipFile: !Sub |
467 | import json, boto3, logging, os, urllib3
468 | import cfnresponse
469 | logger = logging.getLogger()
470 | logger.setLevel(logging.INFO)
471 | VPCID = os.environ['VPCID']
472 |
473 | def lambda_handler(event, context):
474 | logger.info("event: {}".format(event))
475 | try:
476 | if event['RequestType'] == 'Delete':
477 | ec2 = boto3.client('ec2')
478 | response = ec2.describe_security_groups( Filters=[{'Name': 'vpc-id', 'Values': [ VPCID ]},{'Name': 'group-name', 'Values': [ 'GlobalAccelerator' ]}])
479 | sg_id = response.get('SecurityGroups', [{}])[0].get('GroupId', '')
480 | enis = list_network_interfaces(sg_id)
481 | count = len(enis)
482 | while True:
483 | if count == 0:
484 | ec2.delete_security_group(GroupId=sg_id)
485 | break
486 | elif event['RequestType'] == 'Create':
487 | logger.info("event: {}".format(event))
488 |
489 | sendResponseCfn(event, context, cfnresponse.SUCCESS)
490 | except Exception as e:
491 | logger.info("Exception: {}".format(e))
492 | sendResponseCfn(event, context, cfnresponse.FAILED)
493 |
494 | def sendResponseCfn(event, context, responseStatus):
495 | responseData = {}
496 | responseData['Data'] = {}
497 | cfnresponse.send(event, context, responseStatus, responseData, "CustomResourcePhysicalID")
498 |
499 | def list_network_interfaces(sg_id):
500 | # Retrieve the list network interfaces
501 | ec2 = boto3.client('ec2')
502 | try:
503 | response = ec2.describe_network_interfaces( Filters=[{'Name': 'group-id', 'Values': [ sg_id ]}])
504 | print(response)
505 | except ClientError as e:
506 | logging.error(e)
507 | return None
508 | return response['NetworkInterfaces']
509 |
510 | Environment:
511 | Variables:
512 | VPCID:
513 | !Ref VPC
514 |
515 | Outputs:
516 | GlobalAcceleratorDNSName:
517 | Description: "The Domain Name System (DNS) name that Global Accelerator creates that points to your accelerator's static IP addresses."
518 | Value: !GetAtt GlobalAccelerator.DnsName
519 |
--------------------------------------------------------------------------------