Skip to content

Commit bfe2e6a

Browse files
author
Ben Smith
authored
Merge pull request #1507 from sumitsays19/sumitsays19-newpattern-terraform
New serverless pattern - alb-lambda-terraform
2 parents 8307feb + c02479b commit bfe2e6a

File tree

8 files changed

+334
-0
lines changed

8 files changed

+334
-0
lines changed

alb-lambda-terraform/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.js
2+
!jest.config.js
3+
*.d.ts
4+
node_modules
5+
!/lib

alb-lambda-terraform/.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.ts
2+
!*.d.ts
3+

alb-lambda-terraform/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Application Load balancer with AWS Lambda as target with Terraform
2+
3+
This pattern demonstrates how to create an Application Load Balancer with AWS Lambda as target. Implemented in Terraform.
4+
5+
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/alb-lambda-terraform
6+
7+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
8+
9+
## Requirements
10+
11+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
12+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
13+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14+
* [Terraform Installed](https://developer.hashicorp.com/terraform/downloads)
15+
16+
## Deployment Instructions
17+
18+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
19+
```
20+
git clone https://github.com/aws-samples/serverless-patterns
21+
```
22+
2. Change directory to the pattern directory:
23+
```
24+
cd alb-lambda-terraform
25+
```
26+
3. From the command line, run:
27+
```
28+
terraform init
29+
```
30+
4. From the command line, run:
31+
```
32+
terraform plan
33+
```
34+
5. From the command line, run:
35+
```
36+
terraform apply --auto-approve
37+
```
38+
39+
## Testing
40+
41+
1. In the stack output, you can see `alb_url`. When you access the url, you should see the response "Hello World" from Lambda.
42+
43+
** Please note: Application Load Balancer's default settings for health check are 5 consecutive health check successes with 35 seconds interval. So, it will take couple of minutes for the target to be healthy.
44+
45+
## Cleanup
46+
47+
1. To delete the stack, run:
48+
```bash
49+
terraform destroy --auto-approve
50+
```
51+
----
52+
Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
53+
54+
SPDX-License-Identifier: MIT-0
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"title": "Application Load Balancer with Lambda as target",
3+
"description": "Create an Application Load Balancer with Lambda as target using Terraform",
4+
"language": "TypeScript",
5+
"level": "200",
6+
"framework": "Terraform",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This sample project demonstrates how to create an Application Load Balancer with AWS Lambda as target.",
11+
"Implemented in Terraform."
12+
]
13+
},
14+
"gitHub": {
15+
"template": {
16+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/alb-lambda-terraform",
17+
"templateURL": "serverless-patterns/alb-lambda-terraform",
18+
"projectFolder": "alb-lambda-terraform",
19+
"templateFile": "alb-lambda-terraform/main.tf"
20+
}
21+
},
22+
"resources": {
23+
"bullets": [
24+
{
25+
"text": "Application Load Balancer",
26+
"link": "https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html"
27+
},
28+
{
29+
"text": "ALB - Lambda target",
30+
"link": "https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html"
31+
}
32+
]
33+
},
34+
"deploy": {
35+
"text": [
36+
"terraform init",
37+
"terraform apply"
38+
]
39+
},
40+
"testing": {
41+
"text": [
42+
"See the Github repo for detailed testing instructions."
43+
]
44+
},
45+
"cleanup": {
46+
"text": [
47+
"terraform destroy",
48+
"terraform show"
49+
]
50+
},
51+
"authors": [
52+
{
53+
"name": "Sumit Bhati",
54+
"image": "https://avatars.githubusercontent.com/u/139027745",
55+
"bio": "I am a Customer Solutions Manager at AWS"
56+
}
57+
]
58+
}

alb-lambda-terraform/lambda.zip

583 Bytes
Binary file not shown.

alb-lambda-terraform/main.tf

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Required providers configuration
2+
terraform {
3+
required_providers {
4+
aws = {
5+
source = "hashicorp/aws"
6+
version = "~>4.52.0"
7+
}
8+
}
9+
10+
required_version = "~> 1.0"
11+
}
12+
13+
# AWS provider configuration
14+
provider "aws" {
15+
profile = "default"
16+
region = "us-east-1"
17+
}
18+
19+
# Create AWS VPC
20+
resource "aws_vpc" "vpc" {
21+
cidr_block = var.vpc_cidr
22+
23+
}
24+
25+
# Create public subnet 1
26+
resource "aws_subnet" "public_subnet1" {
27+
cidr_block = "10.0.1.0/24"
28+
vpc_id = aws_vpc.vpc.id
29+
availability_zone = "${var.region}a"
30+
tags = {
31+
Name = "Subnet for ${var.region}a"
32+
}
33+
}
34+
35+
# Create public subnet 2
36+
resource "aws_subnet" "public_subnet2" {
37+
cidr_block = "10.0.2.0/24"
38+
vpc_id = aws_vpc.vpc.id
39+
availability_zone = "${var.region}b"
40+
tags = {
41+
Name = "Subnet for ${var.region}b"
42+
}
43+
}
44+
45+
# Create a route table
46+
resource "aws_route_table" "public_rt" {
47+
vpc_id = aws_vpc.vpc.id
48+
49+
route {
50+
cidr_block = "0.0.0.0/0"
51+
gateway_id = aws_internet_gateway.gw.id
52+
}
53+
54+
tags = {
55+
Name = "public_rt"
56+
}
57+
}
58+
59+
# Associate the route table with public subnet 1
60+
resource "aws_route_table_association" "public_rt_table_a" {
61+
subnet_id = aws_subnet.public_subnet1.id
62+
route_table_id = aws_route_table.public_rt.id
63+
}
64+
65+
# Associate the route table with public subnet 2
66+
resource "aws_route_table_association" "public_rt_table_b" {
67+
subnet_id = aws_subnet.public_subnet2.id
68+
route_table_id = aws_route_table.public_rt.id
69+
}
70+
71+
# Create an Internet Gateway
72+
resource "aws_internet_gateway" "gw" {
73+
vpc_id = aws_vpc.vpc.id
74+
}
75+
76+
# Create IAM Role for Lambda Function
77+
resource "aws_iam_role" "lambda_role" {
78+
name = "Lambda_Function_Role"
79+
assume_role_policy = <<EOF
80+
{
81+
"Version": "2012-10-17",
82+
"Statement": [
83+
{
84+
"Action": "sts:AssumeRole",
85+
"Principal": {
86+
"Service": "lambda.amazonaws.com"
87+
},
88+
"Effect": "Allow",
89+
"Sid": ""
90+
}
91+
]
92+
}
93+
EOF
94+
}
95+
96+
# Create IAM policy for Lambda to write logs
97+
resource "aws_iam_policy" "iam_policy_for_lambda" {
98+
99+
name = "aws_iam_policy_for_terraform_aws_lambda_role"
100+
path = "/"
101+
description = "AWS IAM Policy for managing aws lambda role"
102+
policy = <<EOF
103+
{
104+
"Version": "2012-10-17",
105+
"Statement": [
106+
{
107+
"Action": [
108+
"logs:CreateLogGroup",
109+
"logs:CreateLogStream",
110+
"logs:PutLogEvents"
111+
],
112+
"Resource": "arn:aws:logs:*:*:*",
113+
"Effect": "Allow"
114+
}
115+
]
116+
}
117+
EOF
118+
}
119+
120+
# Attach the IAM policy for writing logs to the Lambda Role
121+
resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role" {
122+
role = aws_iam_role.lambda_role.name
123+
policy_arn = aws_iam_policy.iam_policy_for_lambda.arn
124+
}
125+
126+
# Create a security group for application load balancer
127+
resource "aws_security_group" "load_balancer_sg" {
128+
name = "myLoadBalancerSG"
129+
vpc_id = aws_vpc.vpc.id
130+
ingress {
131+
from_port = 80
132+
to_port = 80
133+
protocol = "tcp"
134+
cidr_blocks = ["0.0.0.0/0"]
135+
}
136+
tags = {
137+
Name = "myLoadBalancerSG"
138+
}
139+
}
140+
141+
# Create the application load balancer
142+
resource "aws_lb" "load_balancer" {
143+
name = "myLoadBalancer"
144+
internal = false
145+
load_balancer_type = "application"
146+
security_groups = [aws_security_group.load_balancer_sg.id]
147+
subnets = [aws_subnet.public_subnet1.id,aws_subnet.public_subnet2.id]
148+
tags = {
149+
Name = "myLoadBalancer"
150+
}
151+
}
152+
153+
# Create the ALB listener with the target group.
154+
resource "aws_lb_listener" "listener" {
155+
load_balancer_arn = aws_lb.load_balancer.arn
156+
port = 80
157+
protocol = "HTTP"
158+
default_action {
159+
type = "forward"
160+
target_group_arn = "${aws_lb_target_group.target_group.arn}"
161+
}
162+
}
163+
164+
# Create the ALB target group for Lambda
165+
resource "aws_lb_target_group" "target_group" {
166+
name = "myLoadBalancerTargets"
167+
target_type = "lambda"
168+
vpc_id = aws_vpc.vpc.id
169+
}
170+
171+
# Attach the ALB target group to the Lambda Function
172+
resource "aws_lb_target_group_attachment" "target_group_attachment" {
173+
target_group_arn = aws_lb_target_group.target_group.arn
174+
target_id = aws_lambda_function.lambda_function.arn
175+
}
176+
177+
# Create the Lambda Function
178+
resource "aws_lambda_function" "lambda_function" {
179+
function_name = "lambdaFunction"
180+
runtime = "nodejs14.x"
181+
handler = "index.handler"
182+
filename = "lambda.zip"
183+
role = aws_iam_role.lambda_role.arn
184+
depends_on = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]
185+
tags = {
186+
Name = "lambdaFunction"
187+
}
188+
}
189+
190+
# Allow the application load balancer to access Lambda Function
191+
resource "aws_lambda_permission" "with_lb" {
192+
statement_id = "AllowExecutionFromlb"
193+
action = "lambda:InvokeFunction"
194+
function_name = aws_lambda_function.lambda_function.arn
195+
principal = "elasticloadbalancing.amazonaws.com"
196+
source_arn = aws_lb_target_group.target_group.arn
197+
}

alb-lambda-terraform/outputs.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Output value definitions
2+
3+
output "alb_url" {
4+
value = "http://${aws_lb.load_balancer.dns_name}"
5+
}
6+

alb-lambda-terraform/variables.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
variable "region" {
2+
type=string
3+
description = "AWS Region where deploying resources"
4+
default = "us-east-1"
5+
}
6+
7+
variable "vpc_cidr" {
8+
type=string
9+
description = "CIDR block for Batch VPC"
10+
default = "10.0.0.0/16"
11+
}

0 commit comments

Comments
 (0)