Blog Archives
How to connect Amazon SNS to Lambda with Terraform
Hello everyone,
Today I wanted to share a quick code snippet of how you can connect Amazon SNS to AWS Lambda using Terraform. What I have seen on the web sometimes is never a complete solution, rather parts of code, which at the end, it doesn’t help you that much.
Hopefully, the below script should give you a complete overview of the same.
######## TERRAFORM PARAMETERS ########
variable "app_name" {
description = "The name of the application being built"
default = "data-archiving"
}
# Customer needs to change for account specifics
variable "region_primary" {
default = "eu-west-1"
}
# Customer needs to change for account specifics
variable "sns_topic_properties" {
type = object({ kms_master_key_id = string })
description = "SNS Topic"
default = {
kms_master_key_id = "alias/aws/sns"
}
}
# Customer needs to change for account specifics
variable "delete_data_lambda_function_properties" {
type = object({ filename = string, runtime = string, handler = string, timeout = number, cloudwatch_log_group_retention_in_days = number })
description = "Lambda Function"
default = {
filename = "nametest.zip"
runtime = "python3.8"
handler = "delete_data_lambda_function.lambda_handler"
timeout = 120
cloudwatch_log_group_retention_in_days = 14
}
}
### Tags
variable "tags" {
description = "A map of tags to add to all resources"
type = map(any)
default = {
deployed_by = "terraform"
}
}
######## TERRAFORM RESOURCE CREATION ########
data "aws_iam_policy_document" "lambda_assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
####### Lambda Role #######
resource "aws_iam_role" "lambda_role" {
name = format("%s-lambda-role", var.app_name)
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role_policy.json
tags = var.tags
}
resource "aws_sns_topic" "sns_archive_topic" {
name = format("%s-topic", var.app_name)
kms_master_key_id = var.sns_topic_properties.kms_master_key_id
tags = var.tags
}
data "archive_file" "python_lambda_package" {
type = "zip"
source_file = "${path.module}/code/lambda_code.py"
output_path = var.delete_data_lambda_function_properties.filename
}
resource "aws_lambda_function" "delete_data_lambda_function" {
function_name = format("%s-delete-data-lambda-function", var.app_name)
filename = var.delete_data_lambda_function_properties.filename
source_code_hash = data.archive_file.python_lambda_package.output_base64sha256
role = aws_iam_role.lambda_role.arn
runtime = var.delete_data_lambda_function_properties.runtime
handler = var.delete_data_lambda_function_properties.handler
timeout = var.delete_data_lambda_function_properties.timeout
tags = var.tags
environment {
variables = {
AWS_REGION_PRIMARY = var.region_primary
}
}
}
resource "aws_sns_topic_subscription" "lambda_topic_subscription" {
topic_arn = aws_sns_topic.sns_archive_topic.arn
protocol = "lambda"
endpoint = aws_lambda_function.delete_data_lambda_function.arn
}
resource "aws_lambda_permission" "lambda_sns_permission" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.delete_data_lambda_function.arn
principal = "sns.amazonaws.com"
source_arn = aws_sns_topic.sns_archive_topic.arn
}
resource "aws_cloudwatch_log_group" "lambda_cloudwatch_group" {
name = format("/aws/lambda/%s", aws_lambda_function.delete_data_lambda_function.function_name)
retention_in_days = var.delete_data_lambda_function_properties.cloudwatch_log_group_retention_in_days
tags = var.tags
}
I know it is lengthy code, but this gives an end to end demonstration of SNS to Lambda Trigger. The most important bit in the above code are the two resources being used: aws_sns_topic_subscription and aws_lambda_permission. Those are two that gives you the link between the services, and should allow you use them.
Be aware that I am skipping also the configuration of the AWS terraform provider of this post, as it is irrelevant for what I am trying to show. Perhaps, I will demonstrate in a later blog how to do so.
Once the solution is deployed, you should see similar thing in your account.
If you have any questions or comments, leave it in the comments section of this post.
Happy coding!
Marcos Freccia