TerraformファイルをGit Hubにプッシュしようとしたら400エラーが出た

## はじめに
こんにちは！今回は、Terraformで構築したインフラコードをGitHubにプッシュしようとしたときに遭遇したエラーと、その解決方法を共有したいと思います。同じ問題に直面した方の参考になれば嬉しいです。

## エラーの発生
Terraformファイルを含むリポジトリを初めてGitHubにプッシュしようとしたとき、以下のエラーが発生しました。

```bash
$ git push -u origin main
Enumerating objects: 32, done.
Counting objects: 100% (32/32), done.
Delta compression using up to 8 threads
Compressing objects: 100% (23/23), done.
error: RPC failed; HTTP 400 curl 22 The requested URL returned error: 400
send-pack: unexpected disconnect while reading sideband packet
Writing objects: 100% (32/32), 105.73 MiB | 10.90 MiB/s, done.
Total 32 (delta 2), reused 0 (delta 0), pack-reused 0
fatal: the remote end hung up unexpectedly
Everything up-to-date
```
最初はネットワークの問題かと思い、再度プッシュを試みましたが、同じエラーが発生しました。

## 初期対応：http.postBuffer の増加
同じようなエラーの解決方法を調べるとGitのHTTPポストバッファのサイズを増やす方法が紹介されていたのでそれを参考に実行してみました。

```bash
$ git config http.postBuffer 524288000  # 500MBに設定
````
しかし、再度プッシュを試みると、新たなエラーメッセージが表示されました。

```bash
remote: error: Trace: b4784a87453bda202ef526f94ce07330edd534c82b6392c8e55978bcd9ba5287
remote: error: See https://gh.io/lfs for more information.
remote: error: File terraform-ec2/.terraform/providers/registry.terraform.io/hashicorp/aws/5.55.0/darwin_arm64/terraform-provider-aws_v5.55.0_x5 is 482.25 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
```

このエラーメッセージから、問題のファイルが特定できました。

問題のファイル: 
```
terraform-ec2/.terraform/providers/registry.terraform.io/hashicorp/aws/5.55.0/darwin_arm64/terraform-provider-aws_v5.55.0_x5
```
ファイルサイズ: 482.25 MB（GitHubの制限である100MBを超過）

### このファイルは何か？
このファイルは、TerraformがインストールしたAWSプロバイダーの実行ファイル（バイナリ）です。具体的には、TerraformがAWSリソースを操作するために必要なプラグインであり、あなたのローカル環境（MacのARM64アーキテクチャ）用にダウンロードされたものです。

#### 場所: 
.terraform/ ディレクトリは、Terraformが依存関係（プロバイダーやモジュール）を保存するためのローカルキャッシュディレクトリです。
#### 重要性: 
これらのファイルはローカル環境専用であり、他の環境では再度ダウンロードされます。そのため、Gitで管理する必要はありません。
#### 解決方法：
大容量ファイルをGitの履歴から削除
問題の大容量ファイルをGitの履歴から削除する必要がありました。解決方法をChatGPTに相談したところ、git filter-branch コマンドを使う方法を教えてもらいました。

## リポジトリのバックアップ作成
まず、リポジトリの履歴を操作するため、バックアップを作成しました。

```bash
$ cd ..
$ cp -r terraform terraform_backup
```

## 大容量ファイルを履歴から削除
git filter-branch を使って、問題のファイルを履歴から削除しました。

```bash
$ cd terraform
$ git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch terraform-ec2/.terraform/providers/registry.terraform.io/hashicorp/aws/5.55.0/darwin_arm64/terraform-provider-aws_v5.55.0_x5" \
--prune-empty --tag-name-filter cat -- --all
```

## .gitignore ファイルの更新
今後同じ問題が起きないよう、.gitignore ファイルを設定しました。

```gitignore
# Terraform関連の不要なファイル・ディレクトリを除外

# すべてのディレクトリ内の .terraform/ ディレクトリを除外
**/.terraform/*

# Terraformの状態ファイルを除外
*.tfstate
*.tfstate.*
*.tfstate.backup

# Terraformの変数ファイル（機密情報を含む可能性あり）
*.tfvars
*.tfvars.json

# Terraformのプランファイル
*.tfplan

# Terraformのクラッシュログ
crash.log

# Terraformのオーバーライドファイル
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# TerraformのCLI設定ファイル
.terraformrc
terraform.rc
```

### 既にGitで追跡されている不要なファイルを削除する:

.gitignoreを更新しただけでは、既にGitで追跡されているファイルは除外されません。以下のコマンドでインデックスから削除してください。

```bash
git rm -r --cached .
```

この操作は、すべてのファイルを一旦インデックスから外し、.gitignoreの設定に基づいて再度追加します。

## 変更をコミット
```bash
$ git add . 
$ git commit -m "Remove large file and update .gitignore"
```

## リモートリポジトリへプッシュ
エラーが解消されたので、通常通りプッシュしました。

```bash
$ git push origin main
```
無事にプッシュが成功しました！

## まとめ
TerraformファイルをGitHubにプッシュしようとした際に、400エラーが発生し、その原因が大容量ファイルであることが判明しました。git config http.postBuffer 524288000 を試しても解決せず、最終的に git filter-branch を使用して問題のファイルを履歴から削除することで解決しました。

同じ問題に直面した方は、以下の点に注意してみてください。

不要なファイルをGitで管理しない: .gitignore を適切に設定し、不要なファイルがコミットされないようにします。今回ここの設定を適切にできていないことが原因でした！
同じようなエラーで困っている方の助けになれば幸いです。

## 追記
git filter-branch の非推奨について

git filter-branch は、履歴の書き換えに使用されてきましたが、操作が複雑で誤用しやすいため、現在は非推奨となっています。公式には git filter-repo の使用が推奨されています。git filter-repo は高速で安全に履歴を操作できるツールであり、操作もシンプルです。

### 履歴を書き換える際の注意

履歴の書き換えは強力な操作であり、リポジトリを破損させたり、他の開発者に影響を与える可能性があります。必ず以下の点に注意してください。

#### バックアップを取る: 
万が一の際に元に戻せるよう、リポジトリのバックアップを作成します。

#### 共有リポジトリでの注意: 
他の開発者がクローンしているリポジトリで履歴を書き換えると、プルやプッシュで問題が発生します。今回は個人で使用しているリポジトリでしたがチームで作業している場合は事前に共有し、適切な対応をとることをお勧めします。