Preface
In Terraform the aws_lambda_function has a parameter called source_code_hash. This parameter is a base64-encoded SHA256 hash of the package file specified with either filename or s3_key. The file itself is typically a zip file.
Editing your code and zipping it up over and over can become a tedious process and if you use version control, it’s better practice to just edit a single file and have it zip itself automatically for terraform to use.
The archive_file is also supported within Terraform Enterprise.
Tutorial
For this tutorial we will be creating a hello world lambda. A variables.tf is missing however in the real-world you would still likely have one.
1 Create your main.tf
This is where it gets juicy.
Create your main.tf file. In your main.tf you will have the following Terraform resources created which we will cover below.
- Lambda Function
- Lambda Role
- Lambda Role Policy for CloudWatch Logs
- Archiving Lambda Code
At this point you will have an empty main.tf file.
2 Create your lambda source code file
We will be creating a nodejs lambda. So our code will be written in javascript.
Create a file call example.js within a new folder called lambda. This “lambda” folder will also be used when terraform creates the zip file for you.
Your handler is your filename.method
. So for us it will be example.handler
, this will be used later on in the tutorial.
exports.handler = function (event, context) { context.succeed('hello world'); };
3 Create Role and policies for Lambda
Your Lambda will likely take some sort of action. For example if your Lambda is rotating access keys then your policies would allow certain IAM functionality.
Each one of your Lambda uses a Role have the permissions required to serve its purpose.
Our Lambda role should be allowed to AssumeRole for the Principal Service lambda.amazonaws.com
.
resource "aws_iam_role" "lambda_role" { name = "LambdaRole" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF }
Since this is just a simple hello world our policy is very basic. We want out our Lamba to be logged via CloudWatch logs. We want it to be able to
- Create Log Group
- Create Log Stream
- Put Log Events
resource "aws_iam_role_policy" "lambda_role_policy" { name = "LambdaRolePolicy" role = "${aws_iam_role.lambda_role.id}" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" } ] } EOF }
4 Archiving your source code file
Next, we will archive our hello world example.js
We will make our output_path
the same as the source_file
directory.
data "archive_file" "lambda_archive" { type = "zip" source_file = "${path.module}/lambda/example.js" output_path = "${path.module}/lambda/example.zip" }
5 Create your Lambda
We now have the necessary components to create our Lambda function.
Things to note:
file_name
should match your file and filepath.function_name
is just a custom name for your function.role
will be the role we created earlier.handler
like we covered before is filename.method or in our case example.handler.source_code_hash
is the base64sha256 output of our archive_fileruntime
is nodejs since our hello world is javascript.
resource "aws_lambda_function" "lambda_function" { filename = "${path.module}/lambda/example.zip" function_name = "hello_world_example" role = "${aws_iam_role.lambda_role.arn}" handler = "example.handler" source_code_hash = "${data.archive_file.lambda_archive.output_base64sha256}" runtime = "nodejs8.10" }
Conclusion
Now run your terraform fmt
to format your code, terraform plan
to make sure everything looks good, and finally terraform apply
it!
Testing via Console
Login to your AWS Console and navigate to the Lambda, find and click on your lambda
Click on test on the top right corner. Give it an Event name. The Event Template Hello World provides some inputs, but we can ignore them as they will not be used. Click on Create.
Click on test once more and it’ll run your Lambda manually.
If it was successful then it will be green.
Opening the details tab will show you more details including our hello world output
You can view the logs of your Lambda by clicking the “logs” link.
Clicking on a specific “Log Stream” will provide you information regarding the events within them.
GitHub Repository:
https://github.com/zghafari/terraform-lambda-example