[Docker] Terraformで開発環境のMinIOにバケットを作成する方法

# 概要

`MinIO`というAWS APIと互換性を持つストレージサービスを開発環境で使用しています。
今まで`Shell`を実行してバケットを作成していましたが、この度`Terraform`を使用してバケットを作成するようにしてみました。

# 実装

Docker環境で実装します。

### Dockerfile

ベースイメージに`Debian`を指定し、`MinIO`と`Terraform`をimageにインストールします。

ちなみに`amd64`を指定していますが、M1でも動きました。Intelを考慮する必要のない場合は`linux-amd64 / inux_amd64`の部分を`arm`に変更した方がいいかもしれません。

* `Terraform`のバージョンは現時点での最新にしているので適宜修正してください。
* `Rails`を使用していたらイメージはRubyだったりするのですが、アーキテクチャの部分も適宜変更してください。

```Dockerfile:Dockerfile_minio
FROM debian:latest

RUN apt-get update && apt-get install -y wget unzip curl

# MinIOのインストール
RUN wget https://dl.min.io/server/minio/release/linux-amd64/minio \
    && chmod +x minio \
    && mv minio /usr/local/bin/minio

# Terraformのインストール
ARG TERRAFORM_VERSION="1.6.6"
RUN curl -O https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
    && unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
    && mv terraform /usr/local/bin/terraform \
    && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip

ENV APP_ROOT /minio
RUN mkdir $APP_ROOT
WORKDIR $APP_ROOT

# MinIOの起動
CMD [ "minio", "server", "/data", "--console-address", ":9001" ]
```

### docker-compose.yml

`MinIO`のデータは消えて欲しくないので名前付きボリュームで管理します。
terraform配下には`main.tf`を作成、`Terafform`を実行すると色々ファイルが生成されるので、コンテナ側のminio配下へ反映される様にマウントします。
* ここで言うコンテナ側のminioとは、上記`Dockerfile`で定義した`ENV APP_ROOT /minio`のことです。

```yml:docker-compose.yml
version: '3'
services:
  minio:
    build:
      context: .
      dockerfile: Dockerfile_minio
    environment:
      MINIO_ROOT_USER: user
      MINIO_ROOT_PASSWORD: password
    volumes:
      - minio_volume:/data
      - ./terraform:/minio
    ports:
      - "9000:9000"
      - "9001:9001"
```

### main.tf

`access_key`や`secret_key`は秘匿情報なので、本来は公開NGです。

今回は`AWS`ではなく、コンテナで実行している`MinIO`への接続なので、コメントにある記述が必要になります。

```terraform:terraform/main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  access_key          = "user"
  secret_key          = "password"
  region              = "ap-northeast-1"
  # MinIOでは s3_use_path_style = true が必要
  s3_use_path_style   = true

  endpoints {
    s3 = "http://minio:9000"
  }

  # 認証のエラーが出るため、以下の設定を追加して回避している
  skip_credentials_validation = true
  skip_requesting_account_id  = true
}

# バケットを作成する
resource "aws_s3_bucket" "development-bucket" {
  bucket = "dev-bucket"
}
```

また、`Terraform`を実行すると色々ファイルが生成されるので、git管理されない様に`gitignore`へ対象を追加します。

```gitignore:gitignore
# 以下を追加
terraform/*
!terraform/main.tf
```

#### セットアップ方法

MinIOのコンテナを起動します。

```shell
docker-compose up -d minio
```

MinIOのコンテナに接続します。

```shell
docker exec -it sample-minio-1 /bin/bash
root@fc644eb4df32:/minio#
```

接続したら、コンテナから以下コマンドを実行してバケットを作成します。

```sh
# 1. Terraformの初期化
terraform init

# 2. Terraformの実行確認
terraform plan

# 3. Terraformの実行
terraform apply
# -> yesを入力してください。
```

バケットを削除したいときは、以下コマンドを実行します。

```sh
terraform destroy
# -> yesを入力してください。
```

# 補足
### MinIOについて

MinIOはAWS APIと互換性を持つストレージサービスです。
本番、検証環境でAWS S3を使用しているサービスの場合、MinIOを使用して開発環境でも同じAPIを使用して開発を進めることができます。

### Terrafomについて

Terrafomはクラウドインフラの設計をコード化する事ができるサービスです。
個人的な理解としては、GUIでポチポチして作っていたインフラをコード化して保守性を高めようねという感じです。