DEV Community

Cover image for Why Learn Cloud/AWS? AWS Lambda, API Gateway, IAM Role, Policy with Hands-on Sample
Ömer Berat Sezer
Ömer Berat Sezer

Posted on • Edited on

2 2 2 1

Why Learn Cloud/AWS? AWS Lambda, API Gateway, IAM Role, Policy with Hands-on Sample

Mastering AWSand Infrastructure as Code (IaC) tools such as Terraform/OpenTofu opens up countless possibilities in the world of modern cloud computing. Whether you're looking to progress in your career, enhance cloud operations, or push the boundaries with innovative technologies, cloud expertise is a crucial asset in today’s tech-focused landscape.

Table of Contents

Motivation: Where Do Cloud Skills Help Us?

Cloud expertise extends beyond IT professionals, it's valuable across various domains:

  • DevOps & SRE Roles: Automating infrastructure, CI/CD pipelines, and monitoring applications.
  • Software Development: Deploying, scaling, and managing cloud-native applications.
  • Data Science & AI/ML: Leveraging cloud-based data lakes, analytics, and AI services.
  • Cybersecurity & Compliance: Securing cloud resources and ensuring regulatory compliance.
  • Enterprise IT & Digital Transformation: Driving business innovation with cloud-first strategies.
  • Freelancers & Entrepreneurs: Hosting applications, automating deployments, and reducing operational costs.

What are Lambda, IAM Role/Policy, API Gateway?

  • AWS Lambda: A serverless compute service that allows you to run code in response to events without provisioning or managing servers.

  • IAM Role: A set of permissions that define what actions an entity (like a Lambda function or EC2 instance) can performin AWS.

  • IAM Policy: A documentthat defines specific permissions for users, groups, or roles, controlling what actions are allowed or denied on AWS resources.

  • sts:AssumeRole: An action in AWS Security Token Service (STS) that allows one entity to temporarily assume a different role and inherit its permissions.

  • API Gateway: A fully managed service that enables you to create, publish, and manage APIs for accessing backend services, such as Lambda functions, securely and at scale.

  • Lambda Permission: Grants API Gateway the permission to invoke a Lambda function, enabling the API to trigger Lambda for backend processing.

Hands-on Sample

This sample shows:

  • how to create Lambda function with Python code,
  • how to create Lambda Role, Policy, Policy-Role attachment, Lambda API-gateway permission, uploading code,
  • how to create API-gateway resource and method definition, Lambda-API-gateway connection, deploying API-gateway,
  • details on AWS Lambda, API-Gateway, IAM

lambda-cloudwatch-apigw

There are 3 main parts:

  • lambda.tf: It includes lambda function, lambda role, policy, policy-role attachment, lambda api gateway permission, zipping code
  • api-gateway.tf: It includes api-gateway resource and method definition, lambda - api gateway connection, deploying api gateway, api-gateway deployment URL as output
  • code/main.py: It includes basic lambda handler with basic HTML code, and REST API response.

Code: https://github.com/omerbsezer/Fast-AWS/tree/main/hands-out-labs-code/hands-on-002-lambda-apigateway-python

Steps

  • Create lambda.tf:
    • Terraform Configuration: Specifies the AWS provider version and Terraform version.
    • IAM Role and Policy: Creates an IAM role for the Lambda function and attaches a policy that allows the Lambda function to write logs to CloudWatch.
    • Zipping Lambda Code: Prepares the Python code by zipping it into a format that Lambda can execute.
    • Lambda Function: Creates a Lambda function using the specified IAM role, , and runtime.
    • API Gateway Integration: Grants API Gateway permission to invoke the Lambda function.
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
  required_version = ">= 1.2.0"
}

# Create IAM Role for lambda
resource "aws_iam_role" "lambda_role" {
 name   = "aws_lambda_role"
 assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

# IAM policy for the lambda
resource "aws_iam_policy" "iam_policy_for_lambda" {

  name         = "aws_iam_policy_for_aws_lambda_role"
  path         = "/"
  description  = "AWS IAM Policy for managing aws lambda role"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

# Role - Policy Attachment
resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role" {
  role        = aws_iam_role.lambda_role.name
  policy_arn  = aws_iam_policy.iam_policy_for_lambda.arn
}

# Zipping the , lambda wants the  as zip file
data "archive_file" "zip_the_python_" {
 type        = "zip"
 source_dir  = "${path.module}//"
 output_path = "${path.module}//main.zip"
}

# Lambda Function, in terraform ${path.module} is the current directory.
resource "aws_lambda_function" "lambda_function" {
 filename                       = "${path.module}//main.zip"
 function_name                  = "Lambda-Function"
 role                           = aws_iam_role.lambda_role.arn
 handler                        = "main.lambda_handler"
 runtime                        = "python3.8"
 depends_on                     = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]
}

# With Lambda permission, API Gateway can invoke Lambda 
resource "aws_lambda_permission" "apigw" {
 statement_id  = "AllowAPIGatewayInvoke"
 action        = "lambda:InvokeFunction"
 function_name = aws_lambda_function.lambda_function.function_name
 principal     = "apigateway.amazonaws.com"
 # The "/*/*" portion grants access from any method on any resource within the API Gateway REST API.
 source_arn = "${aws_api_gateway_rest_api.example.execution_arn}/*/*"
}
Enter fullscreen mode Exit fullscreen mode

Code: https://github.com/omerbsezer/Fast-AWS/tree/main/hands-out-labs-code/hands-on-002-lambda-apigateway-python/lambda.tf

  • Create api-gateway.tf:
    • Proxy Usage: The {proxy+} path is used to dynamically route all requests to the Lambda function, eliminating the need to define individual paths and methods.
    • Flexibility: The ANY method allows all HTTP methods, making the API flexible.
    • AWS_PROXY Integration: Simplifies the interaction between API Gateway and Lambda by passing the entire request data to Lambda, allowing it to process dynamically.
# Create API Gateway with Rest API type
resource "aws_api_gateway_rest_api" "example" {
  name        = "Serverless"
  description = "Serverless Application using Terraform"
}

resource "aws_api_gateway_resource" "proxy" {
   rest_api_id = aws_api_gateway_rest_api.example.id
   parent_id   = aws_api_gateway_rest_api.example.root_resource_id
   path_part   = "{proxy+}"     # with proxy, this resource will match any request path
}

resource "aws_api_gateway_method" "proxy" {
   rest_api_id   = aws_api_gateway_rest_api.example.id
   resource_id   = aws_api_gateway_resource.proxy.id
   http_method   = "ANY"       # with ANY, it allows any request method to be used, all incoming requests will match this resource
   authorization = "NONE"
}

# API Gateway - Lambda Connection
resource "aws_api_gateway_integration" "lambda" {
   rest_api_id = aws_api_gateway_rest_api.example.id
   resource_id = aws_api_gateway_method.proxy.resource_id
   http_method = aws_api_gateway_method.proxy.http_method
   integration_http_method = "POST"
   type                    = "AWS_PROXY"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service
   uri                     = aws_lambda_function.lambda_function.invoke_arn
}

# The proxy resource cannot match an empty path at the root of the API. 
# To handle that, a similar configuration must be applied to the root resource that is built in to the REST API object
resource "aws_api_gateway_method" "proxy_root" {
   rest_api_id   = aws_api_gateway_rest_api.example.id
   resource_id   = aws_api_gateway_rest_api.example.root_resource_id
   http_method   = "ANY"
   authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_root" {
   rest_api_id = aws_api_gateway_rest_api.example.id
   resource_id = aws_api_gateway_method.proxy_root.resource_id
   http_method = aws_api_gateway_method.proxy_root.http_method
   integration_http_method = "POST"
   type                    = "AWS_PROXY"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service
   uri                     = aws_lambda_function.lambda_function.invoke_arn
}

# Deploy API Gateway
resource "aws_api_gateway_deployment" "example" {
   depends_on = [
     aws_api_gateway_integration.lambda,
     aws_api_gateway_integration.lambda_root,
   ]
   rest_api_id = aws_api_gateway_rest_api.example.id
   stage_name  = "test"
}

# Output to the URL 
output "base_url" {
  value = aws_api_gateway_deployment.example.invoke_url
}
Enter fullscreen mode Exit fullscreen mode

Code: https://github.com/omerbsezer/Fast-AWS/tree/main/hands-out-labs-code/hands-on-002-lambda-apigateway-python/api-gateway.tf

  • Create main.py under code directory:
def lambda_handler(event, context):
   content = """
   <html>
   <h1> Hello Website running on Lambda! Deployed via Terraform </h1>
   </html>
   """
   response ={
     "statusCode": 200,
     "body": content,
     "headers": {"Content-Type": "text/html",}, 
   }
   return response
Enter fullscreen mode Exit fullscreen mode

Code: https://github.com/omerbsezer/Fast-AWS/tree/main/hands-out-labs-code/hands-on-002-lambda-apigateway-python/code/main.py

  • Run init, validate command:
terraform init
terraform validate
Enter fullscreen mode Exit fullscreen mode

terraform init

  • Run plan, apply command:
terraform plan   # for dry-run
terraform apply
Enter fullscreen mode Exit fullscreen mode

terraform apply

image

  • On AWS Lambda:

lambda1

lambda2

lambda3

  • Create a test by clicking "Test" for lambda function:

image

  • Status code 200, OK is returned successfully:

status ok

  • Execution Role is created, seen on Lambda

execution role

  • Role on IAM:

roles on IAM

  • Policy on IAM:

policy on IAM

  • On AWS Lambda: With Lambda permission, API Gateway can invoke Lambda

lambda permission

  • Lambda is triggered by API-Gateway:

lambda-triggered

  • On AWS API-Gateway:

api-gw

  • By clicking "Test" to test api-gateway

image

  • HTML page that runs on Lambda Function using API-Gateway can be reached. With API-Gateway, lambda function gets DNS and traffic from internet comes to the Lambda function.

html page

  • Run destroy command:
terraform destroy
Enter fullscreen mode Exit fullscreen mode

image

  • On AWS Lambda, function is deleted

Conclusion

In this post, we mentioned:

  • why should we learn Cloud/AWS, IaC/Terraform,
  • how to provision AWS Lambda, API GW, IAM Role and Policy, Assume Role,
  • how to connect Lambda, API GW,
  • how to configure API GW with Terraform,

If you found the tutorial interesting, I’d love to hear your thoughts in the blog post comments. Feel free to share your reactions or leave a comment. I truly value your input and engagement 😉

For other posts 👉 https://dev.to/omerberatsezer 🧐

Let's Discuss! 🤝

  • Why should we learn Lambda and/or API Gateway?
  • What are your popular Cloud/AWS services?

ACI image

ACI.dev: Best Open-Source Composio Alternative (AI Agent Tooling)

100% open-source tool-use platform (backend, dev portal, integration library, SDK/MCP) that connects your AI agents to 600+ tools with multi-tenant auth, granular permissions, and access through direct function calling or a unified MCP server.

Star our GitHub!

Top comments (1)

Collapse
 
omerberatsezer profile image
Ömer Berat Sezer • Edited

My popular cloud service on AWS is Bedrock nowadays. I use Bedrock to run different models (Llama 3.1 405B, Llama3.3 70B, Nova, etc.). It can also be used Bedrock with Lambda and API Gateway to build real-time GenAI apps like chatbots. API Gateway handles requests, Lambda calls Bedrock, and IAM secures it all for fully serverless and scalable.

Postmark Image

"Please fix this..."

Focus on creating stellar experiences without email headaches. Postmark's reliable API and detailed analytics make your transactional emails as polished as your product.

Start free

AWS Security LIVE!

Join AWS Security LIVE! streaming from AWS Partner Summit Hamburg

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️