Skip to content

Commit f354293

Browse files
authored
Merge pull request #2600 from MakendranG/makendrang-feature-vpc-lattice-lambda-tf
New serverless pattern - Amazon VPC Lattice with AWS Lambda as weighted targets (Terraform)
2 parents a4f34a8 + 87e3a87 commit f354293

File tree

7 files changed

+433
-0
lines changed

7 files changed

+433
-0
lines changed

vpc-lattice-lambda-tf/README.md

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Amazon VPC Lattice with AWS Lambda as weighted targets
2+
3+
This pattern demonstrates how to create a VPC Lattice which shifts traffic to different targets based on the weighted routing policy.
4+
5+
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.
6+
7+
## Requirements
8+
9+
* [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.
10+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured.
11+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
12+
* [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) installed
13+
14+
## Deployment Instructions
15+
16+
1. Create a new directory, navigate to that directory in a terminal and clone the repository:
17+
```
18+
git clone https://github.com/aws-samples/serverless-patterns
19+
```
20+
2. Change directory to the pattern directory:
21+
```
22+
cd serverless-patterns/vpc-lattice-lambda-tf
23+
```
24+
3. From the command line, initialize Terraform to downloads and install the providers defined in the configuration:
25+
```
26+
terraform init
27+
```
28+
4. From the command line, apply the configuration in the main.tf file:
29+
```
30+
terraform apply
31+
```
32+
5. Note the outputs from the deployment process. These contain the resource names and/or ARNs which are used for testing.
33+
34+
## How it works
35+
36+
VPC Lattice is to designed to help you easily and effectively discover, secure, connect, and monitor all of the services within it. Each component within VPC Lattice communicates unidirectionally or bi-directionally within the service network based on its association with the service network and its access settings. Access settings are comprised of authentication and authorization policies required for this communication.
37+
38+
This pattern creates below resources:
39+
40+
1. A new VPC with CIDR of 10.0.0.0/16
41+
2. A private subnet
42+
3. Security Group allowing inbound traffic from VPC CIDR 10.0.0.0/16
43+
4. VPC Lattice service
44+
5. VPC Lattice Listener
45+
6. VPC Lattice Service Network
46+
7. VPC Lattice Network Association and Service Association
47+
8. Two Lambda functions (Primary and Secondary) to demonstrate traffic shift.
48+
9. One Lambda function (Demo) to verify traffic shift by calling VPC lattice service DNS.
49+
50+
This pattern uses Lambda as weighted targets. VPC Lattice service shifts traffic based on the percentage of weight configured for target groups under VPC Lattice listener. User may update the weight for the targets according to their use case and requirements.
51+
52+
## Testing
53+
54+
Invoke Demo Lambda function using CLI/Console and observe traffic shift from VPC Lattice service.
55+
56+
## Cleanup
57+
58+
1. Delete all created resources by Terraform
59+
```bash
60+
terraform destroy
61+
```
62+
2. Confirm all created resources has been deleted
63+
```bash
64+
terraform show
65+
```
66+
----
67+
Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
68+
69+
SPDX-License-Identifier: MIT-0

vpc-lattice-lambda-tf/demolambda.zip

901 KB
Binary file not shown.
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"title": "Amazon VPC Lattice with AWS Lambda as weighted targets",
3+
"description": "This pattern demonstrates how to create a VPC Lattice which shifts traffic to different targets based on the weighted routing policy.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "Terraform",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"VPC Lattice is to designed to help you easily and effectively discover, secure, connect, and monitor all of the services within it. Each component within VPC Lattice communicates unidirectionally or bi-directionally within the service network based on its association with the service network and its access settings. Access settings are comprised of authentication and authorization policies required for this communication.",
11+
"This pattern uses Lambda as weighted targets. VPC Lattice service shifts traffic based on the percentage of weight configured for target groups under VPC Lattice listener. User may update the weight for the targets according to their use case and requirements."
12+
]
13+
},
14+
"gitHub": {
15+
"template": {
16+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/vpc-lattice-lambda-tf",
17+
"templateURL": "serverless-patterns/vpc-lattice-lambda-tf",
18+
"projectFolder": "vpc-lattice-lambda-tf",
19+
"templateFile": "main.tf"
20+
}
21+
},
22+
"resources": {
23+
"bullets": [
24+
{
25+
"text": "VPC Lattice Service",
26+
"link": "https://docs.aws.amazon.com/vpc-lattice/latest/ug/what-is-vpc-lattice.html"
27+
},
28+
{
29+
"text": "Lambda",
30+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/welcome.html"
31+
}
32+
]
33+
},
34+
"deploy": {
35+
"text": [
36+
"terraform init",
37+
"terraform apply"
38+
]
39+
},
40+
"testing": {
41+
"text": [
42+
"Invoke Demo Lambda function using CLI/Console and observe traffice shift from VPC Lattice service."
43+
]
44+
},
45+
"cleanup": {
46+
"text": [
47+
"<code>terraform destroy</code>",
48+
"terraform show"
49+
]
50+
},
51+
"authors": [
52+
{
53+
"name": "Makendran G",
54+
"image": "https://drive.google.com/file/d/1mUObnbmn52UWL-Zn39EpgpneiBNv3LCN/view?usp=sharing",
55+
"bio": "Cloud Support Engineer @ AWS",
56+
"linkedin": "makendran",
57+
"twitter": "@MakendranG"
58+
}
59+
]
60+
}

vpc-lattice-lambda-tf/main.tf

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# Provider Configuration
2+
provider "aws" {
3+
region = "us-east-1" # Change this to your desired region
4+
}
5+
6+
# Variables
7+
variable "vpc_cidr" {
8+
default = "10.0.0.0/16"
9+
}
10+
11+
variable "subnet_cidr" {
12+
default = "10.0.7.0/24"
13+
}
14+
15+
# VPC Resources
16+
resource "aws_vpc" "vpc_lattice_vpc" {
17+
cidr_block = var.vpc_cidr
18+
enable_dns_support = true
19+
enable_dns_hostnames = true
20+
instance_tenancy = "default"
21+
}
22+
23+
resource "aws_subnet" "vpc_subnet" {
24+
vpc_id = aws_vpc.vpc_lattice_vpc.id
25+
cidr_block = var.subnet_cidr
26+
availability_zone = "${data.aws_region.current.name}b"
27+
map_public_ip_on_launch = false
28+
29+
tags = {
30+
Name = "Private-new-availability"
31+
}
32+
}
33+
34+
# Security Group
35+
resource "aws_security_group" "vpc_lattice_sg" {
36+
name = "VPCLatticeServiceNetworkSecurityGroup"
37+
description = "Security group for VPC LatticeService"
38+
vpc_id = aws_vpc.vpc_lattice_vpc.id
39+
40+
ingress {
41+
from_port = 443
42+
to_port = 443
43+
protocol = "tcp"
44+
cidr_blocks = ["10.0.0.0/16"]
45+
}
46+
47+
egress {
48+
from_port = 443
49+
to_port = 443
50+
protocol = "tcp"
51+
cidr_blocks = ["0.0.0.0/0"]
52+
}
53+
}
54+
55+
# VPC Lattice Resources
56+
resource "aws_vpclattice_service_network" "vl_service_network" {
57+
name = "vl-test-service-network"
58+
auth_type = "NONE"
59+
}
60+
61+
resource "aws_vpclattice_service" "vl_service" {
62+
name = "vl-test-service"
63+
auth_type = "NONE"
64+
}
65+
66+
# IAM Role for Lambda Functions
67+
resource "aws_iam_role" "lambda_role" {
68+
name = "vpc_lattice_lambda_role"
69+
70+
assume_role_policy = jsonencode({
71+
Version = "2012-10-17"
72+
Statement = [
73+
{
74+
Action = "sts:AssumeRole"
75+
Effect = "Allow"
76+
Principal = {
77+
Service = "lambda.amazonaws.com"
78+
}
79+
}
80+
]
81+
})
82+
}
83+
84+
# Attach basic Lambda execution policy
85+
resource "aws_iam_role_policy_attachment" "lambda_basic" {
86+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
87+
role = aws_iam_role.lambda_role.name
88+
}
89+
90+
# Attach VPC access policy for Lambda
91+
resource "aws_iam_role_policy_attachment" "lambda_vpc" {
92+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
93+
role = aws_iam_role.lambda_role.name
94+
}
95+
96+
# Lambda Functions
97+
resource "aws_lambda_function" "vl_function_primary" {
98+
filename = "primary.zip"
99+
function_name = "vl-function-primary"
100+
role = aws_iam_role.lambda_role.arn
101+
handler = "app.lambda_handler"
102+
runtime = "python3.13"
103+
architectures = ["x86_64"]
104+
source_code_hash = filebase64sha256("primary.zip")
105+
}
106+
107+
resource "aws_lambda_function" "vl_function_secondary" {
108+
filename = "secondary.zip"
109+
function_name = "vl-function-secondary"
110+
role = aws_iam_role.lambda_role.arn
111+
handler = "app.lambda_handler"
112+
runtime = "python3.13"
113+
architectures = ["x86_64"]
114+
source_code_hash = filebase64sha256("secondary.zip")
115+
}
116+
117+
resource "aws_lambda_function" "demo_lambda" {
118+
filename = "demolambda.zip"
119+
function_name = "demo-lambda"
120+
role = aws_iam_role.lambda_role.arn
121+
handler = "app.lambda_handler"
122+
runtime = "python3.13"
123+
architectures = ["x86_64"]
124+
source_code_hash = filebase64sha256("demolambda.zip")
125+
126+
vpc_config {
127+
subnet_ids = [aws_subnet.vpc_subnet.id]
128+
security_group_ids = [aws_security_group.vpc_lattice_sg.id]
129+
}
130+
131+
environment {
132+
variables = {
133+
URL = aws_vpclattice_service.vl_service.dns_entry[0].domain_name
134+
}
135+
}
136+
}
137+
138+
# VPC Lattice Target Groups
139+
resource "aws_vpclattice_target_group" "primary_tg" {
140+
name = "vl-primary-target-group"
141+
type = "LAMBDA"
142+
143+
config {
144+
lambda_event_structure_version = "V2"
145+
}
146+
}
147+
148+
resource "aws_vpclattice_target_group_attachment" "primary_tg_attachment" {
149+
target_group_identifier = aws_vpclattice_target_group.primary_tg.id
150+
target {
151+
id = aws_lambda_function.vl_function_primary.arn
152+
}
153+
}
154+
155+
resource "aws_vpclattice_target_group" "secondary_tg" {
156+
name = "vl-secondary-target-group"
157+
type = "LAMBDA"
158+
159+
config {
160+
lambda_event_structure_version = "V2"
161+
}
162+
}
163+
164+
resource "aws_vpclattice_target_group_attachment" "secondary_tg_attachment" {
165+
target_group_identifier = aws_vpclattice_target_group.secondary_tg.id
166+
target {
167+
id = aws_lambda_function.vl_function_secondary.arn
168+
}
169+
}
170+
171+
# VPC Lattice Listener
172+
resource "aws_vpclattice_listener" "vl_listener" {
173+
name = "vl-service-listener"
174+
protocol = "HTTPS"
175+
port = 443
176+
service_identifier = aws_vpclattice_service.vl_service.id
177+
178+
default_action {
179+
forward {
180+
target_groups {
181+
target_group_identifier = aws_vpclattice_target_group.primary_tg.id
182+
weight = 60
183+
}
184+
target_groups {
185+
target_group_identifier = aws_vpclattice_target_group.secondary_tg.id
186+
weight = 40
187+
}
188+
}
189+
}
190+
}
191+
192+
# VPC Lattice Associations
193+
resource "aws_vpclattice_service_network_service_association" "service_association" {
194+
service_identifier = aws_vpclattice_service.vl_service.id
195+
service_network_identifier = aws_vpclattice_service_network.vl_service_network.id
196+
}
197+
198+
resource "aws_vpclattice_service_network_vpc_association" "vpc_association" {
199+
vpc_identifier = aws_vpc.vpc_lattice_vpc.id
200+
service_network_identifier = aws_vpclattice_service_network.vl_service_network.id
201+
security_group_ids = [aws_security_group.vpc_lattice_sg.id]
202+
}
203+
204+
# Outputs
205+
output "vl_function_primary_arn" {
206+
value = aws_lambda_function.vl_function_primary.arn
207+
}
208+
209+
output "vl_function_secondary_arn" {
210+
value = aws_lambda_function.vl_function_secondary.arn
211+
}
212+
213+
output "vl_service_network_id" {
214+
value = aws_vpclattice_service_network.vl_service_network.id
215+
}
216+
217+
output "vl_service_id" {
218+
value = aws_vpclattice_service.vl_service.id
219+
}
220+
221+
output "vl_service_dns" {
222+
value = aws_vpclattice_service.vl_service.dns_entry[0].domain_name
223+
}
224+
225+
# Data source for current region
226+
data "aws_region" "current" {}

vpc-lattice-lambda-tf/primary.zip

323 Bytes
Binary file not shown.

vpc-lattice-lambda-tf/secondary.zip

324 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)