如何从Terraform 0.12中的模板创建S3存储桶策略?

时间:2019-11-28 00:24:21

标签: amazon-s3 terraform terraform-provider-aws

我正在尝试通过Terraform 0.12创建一个S3存储桶策略,该策略将根据环境(dev / prod)而变化。这是政策的一部分:

{
            "Sid": "AllowAdminAccessToBuckets",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetBucket*"
            ],
            "Resource": [
                "arn:aws:s3:::${var.env-bucket}",
                "arn:aws:s3:::${var.env-bucket}/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "${var.env-vpce}"
                }
            }
        }

如果我使用JSON格式的文档(而不是模板)来进行此操作,则可以进行以下操作:

resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"
  policy = "${file("templates/policy.json")}"
}

如何在策略中指定变量?

2 个答案:

答案 0 :(得分:1)

您可以使用数据资源通过根据您的环境传递变量来为策略创建JSON模板,并使用template_file作为aws_s3_bucket资源中的策略。

variable "env-bucket" {
  default = "sample"
}
variable "env-vpce" {
  default = "sample-vpc"
}

data "template_file" "policy" {
  template = "${file("policy.json")}"

  vars = {
    env-bucket = "${var.env-bucket}"
    env-vpce   = "${var.env-vpce}"
   }
}

resource "aws_s3_bucket" "b" {
   bucket = "my-tf-test-bucket"
   policy = "${data.template_file.policy.rendered}"
}

答案 1 :(得分:0)

您不需要模板文件就可以传递变量,您可以使用heredoc直接内联:

variable "env-bucket" {
  default = "example"
}

variable "env-vpce" {
  default = "vpce-1234567890abcdef"
}

resource "aws_s3_bucket" "b" {
   bucket = var.env-bucket
   policy = <<POLICY
{
    "Sid": "AllowAdminAccessToBuckets",
    "Effect": "Allow",
    "Principal": "*",
    "Action": [
        "s3:GetBucket*"
    ],
    "Resource": [
        "arn:aws:s3:::${var.env-bucket}",
        "arn:aws:s3:::${var.env-bucket}/*"
    ],
    "Condition": {
        "StringEquals": {
            "aws:sourceVpce": var.env-vpce
        }
    }
}
POLICY

}

还值得注意的是,这允许所有对GetBucket* API调用的访问都可以访问流量通过该VPC终结点的任何内容,而不仅仅是管理员(基本上是该VPC中的任何内容),并且也不允许允许任何基于对象的操作,因此"arn:aws:s3:::${var.env-bucket}/*"资源是不必要的,或者您需要将GetBucket*更改为Get*才能允许来自该VPC的流量获取对象。