Как добавить правила жизненного цикла в корзину S3 с помощью terraform? - PullRequest
0 голосов
/ 27 марта 2019

Я использую Terraform для создания корзины в S3 и хочу добавить в нее «папки» и правила жизненного цикла.

Я могу создать корзину (используя ресурс «aws_s3_bucket»).

Я могу создать корзину и определить правила своего жизненного цикла в одном и том же ресурсе "aws_s3_bucket", т.е.во время создания.

Я могу добавить «папки» в корзину (я знаю, что они на самом деле не являются папками, но они представлены клиентским системам, как если бы они были ... :-)), используяресурс "aws_s3_bucket_object", т.е.после создания корзины.

Все хорошо ...

Но я хочу иметь возможность добавлять правила жизненного цикла ПОСЛЕ того, как я создал корзину, но я получаю ошибку, сообщающую, что корзина уже существует,(На самом деле я хочу иметь возможность впоследствии добавлять папки и соответствующие правила жизненного цикла по мере необходимости.)

Теперь я могу добавлять правила жизненного цикла в существующую корзину в графическом интерфейсе AWS, поэтому я знаю, что это разумночто нужно сделать.

Но есть ли способ сделать это с помощью 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.

Ответы [ 3 ]

0 голосов
/ 28 марта 2019

Давайте сначала разберемся, что происходит и как мы можем решить эту проблему. Каждый раз, когда вы определяете 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 для правил жизненного цикла, но это не так.

0 голосов
/ 01 апреля 2019

Спасибо за информацию (мне нравится идея списка, чтобы отделить правила от ресурса).

Проблема заключалась в том, что я не ценил то, что вы можете определять правила жизненного цикла в ресурсе И изменять их впоследствии, поэтому я пытался выяснить, как определять их отдельно ...

Все, что требуется, это указать их в ресурсе и применить terraform, затем вы можете отредактировать его, добавить / изменить / удалить элементы lifecycle_rules и просто снова применить terraform, чтобы применить изменения.

0 голосов
/ 28 марта 2019

Насколько мне известно, вы не можете создавать политику жизненного цикла отдельно.

Кто-то поднял 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 без политики жизненного цикла. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...