『実践Terraform』でバケット定義の書き方が非推奨と警告されてしまう

Terraform初学者です。

『[実践Terraform](https://www.amazon.co.jp/dp/4844378139)』という書籍で勉強しています。

書籍のコードをそのまま記述すると、VSCodeの拡張機能で非推奨と警告されてしまう箇所があったため、備忘録としてまとめます。

この記事におけるバージョンは次のとおりです。

- Terraform: v1.9.5
- HashiCorp Terraform(拡張機能): v2.32.2

## 問題

`第6章 ストレージ`のサンプルコードが対象です。

この章では以下の3つを定義することになっています。

- プライベートバケット
- パブリックバケット
- ログバケット

この3つそれぞれのコードを書籍どおりに書くと非推奨の警告が出てしまいます。

### プライベートバケット

#### 書籍のコード

```terraform:s3.tf
resource "aws_s3_bucket" "private" {
  bucket = "private-pragmatic-terraform"

  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}
```

#### 非推奨の警告

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/af2708fb-1331-b8bc-ee4c-61a4f6aac737.png)

#### 具体的な警告メッセージ

- `"versioning" is deprecated: Reason: ""`
-  `"server_side_encryption_configuration" is deprecated: Reason: ""`

### パブリックバケット

#### 書籍のコード

```terraform:s3.tf
resource "aws_s3_bucket" "public" {
  bucket = "public-pragmatic-terraform"
  acl    = "public-read"

  cors_rule {
    allowed_origins = ["https://example.com"]
    allowed_methods = ["GET"]
    allowed_headers = [""]
    max_age_seconds = 3000
  }
}
```

#### 非推奨の警告

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/7ae2d2ee-15ec-f53f-f2ce-bd38d4916d84.png)

#### 具体的な警告メッセージ

- `"acl" is deprecated: Reason: ""`
- `"cors_rule" is deprecated: Reason: ""`

### ログバケット

#### 書籍のコード

```terraform:s3.tf
resource "aws_s3_bucket" "alb_log" {
  bucket = "alb-log-pragmatic-terraform"

  lifecycle_rule {
    enabled = true

    expiration {
      days = "180"
    }
  }
}
```

#### 非推奨の警告

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/f4d21448-7f44-8118-9dfb-8dbc78596421.png)

#### 具体的な警告メッセージ

- `"lifecycle_rule" is deprecated: Reason: ""`

## 原因

`terraform-provider-aws`のバージョン4.0.0から仕様変更されたようです。

[CHANGELOG](https://github.com/hashicorp/terraform-provider-aws/blob/release/4.x/CHANGELOG.md#400-february-10-2022)を確認したところ、以下の5つが独立したリソースとして新たに追加されていました。

- `aws_s3_bucket_versioning`
- `aws_s3_bucket_server_side_encryption_configuration`
- `aws_s3_bucket_acl`
- `aws_s3_bucket_cors_configuration`
- `aws_s3_bucket_lifecycle_configuration`

それに伴い『[実践Terraform](https://www.amazon.co.jp/dp/4844378139)』で掲載されている記述方法は非推奨となっています。

S3バケットの設定をより柔軟に行えるよう、独立したリソースとして追加された模様です。

それぞれ次のように書くことで警告が外れました。

### プライベートバケット

```terraform:s3.tf
resource "aws_s3_bucket" "private" {
  bucket = "private-pragmatic-terraform"
}

resource "aws_s3_bucket_versioning" "private" {
  bucket = aws_s3_bucket.private.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "private" {
  bucket = aws_s3_bucket.private.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}
```

### パブリックバケット

```terraform:s3.tf
resource "aws_s3_bucket" "public" {
  bucket = "public-pragmatic-terraform"
}

resource "aws_s3_bucket_acl" "public" {
  bucket = aws_s3_bucket.public.id
  acl    = "public-read"
}

resource "aws_s3_bucket_cors_configuration" "public" {
  bucket = aws_s3_bucket.public.id

  cors_rule {
    allowed_origins = ["https://example.com"]
    allowed_methods = ["GET"]
    allowed_headers = ["*"]
    max_age_seconds = 3000
  }
}
```

### ログバケット

```terraform:s3.tf
resource "aws_s3_bucket" "alb_log" {
  bucket = "alb-log-pragmatic-terraform"
}

resource "aws_s3_bucket_lifecycle_configuration" "alb_log" {
  bucket = aws_s3_bucket.alb_log.id

  rule {
    id     = "log_expiration"
    status = "Enabled"

    expiration {
      days = 180
    }
  }
}
```

## おわりに

『[実践Terraform](https://www.amazon.co.jp/dp/4844378139)』はとてもわかりやすいため、初学者にもおすすめです。

ただし出版が2019年なので現在とは異なる点もあります。

今後もそういった箇所が見つかったら、適宜調べてさらにTerraformの理解を深めていきたいと思います。

また、この記事に誤りがありましたらコメントにて教えていただけますと幸いです。

## 参考資料

https://github.com/hashicorp/terraform-provider-aws/blob/release/4.x/CHANGELOG.md#400-february-10-2022

https://github.com/hashicorp/terraform-provider-aws/issues/4418

https://github.com/hashicorp/terraform-provider-aws/issues/20433