Josh Pollara
Posted on February 16, 2023
Creating an AWS Lambda Function with Terraform
Writing the proper Terraform code for an AWS Lambda function may seem like a daunting task but it doesn't have to be.
While there are a few moving parts to the process, I'll explain how to deploy a Lambda function to a VPC that can access other resources within your VPC using
appropriate IAM permissions.
Full code example here: https://github.com/terrateamio/terraform-aws-lambda-example
main.tf
The below resources are examples and should be adjusted to suit your needs. The code can be added to your Terraform repository in a file named main.tf
.
Provider
Add the aws
provider
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
region = "us-west-2"
}
VPC
Create a new VPC
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "example-vpc"
}
}
Subnets
Create at least one subnet
resource "aws_subnet" "example" {
cidr_block = "10.0.1.0/24"
vpc_id = aws_vpc.example.id
availability_zone = "us-west-2b"
tags = {
Name = "example-subnet"
}
}
Security Group
Create a security group
resource "aws_security_group" "example" {
name_prefix = "example-sg"
vpc_id = aws_vpc.example.id
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["10.0.1.0/24"]
}
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
IAM Role and Policy
Create an IAM role and policy
resource "aws_iam_role" "example" {
name = "example-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}
resource "aws_iam_policy" "example" {
name = "example-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = ["arn:aws:logs:*:*:*"]
},{
Effect = "Allow"
Action = [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"
]
Resource = ["*"]
}]
})
}
resource "aws_iam_role_policy_attachment" "example" {
policy_arn = aws_iam_policy.example.arn
role = aws_iam_role.example.name
}
This IAM role and policy allows your Lambda function to create, describe, and delete network interfaces, and create and push logs to CloudWatch.
Lambda Function
The last step is to create your actual Lambda function
resource "aws_lambda_function" "example" {
function_name = "example-lambda"
filename = "lambda_function_payload.zip"
source_code_hash = filebase64sha256("lambda_function_payload.zip")
handler = "index.handler"
role = aws_iam_role.example.arn
runtime = "nodejs14.x"
vpc_config {
subnet_ids = [aws_subnet.example.id]
security_group_ids = [aws_security_group.example.id]
}
}
Verify Changes
View the changes to be deployed to your AWS account
$ terraform init
$ terraform validate
$ terraform plan
Apply Changes
Create the AWS resources defined in your main.tf
$ terraform apply
Conclusion
By following these steps, you can deploy an AWS Lambda function to a VPC with all the proper IAM permissions. Check out Terrateam to learn how to safely plan
and apply
infrastructure changes alongside other code and with your teammates.
Posted on February 16, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.