在SNS Terraform脚本中定义SQS端点



我有一个SQS Terraform模块,我在其中定义的队列名称如下

main_queue_name = "app-sqs-env-${var.env_name}"

通过在单独的文件中定义env_name,我可以创建一个具有所需名称的队列。

现在我想创建一个SNS主题,并希望队列订阅该主题。

当我使用sns_topic_name = "app-sns-env-${var.env_name}"创建SNS主题时,我能够按预期创建主题

如何在SNS模块中定义sqs_endpoint,我想在这个端点定义中使用${var.env_name},因为我们为不同的环境传递不同的名称。

为了能够将SQS队列订阅到SNS主题,我们必须做以下操作:

# Create some locals for SQS and SNS names
locals {
sqs-name = "app-sqs-env-${var.env-name}"
sns-name = "app-sns-env-${var.env-name}"
}
# Inject caller ID for being able to use the account ID
data "aws_caller_identity" "current" {}

# Create a topic policy. This will allow for the SQS queue to be able to subscribe to the topic
data "aws_iam_policy_document" "sns-topic-policy" {
statement {
actions = [
"SNS:Subscribe",
"SNS:Receive",
]
condition {
test     = "StringLike"
variable = "SNS:Endpoint"
# In order to avoid circular dependencies, we must create the ARN ourselves
values = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:${local.sqs-name}",
]
}
effect = "Allow"
principals {
type        = "AWS"
identifiers = ["*"]
}
resources = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:${local.sns-name}"
]
sid = "sid-101"
}
}
# Create a queue policy. This allows for the SNS topic to be able to publish messages to the SQS queue
data "aws_iam_policy_document" "sqs-queue-policy" {
policy_id = "arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:${local.sqs-name}/SQSDefaultPolicy"
statement {
sid    = "example-sns-topic"
effect = "Allow"
principals {
type        = "AWS"
identifiers = ["*"]
}
actions = [
"SQS:SendMessage",
]
resources = [
"arn:aws:sqs:${var.region}:${data.aws_caller_identity.current.account_id}:${local.sqs-name}"
]
condition {
test     = "ArnEquals"
variable = "aws:SourceArn"
values = [
"arn:aws:sns:${var.region}:${data.aws_caller_identity.current.account_id}:${local.sns-name}"
]
}
}
}
# Create the SNS topic and assign the topic policy to it
resource "aws_sns_topic" "sns-topic" {
name         = local.sns-name
display_name = local.sns-name
policy       = data.aws_iam_policy_document.sns-topic-policy.json
}
# Create the SQS queue and assign the queue policy to it
resource "aws_sqs_queue" "sqs-queue" {
name   = local.sqs-name
policy = data.aws_iam_policy_document.sqs-queue-policy.json
}
# Subscribe the SQS queue to the SNS topic
resource "aws_sns_topic_subscription" "sns-topic" {
topic_arn = aws_sns_topic.sns-topic.arn
protocol  = "sqs"
endpoint  = aws_sqs_queue.sqs-queue.arn
}
我希望上面的代码和注释是有意义的。在Terraform文档中有一个aws_sns_topic_subscription的例子,它要复杂得多,但也很有用。

为避免在创建策略时出现循环ARN问题,您可以在创建后使用aws_sqs_queue_policy附加策略,例如

resource "aws_sns_topic" "topic" {
name = "topic-name"
}
resource "aws_sqs_queue" "queue" {
name = "queue-name"
}
# Queue policy allowing send messages from the required topic
data "aws_iam_policy_document" "queue_policy_document" {
statement {
effect = "Allow"
actions = ["sqs:SendMessage"]
principals {
type        = "AWS"
identifiers = ["*"]
}
resources = [aws_sqs_queue.queue.arn]
condition {
test     = "ArnEquals"
variable = "aws:SourceArn"
values   = [aws_sns_topic.topic.arn]
}
}
}
# Attach the queue policy
resource "aws_sqs_queue_policy" "queue_policy" {
queue_url = aws_sqs_queue.queue.id
policy    = data.aws_iam_policy_document.queue_policy_document.json
}
# subscribe queue to the topic
resource "aws_sns_topic_subscription" "topic_subscription" {
topic_arn = aws_sns_topic.topic.arn
endpoint  = aws_sqs_queue.queue.arn
protocol  = "sqs"
}

最新更新