How to Create and Invoke AWS Lambda function using Terraform step by step

Managing your applications on servers and Hardware has always remained a challenge for developers and system administrators, such as memory leakage, storage issues, the system stopped responding, corrupt files by human error, and many more. To avoid the above issue, consider using the most widely and cost-effective AWS serverless compute service, AWS Lambda, that lets you run code without provisioning or managing servers.

In this tutorial, you will learn how to create an AWS Lambda function and invoke it using the AWS Management console and Terraform. Now let’s dive in.

Join 50 other followers

Table of Content

  1. What is AWS Lambda ?
  2. Prerequisites
  3. How to create a basic AWS Lambda function using AWS Management console
  4. Terraform files and Terraform directory structure
  5. Building Terraform Configuration files to create AWS Lambda function
  6. Conclusion

What is AWS Lambda ?

AWS Lambda is a serverless compute services that don’t require any infrastructure to run, such as without needing any server to manage, which further saves you from leakage of memory, CPU, network, and other resources. AWS Lambda service can even scale up to tons of requests per second, and you only need to pay for the time you use it as it has a high-availability compute infrastructure.

AWS Lambda runs code that supports various languages such as Node.js, Python, Ruby, Java, Go and dot (net). AWS Lambda is generally invoked with certain events in the AWS cloud, such as:

  • Change in AWS Simple Storage service (AWS S3) such as upload, delete or update of the data.
  • Update of tables in AWS DynamoDB.
  • API Gateway requests.
  • Data process in Amazon kinesis.

Prerequisites

  • You must have AWS account in order to setup Lambda function with full access Lambda access. If you don’t have AWS account, please create a account from here AWS account.
  • Ubuntu machine to run terraform command, if you don’t have Ubuntu machine you can create an AWS EC2 instance on AWS account with 4GB RAM and at least 5GB of drive space.
  • Terraform Installed on Ubuntu Machine. If you don’t have Terraform installed refer Terraform on Windows Machine / Terraform on Ubuntu Machine
  • Ubuntu machine should have IAM role attached with Lambda function creation permissions or administrator permissions.

You may incur a small charge for creating an EC2 instance on Amazon Managed Web Service.

How to create a basic AWS Lambda function using AWS Management console

First, let’s kick off this tutorial by creating an AWS Lambda function using the AWS Management console. Later in this tutorial, you will create it using the most widely used automation tool Terraform. Let’s start.

  • Open AWS management console and on the top search for Lambda.
Searching for AWS Lambda in the AWS management console
Searching for AWS Lambda in the AWS management console
  • Once Lambda page opens click on the create function button on the right side of the page.
Creating the AWS Lambda function in the AWS management console
Creating the AWS Lambda function in the AWS management console
  • Next, choose Author from scratch as a function type & provide the following details and click on Create function button.
    • Name of function as AWSLambdafunctiondemo
    • Choose Runtime as Python 3.9 or later.
Creating the AWS Lambda function in the AWS management console
Creating the AWS Lambda function in the AWS management console
  • Once the AWS Lambda function is created successfully created, click on TEST button as shown below. Test button test the default hello-world code that already exists in the function.
Verifying the AWS Lambda function in the AWS management console
Verifying the AWS Lambda function in the AWS management console

Terraform files and Terraform directory structure

Now that you know what is Amazon Elastic search and Amazon OpenSearch service are. Let’s now dive into Terraform files and Terraform directory structure that will help you write the Terraform configuration files later in this tutorial.

Terraform code, that is, Terraform configuration files, are written in a tree-like structure to ease the overall understanding of code with .tf format or .tf.json or .tfvars format. These configuration files are placed inside the Terraform modules.

Terraform modules are on the top level in the hierarchy where configuration files reside. Terraform modules can further call another child to terraform modules from local directories or anywhere in disk or Terraform Registry.

Terraform contains mainly five files as main.tf , vars.tf , providers.tf , output.tf and terraform.tfvars.

  1. main.tf – Terraform main.tf file contains the main code where you define which resources you need to build, update or manage.
  2. vars.tf – Terraform vars.tf file contains the input variables which are customizable and defined inside the main.tf configuration file.
  3. output.tf : The Terraform output.tf file is the file where you declare what output paraeters you wish to fetch after Terraform has been executed that is after terraform apply command.
  4. .terraform: This directory contains cached provider , modules plugins and also contains the last known backend configuration. This is managed by terraform and created after you run terraform init command.
  5. terraform.tfvars files contains the values which are required to be passed for variables that are refered in main.tf and actually decalred in vars.tf file.
  6. providers.tf – The povider.tf is the most important file whrere you define your terraform providers such as terraform aws provider, terraform azure provider etc to authenticate with the cloud provider.

Building Terraform Configuration files to create AWS Lambda function

Now that you know what are Terraform configurations files look like and how to declare each of them. In this section, you will learn how to build Terraform configuration files to create AWS Lambda function before running Terraform commands. Let’s get into it.

  • Log in to the Ubuntu machine using your favorite SSH client.
  • Create a folder in home directory named terraform-lambda-demo and switch to that folder.
mkdir ~/terraform-lambda-demo
cd ~/terraform-lambda-demo
  • Create a file named main.tf inside the ~/terraform-lambda-demo directory and copy/paste the below content. The below file creates the below components:
    • Creates IAM role and IAM policy that will be assumed by AWS Lambda to invoke a function.
    • Creates the AWS Lambda function.
    • Creates the AWS Lambda version layer. AWS Layer is a .zip file archive that contains libraries, a custom runtime, or other dependencies that keeps your deployment package small and easily deploys. AWS Lambda Layers allow you to reuse code across multiple lambda functions.
    • Creates the permissions of AWS Lambda function.
# Creating the IAM role and attach a policy so that Lambda can assume the role

resource "aws_iam_role" "lambda_role" {
 count  = var.create_function ? 1 : 0
 name   = var.iam_role_lambda
 assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

# Generating the IAM Policy document in JSON format.

data "aws_iam_policy_document" "doc" {
  statement {
  actions    = var.actions
  effect     = "Allow"
  resources  = ["*"]
    }
}

# Creating IAM policy for AWS lambda function using previously generated JSON

resource "aws_iam_policy" "iam-policy" {
 count        = var.create_function ? 1 : 0
  name         = var.iam_policy_name
  path         = "/"
  description  = "IAM policy for logging from a lambda"
  policy       = data.aws_iam_policy_document.doc.json
}

# Attaching IAM policy on the newly created on IAM role.

resource "aws_iam_role_policy_attachment" "policy_attach" {
  count       = var.create_function ? 1 : 0
  role        = join("", aws_iam_role.lambda_role.*.name)
  policy_arn  = join("", aws_iam_policy.iam-policy.*.arn)
}

resource "aws_lambda_layer_version" "layer_version" {
  count                  = length(var.names) > 0 && var.create_function ? length(var.names) : 0
  filename              = length(var.file_name) > 0 ?  element(var.file_name,count.index) : null
  layer_name          = element(var.names, count.index)
  compatible_runtimes = element(var.compatible_runtimes, count.index)
}

# Generates an archive from content, a file, or directory of files.

data "archive_file" "default" {
  count            = var.create_function && var.filename != null ? 1 : 0
  type              = "zip"
  source_dir     = "${path.module}/files/"
  output_path  = "${path.module}/myzip/python.zip"
}

# Create a lambda function

resource "aws_lambda_function" "lambda-func" {
  count                           = var.create_function ? 1 :0
  filename                       = var.filename != null ? "${path.module}/myzip/python.zip"  : null
  function_name             = var.function_name
  role                               = join("",aws_iam_role.lambda_role.*.arn)
  handler                         = var.handler
  layers                            = aws_lambda_layer_version.layer_version.*.arn
  runtime                        = var.runtime
  depends_on                 = [aws_iam_role_policy_attachment.policy_attach]
}

# Giving permssions to cloudwatch event, SNS or S3 to access the Lambda function.

resource "aws_lambda_permission" "default" {
  count   = length(var.lambda_actions) > 0 && var.create_function ? length(var.lambda_actions) : 0
  action        = element(var.lambda_actions,count.index)
  function_name = join("",aws_lambda_function.lambda-func.*.function_name)
  principal     = element(var.principal,count.index)
}
  • Create one more file named vars.tf inside the ~/terraform-lambda-demo directory and copy/paste below content. This file contains all the variables that are referred in the main.tf configuration file.Now create another file vars.tf which should contains all the variables.
variable "create_function" {
  description = "Controls whether Lambda function should be created"
  type = bool
  default = true  
}

variable "iam_role_lambda" {}
variable "runtime" {}
variable "handler" {}
variable "actions" {
  type = list(any)
  default = []
  description = "The actions for Iam Role Policy."
}
 
variable "iam_policy_name" {}
variable "function_name" {}
variable "names" {
  type        = list(any)
  default     = []
  description = "A unique name for your Lambda Layer."
}
 
variable "file_name" {
  type        = list(any)
  default     = []
  description = "A unique file_name for your Lambda Layer."
}

variable "filename" {}
 
variable "create_layer" {
  description = "Controls whether layer should be created"
  type = bool
  default = false  
}
 
variable "lambda_actions" {
  type        = list(any)
  default     = []
  description = "The AWS Lambda action you want to allow in this statement. (e.g. lambda:InvokeFunction)."
}
 
variable "principal" {
  type        = list(any)
  default     = []
  description = "Valid AWS service principal such as events.amazonaws.com ,sns.amazonaws.com or s3.amazonaws.com."
}
 
variable "compatible_runtimes" {
  type        = list(any)
  default     = []
  description = "A list of Runtimes "
}

  • Create one more file terraform.tfvars inside the same folder and copy/paste the below content. This file contains the values of the variables that you declared in vars.tf file and refered in main.tf file.
iam_role_lambda = "iam_role_lambda"
actions = [
    "logs:CreateLogStream",
    "logs:CreateLogGroup",
    "logs:PutLogEvents"
]
lambda_actions = [
     "lambda:InvokeFunction"
  ]
principal= [
      "events.amazonaws.com" , "sns.amazonaws.com"
]
compatible_runtimes = [
     ["python3.8"]
]
runtime  = "python3.8"
iam_policy_name = "iam_policy_name"
 names = [
    "python_layer"
  ]
file_name = ["myzip/python.zip" ]  
filename = "files"   
handler = "index.lambda_handler"
function_name = "terraformfunction"
  • Now create a folder named files in the ~/terraform-lambda-demo directory and index.py inside the folder and copy/paste the below content.
import os
import json

def lambda_handler(event, context):
    json_region = os.environ['AWS_REGION']
    return {
        "statusCode": 200,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": json.dumps({
            "Region ": json_region
        })
    }

  • Now the folder structure of all the files should like as shown below.
Folder structure of all the files in the terraform-lambda-demo
The folder structure of all the files in the terraform-lambda-demo
  • Now your files and code are ready for execution. Initialize the terraform using the terraform init command.
terraform init
Initializing the terraform using the terraform init command.
Initializing the terraform using the terraform init command.
  • Terraform initialized successfully , now its time to run the plan command which provides you the details of the deployment. Run terraform plan command to confirm if correct resources is going to provisioned or deleted.
terraform plan
Running the terraform plan command
Running the terraform plan command
  • After verification, now its time to actually deploy the code using terraform apply command.
terraform apply
Running the terraform apply command
Running the terraform apply command

Terraform commands terraform init→ terraform plan→ terraform apply all executed successfully. But it is important to manually verify the AWS Lambda function on the AWS Management console.

  • Open your favorite web browser and navigate to the AWS Management Console and log in.
  • While in the Console, click on the search bar at the top, search for ‘Lambda’, and click on the Functions menu item.
Verifying the AWS Lambda function that Terraform created
Verifying the AWS Lambda function that Terraform created
  • Invoke the AWS Lambda function and validate as you did previously. After yoy execute you will see proper response from python application.
Verifying the AWS Lambda function response
Verifying the AWS Lambda function response

Join 50 other followers

Conclusion

In this tutorial, you learned what AWS Lambda is how to create AWS Lambda using AWS Management console and Terraform.

Lambda is an AWS serverless and cost-effective service widely used everywhere and will help you get started with this in the organization. So what do you plan to deploy on your newly created AWS Lambda function?

Advertisement