Forem

Cover image for Deploying AWS SNS and Lambda with Terraform: A Step-by-Step Guide (and Fixing Errors Along the Way)
Osagie Anolu
Osagie Anolu

Posted on • Edited on

Deploying AWS SNS and Lambda with Terraform: A Step-by-Step Guide (and Fixing Errors Along the Way)

Image description

Introduction

Recently, I worked on deploying an AWS SNS Topic and an AWS Lambda function using Terraform. While the process seemed straightforward, I ran into several errors that forced me to troubleshoot and refine my approach. What started as a simple deployment turned into a valuable learning experience that I'm excited to share.

This article details my journeyβ€”from initializing Terraform to resolving permission issues, dealing with Lambda zip packaging problems, and finally cleaning up the infrastructure. If you're new to Terraform or looking for a real-world debugging experience, this one's for you! πŸ’‘


Step 1: Setting Up Terraform

The journey begins with Terraform initialization in your project directory:

terraform init
Enter fullscreen mode Exit fullscreen mode

Image description
This crucial first step downloads the required AWS provider plugins and sets up the backend for state management. It's essential to understand that this command not only creates your working directory but also establishes the foundation for your entire infrastructure deployment.

Next, I ran these essential commands:

terraform fmt
terraform validate
Enter fullscreen mode Exit fullscreen mode
  • terraform fmt: Ensures consistent formatting of Terraform files, which is crucial for maintainability and team collaboration.
  • terraform validate: Checks for syntax errors and correctness in the configuration, helping catch issues early.

Following validation, I proceeded with:

terraform plan
Enter fullscreen mode Exit fullscreen mode

This command previewed the resources Terraform would create. It's like a dry run that shows you exactly what changes will be made to your infrastructure. After carefully reviewing the plan, I proceeded with:

terraform apply
Enter fullscreen mode Exit fullscreen mode

Terraform then prompted for confirmation:

Enter a value: yes
Enter fullscreen mode Exit fullscreen mode

Image description
After confirmation, Terraform began the exciting process of provisioning resources.


Step 2: Dealing with AWS IAM Role Errors

The first major challenge appeared while trying to create an IAM role for Lambda:

Error: creating IAM Role (NBA_Lambda_Role): operation error IAM: CreateRole,
AccessDenied: User is not authorized to perform iam:CreateRole on resource.
Enter fullscreen mode Exit fullscreen mode

πŸ” Solution:
This error taught me an important lesson about AWS permissions. I discovered that my IAM user lacked the necessary permissions to create roles. To resolve this, I needed to update my IAM policies to include:

{
  "Effect": "Allow",
  "Action": "iam:CreateRole",
  "Resource": "*"
}
Enter fullscreen mode Exit fullscreen mode

After adding these permissions, I ran:

terraform apply
Enter fullscreen mode Exit fullscreen mode

This time, the IAM role was created successfully! πŸŽ‰ This experience highlighted the importance of understanding AWS IAM permissions and the principle of least privilege.


Step 3: Handling Lambda Deployment Issues

With the IAM role in place, I faced another challenge during the Lambda function deployment:

Error: reading ZIP file (nba_notifications.zip): open nba_notifications.zip: The system cannot find the file specified.
Enter fullscreen mode Exit fullscreen mode

πŸ” Solution:
This error stemmed from incorrect ZIP file creation. I initially used PowerShell to generate the ZIP:

Compress-Archive -Path nba_notifications.py -DestinationPath nba_notifications.zip
Enter fullscreen mode Exit fullscreen mode

However, a quick check revealed the ZIP file was only 138 bytesβ€”clearly something was wrong! To investigate further, I extracted the ZIP:

Expand-Archive -Path nba_notifications.zip -DestinationPath temp_zip_contents -Force
Get-ChildItem temp_zip_contents
Enter fullscreen mode Exit fullscreen mode

The investigation revealed that nba_notifications.py was empty! πŸ€¦πŸ½β€β™‚οΈ This taught me the importance of verifying package contents before deployment.

After properly creating the ZIP file with all necessary contents and dependencies, I ran:

terraform apply
Enter fullscreen mode Exit fullscreen mode

Finally, success! The Lambda function was deployed correctly. πŸš€


Image description

Step 4: Adding SNS Subscriptions

With both Lambda and the SNS topic successfully created, it was time to set up notifications. Adding subscriptions requires careful attention to detail.

Detailed Steps for Adding a Subscription:

  1. Navigate to the AWS SNS Console in your AWS Management Console.
  2. Locate and click on your newly created SNS topic.
  3. Find the Subscriptions tab and click Create subscription.
  4. Select your desired protocol (Email/SMS), carefully enter the recipient details.
  5. For Email subscriptions, ensure recipients know to check their inbox and confirm the subscription.

Image description
This process may seem simple, but attention to detail is crucial for successful notification delivery. βœ‰οΈ


Step 5: Testing Lambda and SNS Notifications

Image description
Thorough testing is essential for ensuring reliable notifications:

Image description

Complete Lambda Testing Process:

  1. Open the AWS Lambda Console and locate your function.
  2. Click the Test button to create a new test event.
  3. Configure a test event that matches your expected input.
  4. Execute the test and monitor the response.
  5. Check CloudWatch Logs for detailed execution information.
  6. Verify that subscribed users receive expected notifications. πŸ””

This testing phase helped identify and fix several edge cases in my Lambda function's logic.


Step 6: Cleaning Up AWS Resources

Proper cleanup is crucial to avoid unnecessary AWS charges. Here's my detailed cleanup process:

terraform destroy
Enter fullscreen mode Exit fullscreen mode

Terraform displays all resources marked for deletion and requests confirmation:

Do you really want to destroy all resources? Only 'yes' will be accepted.
Enter fullscreen mode Exit fullscreen mode

After typing:

yes
Enter fullscreen mode Exit fullscreen mode

Terraform begins removing resources in the correct order, ensuring no dependency conflicts. A few minutes later, all AWS resources were successfully cleaned up! 🎯

Image description

Conclusion: Key Takeaways and Best Practices

  1. IAM Permissions Are Fundamental β†’ Always start by ensuring your IAM user has the correct permissions for your planned operations.
  2. Package Verification Is Critical β†’ Never assume a ZIP file is correctly created; always verify its contents and size.
  3. SNS Subscription Management Requires Attention β†’ Remember that email subscriptions need manual confirmation from recipients.
  4. CloudWatch Logs Are Essential for Debugging β†’ Make checking logs a habit when troubleshooting Lambda functions.
  5. Resource Cleanup Is Non-Negotiable β†’ Always clean up test resources to avoid unexpected AWS charges.

Through this experience, I learned that deploying AWS services with Terraform is both powerful and challenging. While the tool itself is straightforward, real-world implementations often require careful troubleshooting and attention to detail. I hope this guide helps others navigate similar challenges more effectively. πŸš€


πŸ’¬ Have you encountered similar challenges with Terraform? Share your experiences and solutions in the comments below!

Top comments (4)

Collapse
 
js_4500c85b37e0b profile image
js seniapat

Can you please share the real time terraform working docs for AWS services and also share the real time environment issues whatever you are facing in or working knowledge and how would you resolve those issues followed steps.

Collapse
 
js_4500c85b37e0b profile image
js seniapat

πŸ’¬ Have you encountered similar challenges with Terraform? Share your experiences and solutions in the comments below

Collapse
 
js_4500c85b37e0b profile image
js seniapat

Can you please share the terraform scripts.

Collapse
 
nolunchbreaks_22 profile image
Osagie Anolu

provider "aws" {
region = "us-east-1" # Change this to your preferred AWS region
}

resource "aws_sns_topic" "nba_notifications" {
name = "nba-game-day-notifications"
}

resource "aws_lambda_function" "nba_lambda" {
function_name = "NBA_Notifications"
role = aws_iam_role.lambda_role.arn
runtime = "python3.8"
handler = "nba_notifications.lambda_handler"
filename = "nba_notifications.zip"
}

resource "aws_iam_role" "lambda_role" {
name = "NBA_Lambda_Role"

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