In today’s blog post, I really need to share with you all a quick tip regarding Terraform’s aws_lambda_function resource and how to make the latest local data archive_file to be present when planning/deploying Terraform infrastructure. So, let’s dive straight into it.
Prerequisites
- Terraform
Scenario
Step 1. Take a look at the following Terraform code:
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}
resource "local_file" "lambda_function" {
content = templatefile("${path.module}/lambda/test.py.tpl", {
region = var.region
})
filename = "${path.module}/lambda/test.py"
file_permission = 0644
directory_permission = 0755
}
data "archive_file" "lambda_function" {
type = "zip"
source_file = "${path.module}/lambda/test.py"
output_file_mode = "0644"
output_path = "${path.module}/files/lambda-test.zip"
depends_on = [
local_file.lambda_function
]
}
module "lambda_function" {
source = "../modules/lambda"
function_name = "lambda_function_name"
role = aws_iam_role.iam_for_lambda.arn
filename = data.archive_file.lambda_function.output_path
handler = "test.lambda_handler"
source_code_hash = filebase64sha256(data.archive_file.lambda_function.output_path)
}
Step 2. Create an execution plan.
terraform plan
Expected output:
Error: Error in function call
│
│ on main.tf line 94, in module "lambda_function":
│ 94: source_code_hash = filebase64sha256(data.archive_file.lambda_function.output_path)
│ ├────────────────
│ │ data.archive_file.lambda_function.output_path is "./files/lambda-test.zip"
│
│ Call to function "filebase64sha256" failed: open files/lambda-test.zip: no such file or directory.
╵
As you can see, the terraform plan
command failed because it couldn’t find the lambda-test.zip
file, since it’s not created yet. This is because the built-in functions are not part of the dependency handling even if we add a depends_on
block.
In the example above, the filebase64sha256 function will check if the file is statically present in the configuration, not along the way, during the terraform plan
execution.
Solution
Lucky for us, the archive_file
data exports an output_base64sha256 attribute, which can be used as a source_code_hash value.
Step 1. Update the source_code_hash
parameter line with the following one:
module "lambda_function" {
...
source_code_hash = data.archive_file.lambda_function.output_base64sha256
...
}
Step 2. Create and deploy the Terraform execution plan.
terraform plan && terraform apply --auto-approve
Conclusion
Instead of deploying locally created archive files, uploading and pulling packages from a S3 bucket would be a more resilient, redundant and definitely a preferable approach. Or even better, you could always use container images instead of deployment packages.
Feel free to leave a comment below and if you find this tutorial useful, follow our official channel on Telegram.