TerraformでS3バケットを登録

## はじめに

前回、前々回と、TerraformでEC2インスタンスを構築してみました。
業務でS3を構築する必要があるとのことなので、代わり映えがありませんが、今度はS3にバケットを構築してみようと思います。

## 目標

Terraformを使ってS3バケットを構築。
マネジメントコンソールは一切使用しないこと。

## 参考

[初めてのTerraform](https://qiita.com/class2glass/items/6a55f6a1627780bbbb35)
[SSMでEC2にアクセス](https://qiita.com/class2glass/items/5749d47f6dca79c84c50)
[iResource: aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket)

## 手順

まずは作業フォルダでTerraformコマンドが利用できるよう初期化処理を行います。

```
# terraform init

Initializing the backend...
   ：
   ：
Terraform has been successfully initialized!
   ：
   ：
commands will detect it and remind you to do so if necessary.
```

S3を構築するためのTerraformファイルを用意します。
合わせて環境変数を定義しているファイルたちも用意します。


```
# terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  + create
   ：
   ：

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.
```

記述ミスなど無いようなので実際に構築してみます。
実は一回記述ミスをしてしまいました。
記述ミスというより、バケット名に「_」を使用してしまいました。
バケット名に「_」は使用できませんので「-」に変更しておきました。

```
aws_s3_bucket.bucket1: Creating...
╷
│ Error: Error validating S3 bucket name: only lowercase alphanumeric characters and hyphens allowed in "xxxxx_tf_bucket"
│
│   with aws_s3_bucket.bucket1,
│   on s3.tf line 1, in resource "aws_s3_bucket" "bucket1":
│    1: resource "aws_s3_bucket" "bucket1" {
```

構築ですが、今回も便宜上、「-auto-approve」オプションを使用します。

```
# terraform apply -auto-approve

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  + create

Terraform will perform the following actions:

  # aws_s3_bucket.bucket1 will be created
   ：
   ：
    }

Plan: 1 to add, 0 to change, 0 to destroy.
aws_s3_bucket.bucket1: Creating...
aws_s3_bucket.bucket1: Creation complete after 8s [id=xxxxx-tf-bucket]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

正常終了したようですが、Terraformの実行結果を確認します。

```
# terraform show
# aws_s3_bucket.bucket1:
resource "aws_s3_bucket" "bucket1" {
    acl                         = "private"
    arn                         = "arn:aws:s3:::xxxxx-tf-bucket"
    bucket                      = "xxxxx-tf-bucket"
    bucket_domain_name          = "xxxxx-tf-bucket.s3.amazonaws.com"
    bucket_regional_domain_name = "xxxxx-tf-bucket.s3.us-west-2.amazonaws.com"
    force_destroy               = false
    hosted_zone_id              = "xxxxx"
    id                          = "xxxxx-tf-bucket"
    region                      = "us-west-2"
    request_payer               = "BucketOwner"
    tags_all                    = {}

    versioning {
        enabled    = false
        mfa_delete = false
    }
}
```

実際にAWS上に構築されているのかも確認してみます。

```
# aws s3 ls | grep xxxxx
2021-10-12 06:27:11 xxxxx-tf-bucket
```

aws-cliを使用して実際にAWS上に構築されたことまで確認できました。

動作検証目的なのでこのバケットは削除しておきます。
削除はもちろんdestroyです。
ここでも-auto-approveオプションを使用します。

```
# terraform destroy -auto-approve
aws_s3_bucket.bucket1: Refreshing state... [id=c069544-tf-bucket]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # aws_s3_bucket.bucket1 has been changed
  ~ resource "aws_s3_bucket" "bucket1" {
  ：
  ：
    }

Plan: 0 to add, 0 to change, 1 to destroy.
aws_s3_bucket.bucket1: Destroying... [id=xxxxx-tf-bucket]
aws_s3_bucket.bucket1: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.
```

最後の最後に、ちゃんと削除されたかを確認しておきます。

```
# terraform show
#
# aws s3 ls | grep xxxxx
#
```

無事に後始末まで終えることができました。

## おわりに

最初から最後までGUI、マネジメントコンソールは使用しませんでした。
もうGUIはいらないのでは？と思いがちですが、決してそんな事はありません。
TF内に指定するパラメータはどんな意味があるのかを理解するには、やはりマネジメントコンソール上で確認したほうが視覚情報が加味され理解が深まります。
やり方は人それぞれですが、私は、AWSはまずGUIで構築してみて、同じものをTerraformで作ってみる、そういう作り方のほうが理解しつつ構築できるのではと考えています。

## ところで．．．

これまで何度かTerraformを試してきました。
EC2、SSM EC2、そしてS3。
実は試すたびにフォルダを分けて検証してきました。

```
   └terraform
     ├ec2
     │  ├terraform.tfvars
     │  ├variables.tf
     │  └ec2.tf
     ├ec2ssm
     │  ├terraform.tfvars
     │  ├variables.tf
     │  ├ec2.tf
     │  └role.tf
     └s3
        ├terraform.tfvars
        ├variables.tf
        └s3.tf
```

それぞれのフォルダでinitやってplanやってapplyやって．．．
ちょっと不便というか面倒です。

フォルダ構成を変更し、特定のtfのみを実行することができれば、もっと気軽に検証できる気がしてきました。
次はこのあたりの構成の見直しを進めてみようと思います。