DEV Community

Cover image for Creating an AWS Lambda Function with Terraform
Josh Pollara
Josh Pollara

Posted on • Updated on

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.

Top comments (0)