英文:
Update bucket created in Terraform file results in BucketAlreadyOwnedByYou error
问题
需要将策略添加到我之前在我的Terraform文件中创建的存储桶。
但是,出现了以下错误:
创建S3存储桶时出错:BucketAlreadyOwnedByYou:您之前的
创建具有该名称的存储桶的请求成功,您已拥有它。
我如何修改我的.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}"
}
英文:
I need to add a policy to a bucket I create earlier on in my Terraform file.
However, this errors with
> Error creating S3 bucket: BucketAlreadyOwnedByYou: Your previous
> request to create the named bucket succeeded and you already own it.
How can I amend my .tf file to create the bucket, then update it?
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}"
}
答案1
得分: 4
当首次配置 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 控制台 手动创建 S3 存储桶后,运行以下命令来更新 Terraform 状态,以通知它 S3 存储桶已经存在:
terraform import aws_s3_bucket.<bucket_label> <bucket_name>
S3 存储桶现在将包含在您的 Terraform 状态中,并将由 Terraform 管理。
英文:
When setting up terraform to use s3 as a backend for the first time with a config similar to below:
# 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
}
}
After creating the s3 bucket manually in the AWS console, run the following command to update the terraform state to inform it that the s3 bucket already exists:
terraform import aws_s3_bucket.<bucket_label> <bucket_name>
The s3 bucket will now be in your Terraform state and will henceforth be managed by Terraform.
答案2
得分: 3
你应该使用aws_s3_bucket_policy
资源来向现有的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目录列表一样,这不是大多数人想要的。
英文:
You should use the aws_s3_bucket_policy
resource to add a bucket policy to an existing S3 bucket:
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
}
But if you are doing this at the same time then it's probably worth just inlining this into the original aws_s3_bucket
resource like this:
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 = ["*"]
}
}
}
This builds the S3 ARN in the bucket policy by hand to avoid a potential cycle error from trying to reference the output arn
from the aws_s3_bucket
resource.
If you had created the bucket without the policy (by applying the Terraform without the policy resource) then adding the policy
argument to the aws_s3_bucket
resource will then cause Terraform to detect the drift and the plan will show an update to the bucket, adding the policy.
It's probably worth noting that your canned ACL used in the acl
of the aws_s3_bucket
resource is overlapping with your policy and is unnecessary. You could use either the policy or the canned ACL to allow your S3 bucket to be read by all but the public-read
ACL also allows your bucket contents to be anonymously listed like old school Apache directory listings which isn't what most people want.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论