You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform创建SQS及访问策略时出现循环错误的解决方法

修复Terraform中SQS队列与IAM策略文档的循环依赖问题

问题背景

尝试创建SQS队列并通过data "aws_iam_policy_document"生成访问策略附加到队列,但触发循环依赖错误。

报错信息

╷
│ Error: Cycle: data.aws_iam_policy_document.sqs_vote_policy, aws_sqs_queue.sqs_vote
│

原Terraform代码

resource "aws_sqs_queue" "sqs_vote" {
  name                      = "sqs-erjan"
  delay_seconds             = 0
  message_retention_seconds = 86400
  receive_wait_time_seconds = 0
  policy                    = data.aws_iam_policy_document.sqs_vote_policy.json
}

data "aws_iam_policy_document" "sqs_vote_policy" {
  policy_id = "__default_policy_ID"

  statement {
    sid       = "__console_sub_0"
    actions   = ["SQS:SendMessage"]
    resources = [aws_sqs_queue.sqs_vote.arn]
    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
    effect = "Allow"

    condition {
      test     = "ArnLike"
      variable = "AWS:SourceArn"

      values = [
        aws_sns_topic.vote_sns.arn
      ]
    }

  }

  statement {
    sid       = "__owner_statement"
    actions   = ["SQS:*"]
    resources = [aws_sqs_queue.sqs_vote.arn]
    principals {
      type        = "arn:aws:iam::025416187662:root"
      identifiers = ["*"]
    }
    effect = "Allow"

  }

  # 添加了depends_on但仍出现循环错误
  depends_on = [
    aws_sqs_queue.sqs_vote,aws_sns_topic.vote_sns
  ]
}

问题原因

循环依赖的核心是双向引用:

  • SQS队列资源需要策略文档生成的JSON内容才能创建
  • 策略文档又依赖SQS队列的ARN来生成内容
  • 额外添加的depends_on = [aws_sqs_queue.sqs_vote]进一步强化了这种双向依赖,导致Terraform无法确定执行顺序。

修复方案

方案一:内联生成策略文档

直接在SQS队列资源中用jsonencode内联编写策略,通过self.arn引用当前队列的ARN,避免外部依赖。

resource "aws_sqs_queue" "sqs_vote" {
  name                      = "sqs-erjan"
  delay_seconds             = 0
  message_retention_seconds = 86400
  receive_wait_time_seconds = 0

  policy = jsonencode({
    "Version" : "2012-10-17",
    "Id" : "__default_policy_ID",
    "Statement" : [
      {
        "Sid" : "__console_sub_0",
        "Effect" : "Allow",
        "Principal" : {
          "AWS" : "*"
        },
        "Action" : "SQS:SendMessage",
        "Resource" : self.arn,
        "Condition" : {
          "ArnLike" : {
            "AWS:SourceArn" : aws_sns_topic.vote_sns.arn
          }
        }
      },
      {
        "Sid" : "__owner_statement",
        "Effect" : "Allow",
        "Principal" : {
          "AWS" : "arn:aws:iam::025416187662:root"
        },
        "Action" : "SQS:*",
        "Resource" : self.arn
      }
    ]
  })
}

方案二:使用单独的aws_sqs_queue_policy资源

拆分资源创建顺序:先创建SQS队列,再生成策略文档,最后通过单独的队列策略资源将策略附加到队列。

# 先创建SQS队列,不指定policy参数
resource "aws_sqs_queue" "sqs_vote" {
  name                      = "sqs-erjan"
  delay_seconds             = 0
  message_retention_seconds = 86400
  receive_wait_time_seconds = 0
}

# 生成IAM策略文档,仅依赖SNS主题
data "aws_iam_policy_document" "sqs_vote_policy" {
  policy_id = "__default_policy_ID"

  statement {
    sid       = "__console_sub_0"
    actions   = ["SQS:SendMessage"]
    resources = [aws_sqs_queue.sqs_vote.arn]
    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
    effect = "Allow"

    condition {
      test     = "ArnLike"
      variable = "AWS:SourceArn"
      values = [aws_sns_topic.vote_sns.arn]
    }
  }

  statement {
    sid       = "__owner_statement"
    actions   = ["SQS:*"]
    resources = [aws_sqs_queue.sqs_vote.arn]
    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::025416187662:root"]
    }
    effect = "Allow"
  }

  depends_on = [aws_sns_topic.vote_sns]
}

# 单独创建队列策略,附加到已创建的SQS队列
resource "aws_sqs_queue_policy" "sqs_vote_policy" {
  queue_url = aws_sqs_queue.sqs_vote.id
  policy    = data.aws_iam_policy_document.sqs_vote_policy.json
}

方案对比

  • 方案一:代码更简洁,适合策略逻辑简单的场景,无需额外资源。
  • 方案二:逻辑更清晰,策略文档可复用,适合复杂策略或需要单独管理策略的场景。

内容的提问来源于stack exchange,提问作者ERJAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:45:48