0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

# GitHub Actions × Terraform で AWS インフラを自動デプロイしてみた

0
Posted at

はじめに

インフラの変更を手動で terraform apply するのは、ミスのリスクもあるし、履歴も残りにくい。そこで今回は GitHub Actions を使って Terraform の実行を自動化し、CI/CD パイプライン上で AWS インフラを管理できる環境を構築しました。

OIDC(OpenID Connect)を使った パスワードレス認証 を採用しているので、AWS のアクセスキーをシークレットに保存する必要がないのもポイントです。


構成

ディレクトリ構成

GithubActions/
├── .github/
│   └── workflows/
│       ├── tf_deploy.yml    # Terraform Apply ワークフロー
│       └── tf_destory.yml   # Terraform Destroy ワークフロー
├── backend.tf               # S3 バックエンド設定
└── main.tf                  # AWS リソース定義

構成図

GitHub Actions
    │
    │ OIDC 認証(アクセスキー不要)
    ▼
AWS IAM Role
    │
    ├──▶ S3(tfstate 管理)
    │       bucket: hiro-tech-taku-terraform-tfstate-xxxxxxxx
    │
    └──▶ Terraform が管理する AWS リソース
              ├── VPC(10.0.0.0/16)
              └── Subnet(10.0.1.0/24 / ap-northeast-1a)

使用技術

カテゴリ ツール・サービス
IaC Terraform
CI/CD GitHub Actions
クラウド AWS(VPC, Subnet, S3, IAM)
認証 AWS OIDC(パスワードレス)
tfstate 管理 S3 バックエンド

作業手順

1. S3 バックエンドの設定

Terraform の状態ファイル(tfstate)を S3 で管理します。ローカルに tfstate を持たないことで、チーム開発や CI/CD との相性が格段に上がります。

# backend.tf
terraform {
  backend "s3" {
    bucket = "hiro-tech-taku-terraform-tfstate-xxxxxxxx"
    key    = "network/terraform.tfstate"
    region = "ap-northeast-1"
  }
}

2. AWS リソースの定義

今回は VPC とパブリックサブネットを東京リージョンに作成します。

# main.tf
provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a"
}

3. GitHub Actions の OIDC 認証設定

GitHub Actions から AWS へ安全に接続するため、OIDC を使います。事前に AWS 側で以下を設定します。

  1. IAM Identity Provider に GitHub の OIDC プロバイダー(token.actions.githubusercontent.com)を追加
  2. IAM ロール を作成し、Trust Policy でリポジトリからの Assume Role を許可
  3. ロールの ARN を GitHub リポジトリの Secrets に AWS_ROLE_ARN として登録

4. Terraform Apply ワークフロー

workflow_dispatch(手動実行)をトリガーとして、plan → apply を実行します。誤操作防止のため自動トリガーはあえて設定していません。

# .github/workflows/tf_deploy.yml
name: Terraform Apply

on:
  workflow_dispatch:   # 手動実行推奨(誤操作防止)

permissions:
  id-token: write
  contents: read

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      - uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1

      - name: Terraform Init
        run: terraform init

      - name: Terraform Plan
        run: terraform plan

      - name: Terraform Apply
        run: terraform apply -auto-approve

ポイント: permissions に id-token: write を付与することで OIDC トークンの発行が可能になります。

5. Terraform Destroy ワークフロー

リソースを削除するワークフローも別ファイルで管理します。こちらも workflow_dispatch のみに限定し、意図しない削除を防ぎます。

# .github/workflows/tf_destory.yml
name: Terraform Destroy

on:
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      - uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1

      - name: Terraform Init
        run: terraform init

      - name: Terraform Destroy
        run: terraform destroy -auto-approve

6. 動作確認

GitHub の Actions タブ → ワークフローを選択 → Run workflow ボタンで手動実行します。

各ステップが緑になれば成功。AWS コンソールで VPC とサブネットが作成されていることを確認できます。


振り返り

よかった点

  • OIDC 認証の採用 により、AWS のアクセスキーを一切 GitHub に登録せずに済んだ。セキュリティ面で安心感がある。
  • Apply と Destroy を別ワークフローに分離 することで、誤ってリソースを削除するリスクを減らせた。
  • アクション SHA ピン留め を使用しており、サプライチェーン攻撃への対策ができている。
  • S3 バックエンド を使うことで tfstate がリモートで管理され、どこからでも同じ状態で Terraform を実行できる。

改善したい点

  • Terraform Plan の結果をプルリクエストにコメント する仕組みを追加したい(terraform-plan-notifier などのアクションが使える)。
  • ブランチ戦略の整理:現状は workflow_dispatch のみだが、main ブランチへのマージをトリガーにした自動 apply も検討したい。
  • tfstate のロック:現在は S3 のみのバックエンドだが、DynamoDB によるステートロックを追加することで、同時実行による競合を防げる。
  • モジュール化:VPC やサブネットの定義が増えてきたら、Terraform モジュールとして切り出すと再利用性が上がる。

詰まった点

  • Terraform backend で変数が使えずエラー発生 (原因:backend ブロックは 変数禁止 → backend-config ファイルを生成する方式に変更)
  • GitHub Actions の OIDC が AssumeRole に失敗する問題:原因は Trust Policy の sub が GitHub の実際の sub と一致していない、GitHub の新しい OIDC 仕様(2026年以降)で ownerID と repoID が付与される形式 となっていることが判明
    従来:repo:owner/repo:ref:refs/heads/main
    現在:repo:owner@ownerID/repo@repoID:ref:refs/heads/main

まとめ

GitHub Actions と Terraform を組み合わせることで、インフラの変更をコードレビューのフロー上に乗せることができました。OIDC によるパスワードレス認証は最初の設定こそ少し手間がかかりますが、一度整えてしまえばセキュアで運用しやすい構成になります。

まずは小さなリソース(VPC/Subnet)から始めて、この構成を土台に本番環境のインフラ管理へ拡張していく予定です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?