From Launch to Management: How to Handle AWS SNS Using Terraform


Deploying and Managing AWS SNS with Terraform


Amazon Simple Notification Service (SNS) is a fully managed messaging service that facilitates communication between distributed systems by sending messages to subscribers via various protocols such as HTTP/S, email, SMS, and AWS Lambda. By using Terraform, you can automate the creation, configuration, and management of SNS topics and subscriptions, integrating them seamlessly into your infrastructure-as-code (IaC) workflows.

This article will guide you through launching and managing AWS SNS with Terraform, and will also show you how to create a Terraform module for easier reuse and scalability.

Prerequisites

Before you start, ensure that you have:

  • An AWS Account with the necessary permissions to create and manage SNS topics and subscriptions.
  • Terraform Installed on your local machine.
  • AWS CLI Configured with your credentials.

Step 1: Set Up Your Terraform Project

Begin by creating a directory for your Terraform project:

mkdir sns-terraform
cd sns-terraform
touch main.tf

In the main.tf file, define the AWS provider:

provider "aws" {
  region = "us-east-1"  # Specify the AWS region
}

Step 2: Create and Manage an SNS Topic

Creating an SNS Topic

Define an SNS topic resource:

resource "aws_sns_topic" "example_topic" {
  name = "example-sns-topic"
  tags = {
    Environment = "Production"
    Team        = "DevOps"
  }
}

This creates an SNS topic named example-sns-topic, tagged for easier management.

Configuring Topic Attributes

You can manage additional attributes for your SNS topic, such as a display name or delivery policy:

resource "aws_sns_topic" "example_topic" {
  name         = "example-sns-topic"
  display_name = "Example SNS Topic"

  delivery_policy = jsonencode({
    defaultHealthyRetryPolicy = {
      minDelayTarget   = 20,
      maxDelayTarget   = 20,
      numRetries       = 3,
      backoffFunction  = "exponential"
    }
  })
}

Step 3: Add and Manage SNS Subscriptions

Subscriptions define the endpoints that receive messages from the SNS topic.

Email Subscription

resource "aws_sns_topic_subscription" "email_subscription" {
  topic_arn = aws_sns_topic.example_topic.arn
  protocol  = "email"
  endpoint  = "your-email@example.com"
}

SMS Subscription

resource "aws_sns_topic_subscription" "sms_subscription" {
  topic_arn = aws_sns_topic.example_topic.arn
  protocol  = "sms"
  endpoint  = "+1234567890"  # Replace with your phone number
}

Lambda Subscription

resource "aws_lambda_function" "example_lambda" {
  function_name = "exampleLambda"
  handler       = "index.handler"
  runtime       = "nodejs18.x"
  role          = aws_iam_role.lambda_exec_role.arn
  filename      = "lambda_function.zip"
}

resource "aws_sns_topic_subscription" "lambda_subscription" {
  topic_arn = aws_sns_topic.example_topic.arn
  protocol  = "lambda"
  endpoint  = aws_lambda_function.example_lambda.arn
}

resource "aws_lambda_permission" "allow_sns" {
  statement_id  = "AllowExecutionFromSNS"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.example_lambda.function_name
  principal     = "sns.amazonaws.com"
  source_arn    = aws_sns_topic.example_topic.arn
}

Step 4: Manage SNS Access Control with IAM Policies

Control access to your SNS topic with IAM policies:

resource "aws_iam_role" "sns_publish_role" {
  name = "sns-publish-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Action    = "sts:AssumeRole",
      Effect    = "Allow",
      Principal = {
        Service = "sns.amazonaws.com"
      }
    }]
  })
}

resource "aws_iam_role_policy" "sns_publish_policy" {
  name   = "sns-publish-policy"
  role   = aws_iam_role.sns_publish_role.id

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Action   = "sns:Publish",
      Effect   = "Allow",
      Resource = aws_sns_topic.example_topic.arn
    }]
  })
}

Step 5: Apply the Terraform Configuration

With your SNS resources defined, apply the Terraform configuration:

  1. Initialize the project:
   terraform init
  1. Preview the changes:
   terraform plan
  1. Apply the configuration:
   terraform apply

Confirm the prompt to create the resources.

Step 6: Create a Terraform Module for SNS

To make your SNS setup reusable, you can create a Terraform module. Modules encapsulate reusable Terraform configurations, making them easier to manage and scale.

  1. Create a Module Directory:
   mkdir -p modules/sns
  1. Define the Module: Inside the modules/sns directory, create main.tf, variables.tf, and outputs.tf files.

main.tf:

resource "aws_sns_topic" "sns_topic" {
  name = var.topic_name
  tags = var.tags
}

resource "aws_sns_topic_subscription" "sns_subscriptions" {
  count    = length(var.subscriptions)
  topic_arn = aws_sns_topic.sns_topic.arn
  protocol  = var.subscriptions[count.index].protocol
  endpoint  = var.subscriptions[count.index].endpoint
}

variables.tf:

variable "topic_name" {
  type        = string
  description = "Name of the SNS topic"
}

variable "subscriptions" {
  type = list(object({
    protocol = string
    endpoint = string
  }))
  description = "List of subscriptions"
}

variable "tags" {
  type        = map(string)
  description = "Tags for the SNS topic"
  default     = {}
}

outputs.tf:

output "sns_topic_arn" {
  value = aws_sns_topic.sns_topic.arn
}
  1. Use the Module in Your Main Configuration: In your main main.tf file, call the module:
   module "sns" {
     source        = "./modules/sns"
     topic_name    = "example-sns-topic"
     subscriptions = [
       {
         protocol = "email"
         endpoint = "your-email@example.com"
       },
       {
         protocol = "sms"
         endpoint = "+1234567890"
       }
     ]
     tags = {
       Environment = "Production"
       Team        = "DevOps"
     }
   }

Step 7: Update and Destroy Resources

To update resources, modify the module inputs or other configurations and reapply:

terraform apply

To delete resources managed by the module, run:

terraform destroy

Amazon SNS Mobile Push Notifications, which is part of Amazon Simple Notification Service (SNS), allows you to send push notifications to mobile devices across multiple platforms, including Android, iOS, and others.

AWS SNS Mobile Push Notifications

With Amazon SNS Mobile Push Notifications, you can create platform applications for various push notification services like Apple Push Notification Service (APNs) for iOS, Firebase Cloud Messaging (FCM) for Android, and others. These platform applications can be managed using the aws_sns_platform_application resource in Terraform, as described in your original configuration.

Key Components

  • Platform Applications: These represent the push notification service you are using (e.g., APNs for iOS, FCM for Android).
  • Endpoints: These represent individual mobile devices registered with the platform application.
  • Messages: The notifications that you send to these endpoints.

Example Configuration for AWS SNS Mobile Push Notifications

Below is an example of setting up an SNS platform application for Android (using FCM) with Terraform:

resource "aws_sns_platform_application" "android_application" {
  name                             = "MyAndroidApp${var.environment}"
  platform                         = "GCM" # Use GCM for FCM
  platform_credential              = var.fcm_api_key # Your FCM API Key
  event_delivery_failure_topic_arn = aws_sns_topic.delivery_failure.arn
  event_endpoint_created_topic_arn = aws_sns_topic.endpoint_created.arn
  event_endpoint_deleted_topic_arn = aws_sns_topic.endpoint_deleted.arn
  event_endpoint_updated_topic_arn = aws_sns_topic.endpoint_updated.arn
}

resource "aws_sns_topic" "delivery_failure" {
  name = "sns-delivery-failure"
}

resource "aws_sns_topic" "endpoint_created" {
  name = "sns-endpoint-created"
}

resource "aws_sns_topic" "endpoint_deleted" {
  name = "sns-endpoint-deleted"
}

resource "aws_sns_topic" "endpoint_updated" {
  name = "sns-endpoint-updated"
}

Comparison with GCM/FCM

  • Google Cloud Messaging (GCM) / Firebase Cloud Messaging (FCM): This is Google’s platform for sending push notifications to Android devices. It requires a specific API key (token) for authentication.
  • Amazon SNS Mobile Push: SNS abstracts the differences between platforms (GCM/FCM, APNs, etc.) and provides a unified way to manage push notifications across multiple platforms using a single interface.

Benefits of AWS SNS Mobile Push Notifications

  1. Cross-Platform Support: Manage notifications across multiple mobile platforms (iOS, Android, Kindle, etc.) from a single service.
  2. Integration with AWS Services: Easily integrate with other AWS services like Lambda, CloudWatch, and IAM.
  3. Scalability: Automatically scales to support any number of notifications and endpoints.
  4. Event Logging: Monitor delivery statuses and other events using SNS topics and CloudWatch.

Conclusion

By combining Terraform’s power with AWS SNS, you can efficiently launch, manage, and automate your messaging infrastructure. The Terraform module further simplifies and standardizes the deployment, making it reusable and scalable across different environments. With this setup, you can easily integrate SNS into your infrastructure-as-code strategy, ensuring consistency and reliability in your cloud operations.

AWS SNS Mobile Push Notifications serves as the AWS counterpart to GCM/FCM, providing a powerful, scalable solution for managing push notifications to mobile devices. With Terraform, you can automate the setup and management of SNS platform applications, making it easier to handle push notifications within your AWS infrastructure.

, ,