Terraform is a software tool used for infrastructure as code. Infrastructure as Code (IaC) is a technique to provision computing infrastructure using machine-readable code files. Terraform can provision infrastructure on your machine or any cloud provider. Terraform automatically constructs the infrastructure from code without any manual intervention. Configuring the infrastructure manually can be error-prone; it reduces manual labor and ensures the infrastructure can be provisioned anytime required.
Terraform uses configuration files to provision infrastructure. These files are guides on what to configure. They are used to create, modify, and update the infrastructure. To understand more in-depth how terraform works, read What is Terraform?
Now that we have revised what Terraform is let’s jump into the day’s main task.
First, we’ll create an IAM role with an AWS-managed policy. The role allows us to invoke the Lambda function and access it from resources or anywhere in the world. Then, create the function URL of the lambda function. We will use the lambda function to return a web page using the function URL.
Function URL is the entry point for triggering the Lambda function, allowing external services or applications to invoke the function over HTTP or HTTPS protocols. AWS dynamically generates and manages the function URL, providing a scalable and accessible means to execute serverless functions.
After completing this task, the provisioned infrastructure should look like the one shown in the figure below:
We’ll create an IAM role for our Lambda function and then create the Lambda function. We start by creating a trust policy to attach to our role, LambdaRole
, using the data block. Let’s start by creating a role for a lambda function.
data "aws_iam_policy_document" "assume_role" {statement {effect = "Allow"principals {type = "Service"identifiers = ["lambda.amazonaws.com"]}actions = ["sts:AssumeRole"]}}resource "aws_iam_role" "LambdaRole" {name = "LambdaRole"assume_role_policy = data.aws_iam_policy_document.assume_role.json}resource "aws_iam_role_policy_attachment" "LambdaRoleAttachment" {policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"role = aws_iam_role.LambdaRole.name}
Let’s take a look at the above code and understand it block by block.
Line 1–12: This block defines an IAM policy document that allows AWS Lambda service (lambda.amazonaws.com
) to assume roles. It’s used for granting permissions to the Lambda function.
Line 14–17: This block creates an IAM role named “LambdaRole” with the assumed role policy defined by the data block above.
Line 18–21: This block attaches the AWSLambdaBasicExecutionRole
policy to the IAM role created above. This policy provides basic permissions for Lambda execution.
We have created the IAM role. Now, we will create a lambda function, LambdaFunction
, and upload the code using the data block.
data "archive_file" "lambda" {type = "zip"source_file = "index.js"output_path = "lambda_function_payload.zip"}resource "aws_lambda_function" "LambdaFunction" {filename = "lambda_function_payload.zip"function_name = "LambdaFunction"role = aws_iam_role.LambdaRole.arnhandler = "index.handler"source_code_hash = data.archive_file.lambda.output_base64sha256runtime = "nodejs20.x"}
Let’s take a look at the above code and understand it block by block.
Line 1–5: This block archives the contents of the file lambda.py
into a zip file named lambda_function_payload.zip
. This is used as the deployment package for the Lambda function.
Line 7–17: This block creates an AWS Lambda function named “LambdaFunction” using the deployment package from the archive block. It specifies the IAM role, handler, and runtime (Python 3.11).
Lastly, we will create the function URL and use the output block to display the function invoke URL. Function URL is a dedicated HTTP(S) URL, which is the entry point for triggering the Lambda function.
resource "aws_lambda_function_url" "LambdaFunction" {function_name = aws_lambda_function.LambdaFunction.function_nameauthorization_type = "NONE"}output "function_url" {value = aws_lambda_function_url.LambdaFunction.function_url}
Let’s take a look at the above code and understand it block by block.
Line 1–4: This block creates a URL for the Lambda function. The function is set to have no authorization ("NONE"
).
Line 5–7: This block defines an output variable named “function_url” that outputs the function URL of our LambdaFunction
.
We have put together the above-discussed code and a new Terraform provider block that uses credentials to access the mentioned AWS account and deploy infrastructure in the specified region.
export const handler = async (event) => { try { // Read the HTML file const htmlContent = ` <!DOCTYPE html> <html> <head> <title>My Web Page</title> </head> <body> <h1>Hello from AWS Lambda!</h1> <p>This is a web page served by Lambda.</p> </body> </html> `; return { statusCode: 200, headers: { 'Content-Type': 'text/html', }, body: htmlContent, }; } catch (error) { console.error('Error reading HTML file:', error); return { statusCode: 500, body: 'Internal Server Error', }; } };
Click the “Run” button and set environment variables for the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
using your actual credentials. The syntax varies slightly depending on your operating system:
export AWS_ACCESS_KEY_ID="<Your_actual_access_key_id>"export AWS_SECRET_ACCESS_KEY="<Your_actual_secret_access_key>""
Type the following command to initialize the terraform directory, terraform init
is used to resolve and install dependencies. After initializing the directory, use terraform plan
to see the execution plan; it’s an optional step. After this, execute the configuration file using terraform apply
, it asks for confirmation, then type yes
, and then Terraform will create the requested infrastructure.
terraform initterraform apply
Copy the function URL from the terminal and paste it into the address bar of the new web page.
Congratulations!. Our application is live.
Free Resources