hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.75k stars 9.1k forks source link

[Bug]: AWS SNS topics are regional services #33254

Open valugi opened 1 year ago

valugi commented 1 year ago

Terraform Core Version

1.5.6

AWS Provider Version

4.59.0

Affected Resource(s)

aws_sns_topic is a regional service. Topics can be created in specific regions. Both AWS API, where the request is done to a region endpoint, and CLI, where the region is a parameter, are sensitive to this. https://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html https://docs.aws.amazon.com/cli/latest/reference/sns/create-topic.html

Expected Behavior

We should have the option of choosing the region for the newly created SNS topic.

Actual Behavior

The region is the default, we cannot specify one.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

NA

Steps to Reproduce

create a new SNS topic

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

xnick123 commented 6 months ago

Hi, this is not a bug.

In terraform you manage the region with the provider configuration (for the AWS provider).

Below is an example which makes use of the default provider, it will be created in euc1:

provider "aws" {
  region = "eu-central-1"
}

resource "aws_sns_topic" "user_updates_a" {
  name = "user-updates-topic"
}

If you now add to your previous file below snippet..that new resource will be created in us-east-1:

provider "aws" {
  region = "us-east-1"
  alias  = "useast1"
}

resource "aws_sns_topic" "user_updates_b" {
  name     = "user-updates-topic"
  provider = aws.useast1
}
valugi commented 6 months ago

Maybe is not a bug but definitely a feature that needs to be implemented. Defining providers was my workaround too. If AWS CLI has it as an option within the object definition, I do not see why we could not have it as an option when using terraform to create the same object.

xnick123 commented 6 months ago

Hey, thanks for getting back. In Terraform, the concept of regions is typically managed at the provider level rather than at the resource level for several reasons:

Provider Scope: Providers in Terraform abstract away the interaction with APIs of various cloud providers or services. Since regions are a characteristic of the provider's infrastructure, it makes sense for the configuration of regions to be at the provider level.

Provider Configuration: Providers usually require configuration settings like region, authentication details, etc., to establish a connection with the underlying infrastructure. Placing region configuration at the provider level ensures that it's set once and applies to all resources managed by that provider in the configuration.

Resource Agnosticism: Terraform aims to be cloud-agnostic, allowing you to manage resources across different cloud providers or services within the same configuration. Placing region configuration at the resource level would introduce complexity in handling different configurations for each resource, especially when managing resources across different regions.

Consistency and Centralization: Managing regions at the provider level promotes consistency and centralization. It allows operators to specify regions in a single location, making it easier to manage and maintain configurations, especially in large-scale deployments. Imagine a repo with 1000 terraform resources, where each of the resources would have the region added. The API needs that info for every resource. People would ask for feature to simplify and not having the region = "us-east-1" being mention 1000 times.

However, it's worth noting that some resources might have specific attributes related to regions or availability zones that can be configured individually.

https://developer.hashicorp.com/terraform/language/providers/configuration https://developer.hashicorp.com/terraform/language/resources/syntax

valugi commented 6 months ago

Theory is one thing, and then there is the matter of opinion and implementation. I come from a developer background and for me region is just another parameter. I have a module around the creation of SNS and that should allow me to pass the region as a variable. I can create 1000 SNS topics programmatically and I should not need to define a provider individually for each one of these, when maybe I define the provider at a higher level - the level where I call the SNS module.

Terraform is just an agnostic wrapper around preexisting functions - I am just asking it to implement a feature that already exists in the AWS for this object. I do not see this as unreasonable or against the agnostic philosophy. If Terraform is really cloud agnostic is something that can be discussed, we are talking here specifically about aws_sns_topic not about a generic notification feature that is cloud independent and then it will need to follow a minimal set of common shared features between clouds.

xnick123 commented 6 months ago

I see your point and certainly that is not unreasanoble. My approach in thinking here is that this is about terraform's aws provider, not AWS CDK or an AWS SDK, where you can do what you propose. The alternatives exist because, as you mentioned, other people want to handle infrastructure programatically. For good reasons! I dont have experience with Pulumi, but i think that would be possible there too.

The mentioned logic should/would apply to any resource. Why would SNS be more in need, over any other regional aws resource (SQS, Lambda, EC2, ECR, ECS, EKS, ALB...).

With provider = aws.useast1 you actually just did override the default region individually per resource, and i don't see a huge difference between this and calling it explicetely region.