Creating an AWS Lambda Function with Terraform

joshpollara

Josh Pollara

Posted on February 16, 2023

Creating an AWS Lambda Function with Terraform

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"
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"]
  }
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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]
  }
}
Enter fullscreen mode Exit fullscreen mode

Verify Changes

View the changes to be deployed to your AWS account

$ terraform init
$ terraform validate
$ terraform plan
Enter fullscreen mode Exit fullscreen mode

Apply Changes

Create the AWS resources defined in your main.tf

$ terraform apply
Enter fullscreen mode Exit fullscreen mode

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.

đź’– đź’Ş đź™… đźš©
joshpollara
Josh Pollara

Posted on February 16, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related