Step-by-Step Guide to Creating an AWS SNS Topic with Terraform

In this article, we will create an SNS topic with an access policy that grants our account permission to perform all SNS actions on the topic using Terraform. This guide assumes a basic understanding of both SNS and Terraform. If you’re interested in creating an SNS topic using CloudFormation, check out my article here.

For a detailed list of arguments and parameters for SNS in Terraform, click here. This resource can help you customize your SNS accordingly.

Prerequisites

  1. Basic understanding of Terraform.
  2. Terraform installed on your system.
  3. An AWS Account (Create one if you don’t have an account).
  4. AWS IAM User credentials (‘access_key’ & ‘secret_key’) with permissions to create SNS topics. (Learn how to create an IAM user with the necessary credentials here.)

Steps We’ll Perform

  1. Create Terraform configuration files for the SNS topic.
  2. Use these files to create an SNS topic.
  3. Delete the SNS topic using Terraform.

Creating Terraform Configuration Files for SNS Topic

Start by creating a file named “main.tf” to define the resource. We’ll create the SNS topic in “region = eu-west-3“, but you can adjust this as needed. To simplify initial setup, don’t alter the access policy statement unless you’re familiar with access policies.

Find the code on my GitHub repository: GitHub Link.

File: main.tf
provider "aws" {
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    region = "eu-west-3"
}

resource "aws_sns_topic" "my_first_sns_topic" {
  name = var.sns_name
}

resource "aws_sns_topic_policy" "my_sns_topic_policy" {
  arn = aws_sns_topic.my_first_sns_topic.arn
  policy = data.aws_iam_policy_document.my_custom_sns_policy_document.json
}

data "aws_iam_policy_document" "my_custom_sns_policy_document" {
  policy_id = "__default_policy_ID"

  statement {
    actions = [
      "SNS:Subscribe",
      "SNS:SetTopicAttributes",
      "SNS:RemovePermission",
      "SNS:Receive",
      "SNS:Publish",
      "SNS:ListSubscriptionsByTopic",
      "SNS:GetTopicAttributes",
      "SNS:DeleteTopic",
      "SNS:AddPermission",
    ]
      
    condition {
      test     = "StringEquals"
      variable = "AWS:SourceOwner"

      values = [
        var.account_id,
      ]
    }

    effect = "Allow"

    principals {
      type        = "AWS"
      identifiers = ["*"]
    }

    resources = [
      aws_sns_topic.my_first_sns_topic.arn,
    ]

    sid = "__default_statement_ID"
  }
}

Next, create a file named “terraform.tfvars” to store your AWS IAM User access and secret key:

Check the GitHub link: GitHub Link.

File: terraform.tfvars
access_key = ""
secret_key = ""

You’ll also need a “variables.tf” file for variable definitions used in “main.tf“. Ensure it’s in the same directory as the other files and update variables like ‘account_id’ and ‘sns_name’ to customize the SNS topic.

Check this file on GitHub: GitHub Link.

File: variables.tf
variable "access_key" {
    description = "Access key of AWS IAM user"
}

variable "secret_key" {
    description = "Secret key of AWS IAM user"
}

variable "sns_name" {
    description = "Name of the SNS Topic to be created"
    default     = "my_first_sns"
}

variable "account_id" {
    description = "My Account Number"
    default     = ""
}

Creating an SNS Topic with Terraform

Once you have all the necessary files, proceed to create an SNS Topic with Terraform:

Initialize the working directory containing your Terraform configuration files with:

terraform init

terraform init

Create an execution plan to understand the changes Terraform will apply:

terraform plan

Apply the configuration to create the SNS topic in your AWS account:

terraform apply

Verify the SNS topic creation via the AWS SNS Console.

Deleting the SNS Topic with Terraform

When no longer needed, use the following command to delete the SNS topic. Be cautious with the destroy operation, especially on production servers, as it is irreversible.

terraform destroy

terraform destroy

Conclusion

This article guided you through creating and managing an SNS topic with an access policy in “region = eu-west-3” using Terraform, showcasing Terraform’s efficiency in deployment and resource management.

FAQ

1. Can I use a different AWS region for my SNS topic?

Yes, you can change the region by modifying the region parameter in the provider block in your main.tf file.

2. Can I control which SNS actions are allowed via the access policy?

Certainly! You can adjust the actions in the aws_iam_policy_document to specify exactly which SNS actions are permitted.

3. How can I apply changes to an already created SNS topic?

Modify your Terraform configuration files and re-run terraform plan followed by terraform apply to implement the updates.

4. What if I want to retain certain resources while running terraform destroy?

Use the -target option with terraform apply to specify which resources to destroy selectively.

5. Is it safe to store AWS credentials in terraform.tfvars?

While convenient, it’s recommended to use environment variables or AWS config files for storing credentials to enhance security.