我正在使用Terraform在S3中创建存储桶,我想向其中添加“文件夹”和生命周期规则。
我可以创建存储区(使用“ aws_s3_bucket”资源)。
我可以创建存储桶并在相同的“ aws_s3_bucket”资源中定义生命周期规则。在创建时。
我可以使用“ aws_s3_bucket_object”资源将“文件夹”添加到存储桶中(我知道它们并不是真正的文件夹,但是它们像呈现在客户端系统中一样呈现给客户端系统): 。创建存储区之后。
一切都很好...
但是我希望能够在创建存储桶之后添加生命周期规则,但是却收到一条错误消息,告诉我存储桶已经存在。 (实际上,我希望以后能够根据需要添加文件夹和相应的生命周期规则。)
现在,我可以将生命周期规则添加到AWS GUI中的现有存储桶中,因此我知道这是一件合理的事情。
但是可以用Terraform做到吗?
我想念什么吗?
resource "aws_s3_bucket" "bucket" {
bucket = "${replace(var.tags["Name"],"/_/","-")}"
region = "${var.aws_region}"
#tags = "${merge(var.tags, map("Name", "${var.tags["Name"]}"))}"
tags = "${merge(var.tags, map("Name", "${replace(var.tags["Name"],"/_/","-")}"))}"
}
resource "aws_s3_bucket" "bucket_quarterly" {
bucket = "${aws_s3_bucket.bucket.id}"
#region = "${var.aws_region}"
lifecycle_rule {
id = "quarterly_retention"
prefix = "quarterly/"
enabled = true
expiration {
days = 92
}
}
}
resource "aws_s3_bucket" "bucket_permanent" {
bucket = "${aws_s3_bucket.bucket.id}"
#region = "${var.aws_region}"
lifecycle_rule {
id = "permanent_retention"
enabled = true
prefix = "permanent/"
transition {
days = 1
storage_class = "GLACIER"
}
}
}
resource "aws_s3_bucket_object" "quarterly" {
bucket = "${aws_s3_bucket.bucket.id}"
#bucket = "${var.bucket_id}"
acl = "private"
key = "quarterly"
source = "/dev/null"
}
resource "aws_s3_bucket_object" "permanent" {
bucket = "${aws_s3_bucket.bucket.id}"
#bucket = "${var.bucket_id}"
acl = "private"
key = "permanent"
source = "/dev/null"
}
我希望有一个具有2个生命周期规则的存储桶,但出现以下错误:
错误:应用计划时出错:
2 error(s) occurred:
* module.s3.aws_s3_bucket.bucket_quarterly: 1 error(s) occurred:
* aws_s3_bucket.bucket_quarterly: Error creating S3 bucket: BucketAlreadyOwnedByYou: Your previous request to create the named bucket succeeded and you already own it.
status code: 409, request id: EFE9C62B25341478, host id: hcsCNracNrpTJZ4QdU0AV2wNm/FqhYSEY4KieQ+zSHNsj6AUR69XvPF+0BiW4ZOpfgIoqwFoXkI=
* module.s3.aws_s3_bucket.bucket_permanent: 1 error(s) occurred:
* aws_s3_bucket.bucket_permanent: Error creating S3 bucket: BucketAlreadyOwnedByYou: Your previous request to create the named bucket succeeded and you already own it.
status code: 409, request id: 7DE1B1A36138A614, host id: 8jB6l7d6Hc6CZFgQSLQRMJg4wtvnrSL6Yp5R4RScq+GtuMW+6rkN39bcTUwQhzxeI7jRStgLXSc=
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
答案 0 :(得分:0)
据我所知,您不能单独制定生命周期策略。
有人提出了要创建的资源的PR,以允许您这样做,但看起来它仍处于打开状态:https://github.com/terraform-providers/terraform-provider-aws/issues/6188
对于您的错误,我相信您收到此错误的原因是:
resource "aws_s3_bucket" "bucket"
创建具有特定名称的存储桶。
resource "aws_s3_bucket" "bucket_quarterly"
引用bucket = "${aws_s3_bucket.bucket.id}"
,因此尝试创建与先前资源同名的存储桶(由于名称是唯一的,因此无法完成操作)。
resource "aws_s3_bucket" "bucket_permanent"
类似地,此资源引用bucket = "${aws_s3_bucket.bucket.id}"
,因此尝试创建与第一个资源同名的存储桶(由于名称是唯一的,因此无法完成操作)。
您提到了I expect to have a bucket with 2 lifecycle rules
,但是在上面的代码中,您正在创建3个单独的s3存储桶(一个不带生命周期,两个带生命周期)和两个对象(文件夹)被放置在不带s3桶的情况下生命周期政策。
答案 1 :(得分:0)
首先让我们分解发生的事情以及我们如何克服这个问题。每次您定义resource "aws_s3_bucket"
时,terraform都会尝试使用指定的参数创建存储区。如果您要将生命周期策略附加到存储桶,请在定义存储桶的位置执行此操作,例如:
resource "aws_s3_bucket_object" "quarterly" {
bucket = "quarterly_bucket_name"
#bucket = "${var.bucket_id}"
acl = "private"
key = "quarterly"
source = "/dev/null"
lifecycle_rule {
id = "quarterly_retention"
prefix = "folder/"
enabled = true
expiration {
days = 92
}
}
}
resource "aws_s3_bucket_object" "permanent" {
bucket = "perm_bucket_name"
acl = "private"
key = "permanent"
source = "/dev/null"
lifecycle_rule {
id = "permanent_retention"
enabled = true
prefix = "permanent/"
transition {
days = 1
storage_class = "GLACIER"
}
}
}
存储桶上可以有多个lifecycle_rule
块。
如果要将生命周期规则定义为外部块,则可以通过以下方式实现:
// example of what the variable would look like:
variable "lifecycle_rules" {
type = "list"
default = []
}
// example of what the assignment would look like:
lifecycle_rules = [{
id = "cleanup"
prefix = ""
enabled = true
expiration = [{
days = 1
}]
}, {...}, {...} etc...]
// example what the usage would look like
resource "aws_s3_bucket_object" "quarterly" {
bucket = "quarterly_bucket_name"
#bucket = "${var.bucket_id}"
acl = "private"
key = "quarterly"
source = "/dev/null"
lifecycle_rule = [ "${var.lifecycle_rules}" ]
}
注意:以上具有外部生命周期策略的实现实际上并不是最好的方法,而是唯一的方法。您几乎可以欺骗地形来接受地图列表,该列表恰好与lifecycle_rule类型相同,因此可以正常工作。理想情况下,Terraform应该为生命周期规则拥有自己的resource
块,但没有。
答案 2 :(得分:0)
感谢信息(我喜欢列表的概念,用于将规则与资源分开)。
问题是,我不欣赏您可以在资源中定义生命周期规则并随后进行更改,因此,我试图弄清楚如何分别定义它们...
所需要做的就是在资源中指定它们并进行terraform的应用,然后您可以对其进行编辑并添加/修改/删除lifecycle_rules项,然后再次进行terraform的应用以应用更改。