繁体   English   中英

如何使用 terraform 将生命周期规则添加到 S3 存储桶?

[英]How to add lifecycle rules to an S3 bucket using terraform?

我正在使用 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.

让我们首先分解正在发生的事情以及我们如何克服这个问题。 每次定义resource "aws_s3_bucket" ,terraform 都会尝试使用指定的参数创建存储桶。 如果要将生命周期策略附加到存储桶,请在定义存储桶的位置执行此操作,例如:

resource "aws_s3_bucket" "quarterly" {
    bucket  = "quarterly_bucket_name"
    #bucket  = "${var.bucket_id}"
    acl     = "private"
    lifecycle_rule {
        id      = "quarterly_retention"
        prefix  = "folder/"
        enabled = true

        expiration {
            days = 92
        }
    }
}

resource "aws_s3_bucket" "permanent" {
    bucket  = "perm_bucket_name"
    acl     = "private"
    lifecycle_rule {
        id      = "permanent_retention"
        enabled = true
        prefix  = "permanent/"

        transition {
            days            = 1
            storage_class   = "GLACIER"
        }
    }
}

一个bucket上可以有多个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" "quarterly" {
    bucket  = "quarterly_bucket_name"
    #bucket  = "${var.bucket_id}"
    acl     = "private"
    source  = "/dev/null"
    lifecycle_rule = [ "${var.lifecycle_rules}" ]
}

注意:上面的外部生命周期策略的实现并不是最好的方法,而是唯一的方法。 您几乎可以欺骗 terraform 接受地图列表,该列表恰好与 Lifecycle_rule 类型相同,因此它可以工作。 理想情况下,Terraform 应该有自己的生命周期规则resource块,但它没有。

编辑:当我们现在有动态块时,为什么还要有单独的资源块! 呜呼

据我所知,您不能单独制定生命周期策略。

有人为要创建的资源提出了 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 存储桶(一个没有生命周期,2 个有生命周期)和两个被放入 s3 存储桶的对象(文件夹)没有生命周期策略。

感谢您提供信息(我喜欢将规则与资源分开的列表的想法)。

问题是我不明白您可以在资源中定义生命周期规则并随后更改它们,所以我试图弄清楚如何分别定义它们......

所需要做的就是在资源中指定它们并执行 terraform apply,然后您可以编辑它并添加/修改/删除生命周期规则项,然后再次执行 terraform apply 以应用更改。

    source "aws_s3_bucket" "my_s3_bucket" {
       bucket = local.s3_bucket_name
    
    }



    
    resource "aws_s3_bucket_acl" "my_s3_bucket_acl" {
      bucket = aws_s3_bucket.my_s3_bucket.arn
    
      lifecycle {
        prevent_destroy = true
      }
    }


    
    resource "aws_s3_bucket_versioning" "my_s3_bucket_versioning" {
      bucket = aws_s3_bucket.my_s3_bucket.arn
      versioning_configuration {
        status = true
      }
    }
    



    resource "aws_s3_bucket_server_side_encryption_configuration" "my_s3-bucket_encryption" {
      bucket = aws_s3_bucket.my_s3_bucket.arn
      rule {
        apply_server_side_encryption_by_default {
          sse_algorithm = "AES256"
        }
      }

}

resource "aws_s3_bucket_lifecycle_configuration" "my_s3_bucket_lifecycle_config" {
  bucket = aws_s3_bucket.my_s3_bucket.arn
  rule {
    id     = "dev_lifecycle_7_days"
    status = true

    abort_incomplete_multipart_upload {
      days_after_initiation = 30
    }
    noncurrent_version_expiration {
      noncurrent_days = 1
    }
    transition {
      storage_class = "STANDARD_IA"
      days = 30
    }
    expiration {
      days = 30
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM