更新在 Terraform 文件中创建的存储桶导致 BucketAlreadyOwnedByYou 错误
Update bucket created in Terraform file results in BucketAlreadyOwnedByYou error
我需要向我之前在 Terraform 文件中创建的存储桶添加策略。
然而,这个错误
Error creating S3 bucket: BucketAlreadyOwnedByYou: Your previous
request to create the named bucket succeeded and you already own it.
如何修改我的 .tf 文件以创建存储桶,然后更新它?
resource "aws_s3_bucket" "bucket" {
bucket = "my-new-bucket-123"
acl = "public-read"
region = "eu-west-1"
website {
index_document = "index.html"
}
}
data "aws_iam_policy_document" "s3_bucket_policy_document" {
statement {
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.bucket.arn}/*"]
principals {
type = "AWS"
identifiers = ["*"]
}
}
}
resource "aws_s3_bucket" "s3_bucket_policy" {
bucket = "${aws_s3_bucket.bucket.bucket}"
policy = "${data.aws_iam_policy_document.s3_bucket_policy_document.json}"
}
您应该使用 aws_s3_bucket_policy
resource 将存储桶策略添加到现有 S3 存储桶:
resource "aws_s3_bucket" "b" {
bucket = "my_tf_test_bucket"
}
resource "aws_s3_bucket_policy" "b" {
bucket = "${aws_s3_bucket.b.id}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "MYBUCKETPOLICY",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my_tf_test_bucket/*",
"Condition": {
"IpAddress": {"aws:SourceIp": "8.8.8.8/32"}
}
}
]
}
POLICY
}
但如果您同时执行此操作,那么将其内联到原始 aws_s3_bucket
资源中可能是值得的,如下所示:
locals {
bucket_name = "my-new-bucket-123"
}
resource "aws_s3_bucket" "bucket" {
bucket = "${local.bucket_name}"
acl = "public-read"
policy = "${data.aws_iam_policy_document.s3_bucket_policy_document.json}"
region = "eu-west-1"
website {
index_document = "index.html"
}
}
data "aws_iam_policy_document" "s3_bucket_policy_document" {
statement {
actions = ["s3:GetObject"]
resources = ["arn:aws:s3:::${local.bucket_name}/*"]
principals {
type = "AWS"
identifiers = ["*"]
}
}
}
这会在存储桶策略中手动构建 S3 ARN,以避免尝试从 aws_s3_bucket
资源引用输出 arn
时出现潜在的循环错误。
如果您创建了没有策略的存储桶(通过在没有策略资源的情况下应用 Terraform),然后将 policy
参数添加到 aws_s3_bucket
资源将导致 Terraform 检测漂移和该计划将显示对存储桶的更新,添加策略。
可能值得注意的是,您在 aws_s3_bucket
资源的 acl
中使用的固定 ACL 与您的策略重叠并且是不必要的。您可以使用策略或固定 ACL 来允许所有人读取您的 S3 存储桶,但 public-read
ACL 还允许您的存储桶内容像老式 Apache 目录列表一样匿名列出,这不是大多数人所希望的想要。
首次设置 Terraform 以使用 s3 作为后端时,配置类似于以下内容:
# backend.tf
terraform {
backend "s3" {
bucket = "<bucket_name>"
region = "eu-west-2"
key = "state"
dynamodb_endpoint = "https://dynamodb.eu-west-2.amazonaws.com"
dynamodb_table = "<table_name>"
}
}
resource "aws_s3_bucket" "<bucket_label>" {
bucket = "<bucket_name>"
lifecycle {
prevent_destroy = true
}
}
在 AWS console 中手动创建 s3 存储桶后,运行 以下命令更新 terraform 状态以通知它 s3 存储桶已经存在:
terraform import aws_s3_bucket.<bucket_label> <bucket_name>
s3 存储桶现在将处于您的 Terraform 状态,并且此后将由 Terraform 管理。
我需要向我之前在 Terraform 文件中创建的存储桶添加策略。
然而,这个错误
Error creating S3 bucket: BucketAlreadyOwnedByYou: Your previous request to create the named bucket succeeded and you already own it.
如何修改我的 .tf 文件以创建存储桶,然后更新它?
resource "aws_s3_bucket" "bucket" {
bucket = "my-new-bucket-123"
acl = "public-read"
region = "eu-west-1"
website {
index_document = "index.html"
}
}
data "aws_iam_policy_document" "s3_bucket_policy_document" {
statement {
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.bucket.arn}/*"]
principals {
type = "AWS"
identifiers = ["*"]
}
}
}
resource "aws_s3_bucket" "s3_bucket_policy" {
bucket = "${aws_s3_bucket.bucket.bucket}"
policy = "${data.aws_iam_policy_document.s3_bucket_policy_document.json}"
}
您应该使用 aws_s3_bucket_policy
resource 将存储桶策略添加到现有 S3 存储桶:
resource "aws_s3_bucket" "b" {
bucket = "my_tf_test_bucket"
}
resource "aws_s3_bucket_policy" "b" {
bucket = "${aws_s3_bucket.b.id}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "MYBUCKETPOLICY",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my_tf_test_bucket/*",
"Condition": {
"IpAddress": {"aws:SourceIp": "8.8.8.8/32"}
}
}
]
}
POLICY
}
但如果您同时执行此操作,那么将其内联到原始 aws_s3_bucket
资源中可能是值得的,如下所示:
locals {
bucket_name = "my-new-bucket-123"
}
resource "aws_s3_bucket" "bucket" {
bucket = "${local.bucket_name}"
acl = "public-read"
policy = "${data.aws_iam_policy_document.s3_bucket_policy_document.json}"
region = "eu-west-1"
website {
index_document = "index.html"
}
}
data "aws_iam_policy_document" "s3_bucket_policy_document" {
statement {
actions = ["s3:GetObject"]
resources = ["arn:aws:s3:::${local.bucket_name}/*"]
principals {
type = "AWS"
identifiers = ["*"]
}
}
}
这会在存储桶策略中手动构建 S3 ARN,以避免尝试从 aws_s3_bucket
资源引用输出 arn
时出现潜在的循环错误。
如果您创建了没有策略的存储桶(通过在没有策略资源的情况下应用 Terraform),然后将 policy
参数添加到 aws_s3_bucket
资源将导致 Terraform 检测漂移和该计划将显示对存储桶的更新,添加策略。
可能值得注意的是,您在 aws_s3_bucket
资源的 acl
中使用的固定 ACL 与您的策略重叠并且是不必要的。您可以使用策略或固定 ACL 来允许所有人读取您的 S3 存储桶,但 public-read
ACL 还允许您的存储桶内容像老式 Apache 目录列表一样匿名列出,这不是大多数人所希望的想要。
首次设置 Terraform 以使用 s3 作为后端时,配置类似于以下内容:
# backend.tf
terraform {
backend "s3" {
bucket = "<bucket_name>"
region = "eu-west-2"
key = "state"
dynamodb_endpoint = "https://dynamodb.eu-west-2.amazonaws.com"
dynamodb_table = "<table_name>"
}
}
resource "aws_s3_bucket" "<bucket_label>" {
bucket = "<bucket_name>"
lifecycle {
prevent_destroy = true
}
}
在 AWS console 中手动创建 s3 存储桶后,运行 以下命令更新 terraform 状态以通知它 s3 存储桶已经存在:
terraform import aws_s3_bucket.<bucket_label> <bucket_name>
s3 存储桶现在将处于您的 Terraform 状态,并且此后将由 Terraform 管理。