AWS×GitHub Actionsで実践するIaCデプロイ自動化:トラブルシューティング編
はじめに
クラウドインフラストラクチャの構築・管理において、Infrastructure as Code(IaC)とCI/CDパイプラインの組み合わせは現代のベストプラクティスとなっています。
今回は、AWS環境をTerraformで構築し、GitHub Actionsを用いて自動デプロイする過程で遭遇した様々なエラーと、その解決方法について詳しく解説します。
実際のプロジェクト進行では、理想通りに進まないことがほとんどです。
この記事では特に 「失敗から学ぶ」 という観点から、私が直面した問題とその解決策を共有します。
プロジェクト概要
今回のプロジェクトでは、以下の技術スタックを使用しました:
- インフラ定義: Terraform
- クラウドプロバイダ: AWS(Amazon Web Services)
- CI/CD: GitHub Actions
- バージョン管理: Git/GitHub
目標は、コードをプッシュするだけでAWS環境が自動的に構築・更新される仕組みを作ることでした。
遭遇したエラー①:AWS認証情報の問題
エラー内容
最初に遭遇したのは、GitHub Actionsのワークフロー実行時に発生したAWS認証エラーでした。
Run terraform fmt -check
/home/runner/work/_temp/5d7b0f66-6c5e-4010-ad77-73ef92e81c1b/terraform-bin fmt -check
backend.tf
main.tf
Error: Terraform exited with code 3.
Error: Process completed with exit code 1.
一見するとフォーマットエラーのように見えますが、実際には認証情報の問題が根本原因でした。
原因分析
調査の結果、以下の問題が見つかりました:
- 無効なAWSアクセスキー: GitHub Secretsに設定したAWSアクセスキーが無効または期限切れでした
- S3バケット設定の問題: Terraformのバックエンドとして使用するS3バケットが正しく設定されていませんでした
- DynamoDBテーブルの権限不足: 状態ロック用のDynamoDBテーブルを作成する権限がありませんでした
解決策
-
AWS IAMで新しいアクセスキーを作成
- IAMコンソールから専用のデプロイ用ユーザーを作成
- 必要最小限の権限を持つポリシーを作成・アタッチ
- 新しいアクセスキーをGitHub Secretsに設定
こちらの記事を参考にアクセスキーを作成しました。
-
S3バケットの正しい設定
terraform { backend "s3" { bucket = "terraform-state-fumipen-123" # 実際に作成したバケット名 key = "aws/terraform.tfstate" region = "ap-northeast-1" encrypt = true } }
-
DynamoDBテーブルの設定を一時的に削除
- 権限の問題を回避するため、DynamoDBによる状態ロックを一時的に無効化
遭遇したエラー②:GitHubの大容量ファイル制限
エラー内容
Terraformの設定が完了し、コードをGitHubにプッシュしようとした際に以下のエラーが発生しました:
remote: error: File aws/.terraform/providers/registry.terraform.io/hashicorp/aws/5.90.0/darwin_amd64/terraform-provider-aws_v5.90.0_x5 is 669.60 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.
To https://github.com/fumifumi0831/terraform-multicloud-deploy.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://github.com/fumifumi0831/terraform-multicloud-deploy.git'
原因分析
Terraformを初期化すると、.terraform
ディレクトリにプロバイダーのバイナリファイルがダウンロードされます。AWSプロバイダーは特に大きく、669.60MBもあり、GitHubの制限(100MB)を大幅に超えていました。
さらに問題だったのは、このファイルが誤ってGitの追跡対象になっていたことです。.gitignore
ファイルが適切に設定されていなかったため、Terraformの一時ファイルやバイナリがリポジトリに含まれてしまいました。
解決策
-
適切な.gitignoreファイルの作成
# Local .terraform directories **/.terraform/* # .tfstate files *.tfstate *.tfstate.* # Crash log files crash.log crash.*.log # Exclude all .tfvars files *.tfvars *.tfvars.json # Ignore override files override.tf override.tf.json *_override.tf *_override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc # Ignore lock files .terraform.lock.hcl # macOS .DS_Store
-
既に追跡されているファイルの削除
git rm -r --cached aws/.terraform git commit -m "Remove .terraform directories from git"
-
Gitの履歴からも大きなファイルを削除
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch aws/.terraform/providers/registry.terraform.io/hashicorp/aws/5.90.0/darwin_amd64/terraform-provider-aws_v5.90.0_x5" --prune-empty --tag-name-filter cat -- --all git gc --prune=now git push origin main --force
この一連の操作により、大きなファイルをGitの履歴から完全に削除し、リポジトリのサイズを適切に保つことができました。
gitの追跡ファイルの削除やGitの履歴からも削除する方法についてはこちらに方法を詳しく載せてます。
学んだ教訓
1. 事前準備の重要性
-
適切な.gitignoreの設定: プロジェクト開始時に適切な
.gitignore
ファイルを用意することで、多くの問題を未然に防げます - 権限の最小化: 必要最小限の権限を持つIAMユーザーを使用することでセキュリティリスクを低減できます
2. トラブルシューティングのアプローチ
- エラーメッセージの正確な理解: 表面的なエラーメッセージだけでなく、根本原因を特定することが重要です
- 段階的な検証: 小さな変更を加えて検証することで、問題の切り分けがしやすくなります
3. CI/CDパイプラインの設計
- 環境変数とシークレットの管理: 認証情報は必ずGitHub Secretsなどの安全な方法で管理する
- ワークフローの分割: 複雑なワークフローは小さく分割し、各ステップで適切な検証を行う
GitHub Actionsワークフローの最終形
最終的に完成したGitHub Actionsのワークフローは以下のようになりました:
name: Multi-Cloud Terraform Deployment
on:
# プッシュ時に実行
push:
branches: [ main ]
paths:
- 'aws/**'
- '.github/workflows/**'
# プルリクエスト時に実行
pull_request:
branches: [ main ]
paths:
- 'aws/**'
- '.github/workflows/**'
# 手動実行
workflow_dispatch:
inputs:
deploy_target:
description: 'デプロイターゲット'
required: true
default: 'aws'
type: choice
options:
- aws
jobs:
# 変更されたディレクトリを検出するジョブ
detect-changes:
runs-on: ubuntu-latest
outputs:
aws_changed: ${{ steps.filter.outputs.aws }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Filter paths
uses: dorny/paths-filter@v2
id: filter
with:
filters: |
aws:
- 'aws/**'
# AWS デプロイジョブ
deploy-aws:
needs: detect-changes
if: |
github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_target == 'aws' ||
github.event_name != 'workflow_dispatch' && needs.detect-changes.outputs.aws_changed == 'true'
runs-on: ubuntu-latest
environment: aws-deployment
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.5.0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Terraform Init
run: terraform init
working-directory: ./aws
- name: Terraform Format
run: terraform fmt -check
working-directory: ./aws
- name: Terraform Validate
run: terraform validate
working-directory: ./aws
- name: Terraform Plan
run: terraform plan
working-directory: ./aws
if: github.event_name == 'pull_request'
- name: Terraform Apply
run: terraform apply -auto-approve
working-directory: ./aws
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
まとめ
AWS環境をTerraformとGitHub Actionsで自動デプロイする過程では、様々な問題に直面しました。特に認証情報の管理や大きなファイルの取り扱いには注意が必要です。
しかし、これらの問題を一つずつ解決していくことで、堅牢なCI/CDパイプラインを構築することができました。失敗から学ぶことで、より深い知識と経験を得ることができたと感じています。
IaCとCI/CDの組み合わせは、現代のクラウドインフラ管理において非常に強力なアプローチです。初期設定に手間がかかることもありますが、一度構築してしまえば、インフラの変更を安全かつ迅速に行うことができます。
皆さんもぜひ、この記事で紹介したトラブルシューティングの知識を活かして、自分だけのIaCパイプラインを構築してみてください。
今回私が作成したリソースはこちらです。
最後に
私は2つのプラットフォームで生成AIに関する発信を行なっております。
生成AIサービスの考察を見たい方へ
生成AIサービスの動向やや具体的な内容は、noteで詳しく解説しています。
noteプロフィール: @mizupee
日々の生成AI分析を追いたい方へ
毎日1つの生成AIサービスを分析するTwitter投稿「#100DaysofAI」もぜひフォローください。簡潔なポイント分析とアイデア共有を継続中です。
Twitter: @mizupee
参考リソース
この記事が皆さんのクラウドインフラ自動化の旅に役立つことを願っています。質問やフィードバックがあれば、コメント欄でお待ちしています!
Discussion