Lambda Function URL

Sign Up to Build

About this Architecture

Here is some information about this architecture.

One of the really cool features of Lambda is the ability to initiate it via a URL. This is a handy feature that can be used for simple use cases.

In this solution, we will show you how to deploy a Lambda function via Terraform, and configure it to respond to URL requests.

How to Build This Solution

Here are the steps you can follow to build this solution on your own.

Get Your AWS Credentials

If you're using the Skillmix Labs feature, open the lab settings (the beaker icon) on the right side of the code editor. Then, click the Start Lab button to start hte lab environment.

Wait for the credentials to load. Then run this in the terminal:

$ aws configure --profile smx-lab
AWS Access Key ID [None]: AKIA3E3W34P42CSHXDH5
AWS Secret Access Key [None]: vTmqpOqefgJfse8i6QwzgpjgswPjHZ6h/oiQq4zf
Default region name [None]: us-west-2
Default output format [None]: json

Be sure to name your credentials profile 'smx-lab'.

Note: If you're using your own AWS account you'll need to ensure that you've created and configured a named AWS CLI profile named smx-lab.

Create the Terraform File

We'll be doing all of our work in one Terraform file. Create a new directory on your computer somewhere, and then create a file named main.tf in it.

Create the Terraform & Provider Block

Next, we will create a Terraform configuration that will allow us to use the AWS provider. This configuration will require us to specify the version of the AWS provider that we want to use, as well as the version of Terraform that we are using. We will also specify the AWS profile and region that we want to use. This code will ensure that the correct versions of Terraform and the AWS provider are used, and that the AWS provider is configured correctly.

Append this code to the main.tf file:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.21"
    }
  }

  required_version = "~> 1.2"
}

provider "aws" {
  profile = "smx-temp"
  region  = "us-west-2"
}

Create the Data Resource Blocks

Next, we will create two data sources that will allow us to access information about the current AWS account and region. The first data source, "aws_caller_identity", will provide us with information about the current AWS account, such as the account ID and user ARN. The second data source, "aws_region", will provide us with information about the current AWS region, such as the region name and endpoint.

Append this code to the main.tf file:

data "aws_caller_identity" "current" {}

data "aws_region" "current" {}

Create the Lambda Function

Next, we will create an AWS Lambda function. This code will create a Lambda function called "FURLFunction" with a handler of "app.handler" and a runtime of "nodejs14.x". The source code for the Lambda function will be stored in an archive file and the source code hash will be stored in a base64sha256 format. Finally, the code will assign an IAM role to the Lambda function.

Append this code to the main.tf file:

resource "aws_lambda_function" "lambda_function" {
  function_name    = "FURLFunction"
  filename         = data.archive_file.lambda_zip_file.output_path
  source_code_hash = data.archive_file.lambda_zip_file.output_base64sha256
  handler          = "app.handler"
  role             = aws_iam_role.lambda_iam_role.arn
  runtime          = "nodejs14.x"
}

Create the Lambda Archive File Resource

Next, we will create an archive file resource. This resource will take a source file, in this case the app.js file, and compress it into a zip file. The output path of the zip file is specified in the output_path argument. This zip file can then be used to deploy a Lambda function.

Append this code to the main.tf file:

data "archive_file" "lambda_zip_file" {
  type        = "zip"
  source_file = "${path.module}/src/app.js"
  output_path = "${path.module}/lambda.zip"
}

Create the Lambda Node.js File

We will now create the actual JavaScript file that will be used for the Lambda function. In the project directory, create a folder named src. In that folder, create a file named app.js and add the following code to it. This code will return some basic response information when called.

/*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *  SPDX-License-Identifier: MIT-0
 */

'use strict'

exports.handler = async (event) => {
  // Lambda handler code
  return {
    body: `Hello World`,
    statusCode: 200,
  }
}

Create the Lambda IAM Policy

Next, we will create a data resource for the AWS managed IAM policy named "AWSLambdaBasicExecutionRole". This policy is used to grant the necessary permissions to an AWS Lambda function so that it can execute properly. The data resource will allow us to reference the policy in our Terraform code.

Append this code to the main.tf file:

data "aws_iam_policy" "lambda_basic_execution_role_policy" {
  name = "AWSLambdaBasicExecutionRole"
}

Create the Lambda IAM Role

Next, we will create an IAM role for our Lambda function using the Terraform code above. This code will create an IAM role with the name prefix "LambdaFunctionRole-", and it will attach a managed policy to the role. The assume role policy will also be set, which will allow the Lambda service to assume the role and access the resources associated with it.

Append this code to the main.tf file:

resource "aws_iam_role" "lambda_iam_role" {
  name_prefix = "LambdaFunctionRole-"
  managed_policy_arns = [data.aws_iam_policy.lambda_basic_execution_role_policy.arn]

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

Create the Lambda Function URL Resource

Next, we will create an AWS Lambda Function URL resource. This resource will allow us to create a URL that can be used to access the Lambda function we created. The function_name parameter will be set to the name of the Lambda function we created, and the authorization_type will be set to AWS_IAM. Finally, we will set the cors parameter to allow all origins to access the URL.

Append this code to the main.tf file:

resource "aws_lambda_function_url" "function_url" {
  function_name      = aws_lambda_function.lambda_function.function_name
  authorization_type = "AWS_IAM"

  cors {
    allow_origins     = ["*"]
  }
}

Create Outputs

Lastly, we will create some outputs. Append this code to the main.tf to output the function ARN and endpoint URL.

output "FunctionARN" {
  value       = aws_lambda_function.lambda_function.arn
  description = "Lambda function name"
}

output "FunctionUrlEndpoint" {
  value       = aws_lambda_function_url.function_url.function_url
  description = "Lambda function url"
}

Deploying the Project

Now that we have all of our code written, we can deploy the project. Open a terminal, navigate to the project, and run these commands.

# initialize the project 
$ terraform init 

# plan the project 
$ terraform plan 

# apply the project 
$ terraform apply

Test the Project

To test the project, simply open the Function URL endpoint in your browser. It should return a successful status.

Destroy the Project

Run the destroy command to end it all

$ terraform destroy