我正在使用 terraform 创建 SNS 队列。我也在创建自己的 SNS 策略文件
Terraform 代码:-
变量.tf
variable "awsAccId" {
default = "111222433"
}
variable "region" {
default = "ca-central-1"
}
locals.tf
sns_topic_name = "fail-notification"
fail_noti_topic_arn = "arn:aws:sns:${var.region}:${var.awsAccId}:${local.sns_topic_name }"
resource "aws_sns_topic" "fail-noti-topic" {
name = "${local.sns_topic_name }"
}
resource "aws_sns_topic_policy" "fail-noti-topic-policy" {
arn = aws_sns_topic.fail-noti-topic.arn
policy = file("policy/sns-policy.json")
}
resource "aws_sns_topic_subscription" "fail-noti-topic" {
...
...
}
内部策略(文件夹)-> sns-policy.json(文件)
{
"Version": "2012-10-17",
"Id": "${local.sns_topic_name }_policy_ID",
"Statement": [
{
"Sid": "${local.sns_topic_name}_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "${local.fail_noti_topic_arn}",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "{var.awsAccId}"
}
}
}
]
}
我期望 json 中的变量能够解析,并且我会得到
locals.tf
和 variables.tf
文件中描述的确切值。
相反,访问策略如 AWS 控制台所示是
我尝试使用
policy = jsonencode(file("policy/sns-policy.json"))
,但我收到另一个错误,而terraform apply
(类似这样)
policyerror Attribute is not valid
.
这个错误在规划阶段是不存在的。
我也尝试过类似的事情
resource "aws_sns_topic_policy" "fail-noti-topic-policy" {
arn = aws_sns_topic.fail-noti-topic.arn
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "${local.sns_topic_name }_policy_ID",
"Statement": [
{
"Sid": "${local.sns_topic_name}_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
......
POLICY
但是,这也不能解析变量及其相应的值。
我应该怎么做,解析策略 JSON 文件中的变量,以便获得它们的实际值,而不是变量本身?
我通常做的是使用可用于创建策略的数据源,因为最容易获得正确的插值。在这种情况下,它看起来像下面这样:
data "aws_iam_policy_document" "sns_topic_policy" {
statement {
sid = "${local.sns_topic_name }_policy_ID"
effect = "Allow"
actions = [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:AddPermission",
"SNS:Subscribe"
]
condition {
test = "StringEquals"
variable = "aws:SourceOwner"
values = [
var.awsAccId
]
}
resources = [
local.fail_noti_topic_arn
]
principals {
type = "AWS"
identifiers = [
"*"
]
}
}
}
templatefile
函数(而不是 file
)来提供输入值。在这种情况下,您可以执行以下操作:
resource "aws_sns_topic_policy" "fail-noti-topic-policy" {
arn = aws_sns_topic.fail-noti-topic.arn
policy = templatefile("${path.root}/policy/sns-policy.json", {
id = "${local.sns_topic_name }_policy_ID"
sid = "${local.sns_topic_name}_statement_ID"
resource = local.fail_noti_topic_arn
account_id = var.awsAccId
})
}
为此,您还必须在模板化 JSON 文件中进行更改:
{
"Version": "2012-10-17",
"Id": "${id}",
"Statement": [
{
"Sid": "${sid}",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "${resource}",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "${account_id}"
}
}
}
]
}