web-dev-qa-db-ja.com

Terraformを使用して既存のAWS S3バケットにライフサイクルルールを追加する方法

既存のS3バケットがあり、それに「フォルダー」とlifecycle_rulesを追加したいと思います。

(ストレージゲートウェイを介してアクセスされるため、クライアントエンドでそれらが表される方法であるため、「フォルダー」と言います。)

たとえば、四半期ごとのバックアップを保持するためのフォルダーを作成できます。

resource "aws_s3_bucket_object" "quarterly" {
    bucket  = "${var.bucket_id}"
    acl     = "private"
    key     = "quarterly"
    source  = "/dev/null"
}

しかし、次のようにしてライフサイクルルールを追加しようとすると、

resource "aws_s3_bucket" "quarterly" {
    bucket  = "${var.bucket_id}"
    acl     = "private"

    lifecycle_rule {
        id      = "quarterly_retention"
        prefix  = "quarterly/"
        enabled = true
        tags {
            "rule"  = "quarterly"
        }

        expiration {
            days = 92
        }
    }
}

テラフォームを適用するとエラーが発生します。

* aws_s3_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: 702396A7D2FA28BA, Host id: IJDA+vszRBYl4zmvW56dSnC2va2qpQXlfgeEL7X1QQHHv8eEaYKvSUCL0ZIj/VsdvQ2hkBLGjAY=

作成時にライフサイクルルールを埋め込むのではなく、最初にバケットを作成してから、後でフォルダーとライフサイクルルールを追加したいと考えています。

私は何かを逃していますか、それは間違っていますか?

ご協力いただきありがとうございます!

3
prowla

最初にバケットを作成し、構成を段階的に更新することで問題なく機能するはずです。最終的には、他の方法でバケットを削除すると、Terraformはすべてのルールを適用してバケットを再作成します。

terraform.tfstateファイルを紛失したため、Terraformはすでにバケットを作成したことを認識していないか、そもそもTerraform外でバケットを作成したため、作成しようとして失敗しました。 Terraformは、その構成、つまりライフサイクルルールを更新できるようにバケットを「所有」する必要があります。

次のような方法で既存のバケットを状態ファイルにインポートできるはずです

terraform import aws_s3_bucket.quarterly <your bucket ID>

https://www.terraform.io/docs/providers/aws/r/s3_bucket.html の下部を参照してください

Terraformを実行すると、ライフサイクルルールを更新するだけで表示されます。

1
bodgit

@bodgitによると、メソッドは「aws_s3_bucket」リソース内にライフサイクルルールを埋め込み、「terraform apply」を再実行することです。

lifecycle_rule句はリソースに追加(またはリソースから削除)でき、バケットに適用されます。

ルールをバケットの作成から分離して、それらを明確に処理できるようにしようとしていましたが、これで十分です。

だから、私はバケットを次のように定義します:

resource "aws_s3_bucket" "bucket" {
    bucket      = "${replace(var.tags["Name"],"/_/","-")}"
    region      = "${var.aws_region}"

    tags        = "${merge(var.tags, map("Name", "${replace(var.tags["Name"],"/_/","-")}"))}"

    lifecycle_rule {
        id      = "quarterly_retention"
        prefix  = "quarterly/"
        enabled = true

        expiration {
            days = 92
        }
    }

}

「terraform apply」を実行すると、バケットが1つのルールで作成されます。

次に、.tfファイルを編集して、2番目のlifecycle_ruleを追加します。

resource "aws_s3_bucket" "bucket" {
    bucket      = "${replace(var.tags["Name"],"/_/","-")}"
    region      = "${var.aws_region}"

    tags        = "${merge(var.tags, map("Name", "${replace(var.tags["Name"],"/_/","-")}"))}"

    lifecycle_rule {
        id      = "quarterly_retention"
        prefix  = "quarterly/"
        enabled = true

        expiration {
            days = 92
        }
    }

    lifecycle_rule {
        id      = "permanent_retention"
        enabled = true
        prefix  = "permanent/"

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

}

「terraform apply」を再度実行すると、バケットに2番目のルールが追加されます。

次に、ルールを再度編集して削除し、「適用」を再度実行すると、ルールが失われます。

次に、編集してルールを追加し、再度適用を実行すると、そのルールが存在します。

助けてくれてありがとう!

1
prowla