12
1

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】OIDC認証でAWSデプロイを自動化する手順

12
Posted at

はじめに

本記事では、GitHub ActionsとTerraformを使用して、OIDC(OpenID Connect)認証によるAWSリソースのデプロイ環境を構築する手順を紹介します。従来のIAMユーザーのアクセスキーを使用する方法と比較し、OIDCを使用することでより安全な認証が実現できます。

本ブログに掲載している内容は私個人の見解であり、​所属する組織の立場や戦略、意見を代表するものではありません。​あくまでエンジニアとしての経験や考えを発信していますので、ご了承ください。​

OIDCとは

OIDC(OpenID Connect)は、OAuth 2.0をベースにした認証プロトコルです。GitHub ActionsからAWSへのアクセスにOIDCを使用することで、以下のメリットがあります:

  • セキュリティ向上: 長期的なアクセスキーをGitHub Secretsに保存する必要がない
  • 自動ローテーション: 一時的な認証情報が自動的に発行される
  • アクセス制御: 特定のリポジトリやブランチからのみアクセスを許可できる

前提条件

  • AWSとGitHubのアカウントを持っていること
  • Gitがインストールされていること

Git/GitHubの準備(リポジトリ作成と接続)

まず、ローカル環境とGitHubでリポジトリを準備します。

1. ローカルリポジトリの作成

VS Codeのターミナルやコマンドプロンプトで以下のコマンドを実行します。

# リポジトリ用のディレクトリを作成
mkdir terraform-aws
cd terraform-aws

# Git初期化(ローカルリポジトリとして設定)
git init

# READMEファイルを作成(最初のコミット用)
echo "# terraform-aws" >> README.md

# ステージングエリアに追加
git add .

# 最初のコミット
git commit -m "first commit"

Windows環境では C:\Users\ユーザー名\terraform-aws のようなパスにディレクトリが作成されます。

2. GitHubでリポジトリを作成

  1. GitHubにログイン

  2. 右上の「+」アイコンから「New repository」を選択

  3. リポジトリ設定:

    • Owner: 自分のアカウントを選択
    • Repository name: terraform-aws
    • Visibility: Private(推奨)

    image.png

  4. 「Create repository」をクリック

今回はAWSの認証情報を扱うため、必ずPrivateリポジトリとして作成してください。

3. ローカルとGitHubを接続してPush

GitHubでリポジトリを作成したら、ローカルリポジトリと接続します。

# リモートリポジトリを追加(HTTPSで接続)
git remote add origin https://github.com/YOUR_USERNAME/terraform-aws.git

# ブランチ名をmainに変更
git branch -M main

# GitHubへPush
git push -u origin main

YOUR_USERNAME の部分は、ご自身のGitHubユーザー名に置き換えてください。
初回のpush時には、GitHubの認証情報の入力を求められる場合があります。

これでローカルとGitHubの接続が完了し、コード管理の準備が整いました。

環境構築手順

1. AWSでOIDCプロバイダーを作成

まず、AWSマネジメントコンソールでGitHub用のOIDCプロバイダーを作成します。

  1. IAMコンソールを開く

  2. 「IDプロバイダー」→「プロバイダーを追加」を選択

  3. 以下の値を入力:

    • プロバイダーのタイプ: OpenID Connect
    • プロバイダーのURL: https://token.actions.githubusercontent.com
    • 対象者: sts.amazonaws.com

    image.png

2. IAMロールの作成

GitHub ActionsがAssumeできるIAMロールを作成します。

  1. IAMコンソールで「ロール」→「ロールを作成」を選択

  2. 「ウェブアイデンティティ」を選択

  3. アイデンティティプロバイダーでtoken.actions.githubusercontent.comを選択

  4. Audienceで sts.amazonaws.com を選択

  5. 信頼ポリシーを編集して、特定のリポジトリのみアクセスできるように設定

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
            },
            "StringLike": {
              "token.actions.githubusercontent.com:sub": "repo:YOUR_GITHUB_USERNAME/YOUR_REPO_NAME:*"
            }
          }
        }
      ]
    }
    

  6. 必要な権限ポリシーをアタッチ(今回は検証のためPowerUserAccessを利用しましたが、用途に応じて必要最小限の権限を付与してください。)

    image.png

  7. ロール名を設定して作成完了

  8. 作成したIAMロールのARNをコピーして控えておく(次のステップで使用します)

    image.png

3. GitHub Secretsの設定

IAMロールを作成したら、GitHubリポジトリにARNを登録します。

GitHub Secretsを使用することで、機密情報をコードへ直接書かずに安全に管理でき、暗号化されて保存されるためログにも表示されません。

設定手順

  1. GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」を開く
  2. 「New repository secret」をクリック
  3. 以下のシークレットを追加:
    • Name: AWS_ROLE_ARN
    • Value: 先ほど作成したIAMロールのARN(例: arn:aws:iam::123456789012:role/GitHubActionsRole
  4. 「Add secret」をクリック

このシークレットは、GitHub Actionsワークフローから ${{ secrets.AWS_ROLE_ARN }} として参照されます。

参考資料:
AWS公式ドキュメント: GitHub Actions での OIDC の設定

4. S3バケットの作成(Terraformステート管理用)

Terraformのステートファイルを保存するためのS3バケットを作成します。

  1. S3コンソールでバケットを作成
  2. バケット名を設定(例: terraform-state-your-name
  3. リージョンを選択(例: ap-northeast-1
  4. バージョニングを有効化(推奨)
  5. 暗号化を有効化(推奨)

5. Terraformの設定

terraform.tf

Terraformのバージョン、プロバイダー、バックエンドを設定します。

terraform {
  required_version = ">= 1.14" #バージョン指定はお使いの環境に合わせてください
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.68" #バージョン指定はお使いの環境に合わせてください
    }
  }

  backend "s3" {
    bucket  = "terraform-state-your-name" #自身のバケット名に変更してください
    region  = "ap-northeast-1"
    key     = "terraform.tfstate"
    encrypt = true
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

main.tf

実際にデプロイするAWSリソースを定義します。今回はサンプルとしてVPCを作成します。

# VPCを1つ作成する
resource "aws_vpc" "this" {
  cidr_block = "10.0.0.0/24"
  tags = {
    Name = "test-vpc"
  }
}

参考資料:
Terraform公式ドキュメント

6. GitHub Actionsワークフローの作成

.github/workflows/terraform.yml

Pull Requestがマージされた際に自動的にTerraformを実行するワークフローの一例です。

name: terraform apply test

on:
  pull_request:
    branches:
      - main
    types: [closed]

permissions:
  id-token: write # OIDCを利用する際に必須
  contents: read  # actions/checkout のために必要

jobs:
  terraform-apply:
    if: github.event.pull_request.merged == true
    name: Terraform Apply
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure AWS credentials from test account
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.14

      - name: Terraform Init
        id: init
        working-directory: ./terraform
        run: terraform init

      - name: Terraform Validate
        id: validate
        working-directory: ./terraform
        run: terraform validate -no-color

      - name: Terraform Plan
        id: plan
        working-directory: ./terraform
        run: terraform plan -no-color

      - name: Terraform Apply
        id: apply
        working-directory: ./terraform
        run: terraform apply -auto-approve

参考資料:
GitHub Actions公式ドキュメント: configure-aws-credentials

ディレクトリ構成

最終的なディレクトリ構成は以下のようになります:

.
├── .github/
│   └── workflows/
│       └── terraform.yml
├── terraform/
│   ├── main.tf
│   └── terraform.tf
└── README.md

実行方法(デプロイ)

実際にTerraformファイルを作成し、GitHub Actions経由でデプロイする手順を説明します。

1. ブランチを作成してファイルを追加

まず、作業用のブランチを作成します。

# 新しいブランチを作成して切り替え
git checkout -b github_test

この時点で、先ほど作成した以下のファイルがリポジトリに存在することを確認してください。

  • terraform/terraform.tf
  • terraform/main.tf
  • .github/workflows/terraform.yml

2. 変更をコミットしてPush

作成したファイルをステージングし、コミットしてGitHubにPushします。

# すべての変更をステージングエリアに追加
git add .

# コミットメッセージを付けてコミット
git commit -m "GitHub Workflow test commit"

# GitHubのリモートリポジトリへPush
git push -u origin github_test

3. Pull Requestを作成してマージ

  1. GitHubのリポジトリページを開く
  2. 「Compare & pull request」ボタンが表示されるのでクリック
  3. Pull Requestのタイトルと説明を入力
  4. 「Create pull request」をクリック
  5. 内容を確認後、「Merge pull request」をクリック
  6. 「Confirm merge」をクリックしてマージ完了

4. GitHub Actionsの実行を確認

Pull Requestがマージされると、自動的にGitHub Actionsが実行されます。

  1. リポジトリの「Actions」タブを開く

  2. 「terraform apply test」ワークフローの実行状況を確認

  3. 各ステップ(Init、Validate、Plan、Apply)の実行ログを確認

  4. すべてのステップが成功(✓)すれば、AWSリソースがデプロイされています

    image.png

5. AWSコンソールで確認

デプロイが成功したら、AWSマネジメントコンソールでリソースが作成されているか確認しましょう。

  1. AWSコンソールにログイン

  2. VPCダッシュボードを開く

  3. 作成したVPC(test-vpc)が表示されることを確認

    image.png

おまけ:リソースの削除もOIDC経路で安全に

デプロイだけでなく、リソースの削除(destroy)もOIDC認証経由で実行できます。ローカル環境からAWSにアクセスすることなく、すべての操作をGitHub経由で完結できます。

Destroy用のワークフロー例

.github/workflows/terraform-destroy.yml として保存します。

name: terraform destroy

on:
  workflow_dispatch:  # 手動実行のみ

permissions:
  id-token: write
  contents: read

jobs:
  terraform-destroy:
    name: Terraform Destroy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

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

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.14

      - name: Terraform Init
        working-directory: ./terraform
        run: terraform init

      - name: Terraform Destroy
        working-directory: ./terraform
        run: terraform destroy -auto-approve

実行方法

  1. GitHubリポジトリの「Actions」タブを開く
  2. 「terraform destroy」ワークフローを選択
  3. 「Run workflow」をクリックして実行

このワークフローは手動実行のみですが、実行すると即座にリソースが削除されます。実行前に削除対象を十分に確認してください。

トラブルシューティング

エラー: "Error: error configuring Terraform AWS Provider: failed to get shared config profile"

  • IAMロールのARNがGitHub Secretsに正しく設定されているか確認
  • AWS_ROLE_ARN のシークレット名が一致しているか確認

エラー: "Error: No valid credential sources found"

  • GitHub Actionsの permissionsid-token: write が設定されているか確認
  • AWS側のOIDCプロバイダーとIAMロールの信頼関係が正しく設定されているか確認

エラー: "Error: Failed to get existing workspaces"

  • S3バケットが存在するか確認
  • IAMロールにS3バケットへのアクセス権限があるか確認

まとめ

GitHub ActionsとTerraformを組み合わせ、OIDC認証を使用することで、安全かつ効率的なAWSリソースのデプロイ環境を構築できました。今回の構成により、以下を実現できました。

  • セキュリティの向上: アクセスキー管理が不要
  • 自動化: Pull Requestマージで自動デプロイ
  • チーム開発対応: S3によるステート管理

この仕組みを基盤として、より複雑なインフラ管理にも柔軟に対応できます。
ぜひ、皆さんの環境でも試してみてください!

12
1
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
12
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?