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

Managing your applications on server and Hardware has always remained a challenge for developers and system administrators. Some of the challenges are Memory leak, storage issues , system stopped responding , corrupt files by human error and many more. To avoid this AWS launched most widely and cost effective “server less” service which is AWS Lambda, which works almost with all code languages.

AWS Lambda doesn’t require any Hardware or servers to work on , it works on server less technology. So In this tutorial we will learn how to create Lambda function and invoke it using AWS Management console and Terraform. Now lets dive in.

Table of Content

  1. What is AWS Lambda ?
  2. Prerequisites
  3. How to create a basic Lambda function using AWS Management console
  4. How to Install terraform on ubuntu 18.04 LTS ?
  5. Terraform Configuration Files and Structure
  6. Configure terraform files to build AWS Lambda using Terraform
  7. Conclusion

What is AWS Lambda ?

AWS Lambda is a server less AWS service which doesn’t require any infrastrure to run. AWS Lambda service runs code without needing any server to manage that. It is a very scalable service when required it can even scale up to tons of request per second. The Best part with this service is whatever time we use it we just need to pay for that. With this service you don’t require any kind of administration such as managing memory, CPU, network and other resources.

AWS Lambda runs code which support various languages such as Node.js , Python , Ruby , Java , Go & dot (net) . AWS Lambda is generally used with certain events such as

  • Change in AWS S3 ( Simple Storage service ) data like upload, delete or update.
  • Update of any tables in DynamoDB
  • API Gateway requests
  • Any data process in Amazon kinesis

AWS Lambda allows you to create function and later you need to invoke Lambda function and later then monitor it with logs or data traces.

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, if you don’t have any machine you can create a ec2 instance on AWS account
  • Recommended to have 4GB RAM
  • At least 5GB of drive space
  • Ubuntu machine should have IAM role attached with Lambda function creation permissions or it is always great to have administrator permissions to work with demo’s.

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

How to create a basic Lambda function using AWS Management console

  • Open AWS management console and on the top and search for Lambda
  • Once Lambda page opens click on Create function
  • Now, For demo we will use Author from scratch as a function type & Provide the name of function , Language in which you would like to code & finally click on Create function
  • After function is successfully created , click on TEST
  • Now enter the name of event
  • Now, again click on TEST

It confirms that demo and a very basic sample AWS Lambda is created and invoked succesfully.

How to Install Terraform on Ubuntu 18.04 LTS

  • Update your already existing system packages.
sudo apt update
  • Download the latest version of terraform in opt directory
wget https://releases.hashicorp.com/terraform/0.14.8/terraform_0.14.8_linux_amd64.zip
This image has an empty alt attribute; its file name is image-163.png
  • Install zip package which will be required to unzip
sudo apt-get install zip -y
  • unzip the Terraform download zip file
unzip terraform*.zip
  • Move the executable to executable directory
sudo mv terraform /usr/local/bin
  • Verify the terraform by checking terraform command and version of terraform
terraform               # To check if terraform is installed 

terraform -version      # To check the terraform version  
This image has an empty alt attribute; its file name is image-164.png
This image has an empty alt attribute; its file name is image-165.png
  • This confirms that terraform has been successfully installed on ubuntu 18.04 machine.

Terraform Configuration Files and Structure

Let us first understand terraform configuration files before running Terraform commands.

  • main.tf : This file contains code that create or import other AWS resources.
  • vars.tf : This file defines variable types and optionally set the values.
  • output.tf: This file helps in generating of the output of AWS resources .The output is generated after the terraform apply command is executed.
  • terraform.tfvars: This file contains the actual values of variables which we created in vars.tf
  • provider.tf: This file is very important . You need to provide the details of providers such as AWS , Oracle or Google etc. so that terraform can make the communication with the same provider and then work with resources.

Configure Terraform files to build AWS Lambda using Terraform

In this demonstration we will create IAM role and IAM policy which we will be assumed by Lambda to invoke a function . Later in this tutorial we will create and invoke Lambda function with proper configurations . Lets get started and configure terraform files which are required for creation of AWS Lambda function on AWS account.

  • Create a folder inside opt directory
mkdir /opt/terraform-lambda-demo
cd /opt/terraform-lambda-demo
  • Now create a file main.tf inside the directory you’re in
vi main.tf
  • Paste the below content in main.tf file

main.tf

# To Create 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
}
# Generates IAM Policy document in JSON format.

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

# IAM policy for logging from a lambda

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
}

# Policy Attachment on 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)
}

# Lambda Layers allow you to reuse code across multiple lambda functions.
# Layer is a .zip file archive that contains libraries, a custom runtime, or other dependencies      # Layers let you keep your deployment package small, which makes development easier

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]
}

# Give External source (like CloudWatch Event, SNS or S3) permission 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)

}
  • Now create another file vars.tf which should contains all the variables.

vars.tf

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 = "The principal who is getting this permission. e.g. s3.amazonaws.com, an AWS account ID, or any valid AWS service principal such as events.amazonaws.com or sns.amazonaws.com."
}
 
variable "compatible_runtimes" {
  type        = list(any)
  default     = []
  description = "A list of Runtimes this layer is compatible with. Up to 5 runtimes can be specified."
}
  • Next is to set the values of variables which we declared earlier in vars.tf. Lets create another file and name it terraform.tfvars

terraform.tfvars

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 directory called files inside /opt/terraform-lambda-demo and create a file inside it and name it index.py
cd /opt/terraform-lambda-demo
mkdir files/
cd /opt/terraform-lambda-demo/files/index.py

NOTE: We will use Python for this Lambda function

  • Paste the below Python code in /opt/terraform-lambda-demo/files/index.py which will be executed.
# index.py

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
        })
    }
  • Your folder structure should like below
  • Now your files and code are ready for execution . Initialize the terraform
terraform init
  • Terraform initialized successfully , now its time to see the plan which is kind of blueprint before deployment. We generally use plan to confirm if correct resources is going to provisioned or deleted.
terraform plan
  • After verification , now its time to actually deploy the code using apply.
terraform apply
  • Let us verify in Amazon Management console if AWS Lambda function is created succesfully
  • Invoke the Lambda function and validate

Great , Lambda function is executed successfully and we can see proper response from python application.

Conclusion

In this demonstration we learnt how to create AWS Lambda using AWS Management console and invoke a Lambda function . Later in this tutorial we learnt to create and invoke Lambda function with proper configurations using Terraform.

Lambda is AWS server less and cost effective service a which is widely used everywhere and will help you get started with this in the organization. Once you are familiar with AWS Lambda I am sure you will forget using servers and code deployments on servers.

Please like and share with your friends if you like it. Hope this tutorial will be helpful.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s