1. 概要
- OIDCとは何か、なぜアクセスキーより安全か
- GitHub ActionsのOIDCトークンの仕組み
- AWS IAMのOIDCプロバイダー設定とIAMロール作成
- GitHub ActionsでのOIDC認証設定
- conditionで特定リポジトリ・ブランチに限定する方法
GitHub ActionsからAWSを操作する際、従来はIAMアクセスキーをGitHub Secretsに保存していました。OIDCを使うと、一時的な認証情報を自動取得するため、長期間有効なアクセスキーが不要になります。
2. OIDCとは
OIDC(OpenID Connect)は、GitHub ActionsのジョブがAWSに対して「自分はGitHubのどのリポジトリのどのワークフローです」と証明する仕組みです。
GitHub Actions
│ OIDCトークン(JWT)を発行
↓
AWS IAM(OIDC プロバイダー)
│ トークンを検証 → 一時認証情報を発行
↓
AWS(S3・EC2等)
OIDCのメリット:
- アクセスキーを管理・ローテーションする必要がない
- 一時的な認証情報(15分〜12時間)のみ使用
- 特定リポジトリ・ブランチのみに権限を絞れる
3. AWSのOIDCプロバイダーとIAMロールを作成
# oidc_setup/main.tf
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
variable "github_org" {
description = "GitHubオーガニゼーション名"
type = string
}
variable "github_repo" {
description = "GitHubリポジトリ名"
type = string
}
# GitHubのOIDCプロバイダー(アカウントに1つ)
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
tags = {
Name = "github-oidc-provider"
Environment = var.environment
ManagedBy = "terraform"
}
}
# GitHub ActionsがAssumeRoleするIAMロール
resource "aws_iam_role" "github_actions" {
name = "GitHubActionsRole-${var.github_repo}"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = { Federated = aws_iam_openid_connect_provider.github.arn }
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
}
StringLike = {
# mainブランチのみに制限する場合
"token.actions.githubusercontent.com:sub" = "repo:${var.github_org}/${var.github_repo}:ref:refs/heads/main"
}
}
}
]
})
tags = {
Name = "GitHubActionsRole-${var.github_repo}"
Environment = var.environment
ManagedBy = "terraform"
}
}
# 必要な権限を付与(最小権限が望ましい)
resource "aws_iam_role_policy_attachment" "github_actions" {
role = aws_iam_role.github_actions.name
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
# 本番ではterraform実行に必要な最小権限ポリシーに絞る
}
4. conditionの書き方パターン
# パターン1: mainブランチのみ
"token.actions.githubusercontent.com:sub" = "repo:my-org/my-repo:ref:refs/heads/main"
# パターン2: リポジトリの全ブランチ(PRも含む)
"token.actions.githubusercontent.com:sub" = "repo:my-org/my-repo:*"
# パターン3: タグのみ
"token.actions.githubusercontent.com:sub" = "repo:my-org/my-repo:ref:refs/tags/*"
# パターン4: 特定の環境(GitHub Environmentsを使う場合)
"token.actions.githubusercontent.com:sub" = "repo:my-org/my-repo:environment:production"
推奨: planはPRで実行するため*、applyはmainブランチに限定するために別ロールに分けることも検討してください。
5. GitHub Actionsでの設定
# .github/workflows/terraform.yml
name: Terraform
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
id-token: write # OIDCトークン発行に必須
contents: read
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole-my-repo
aws-region: ap-northeast-1
# role-session-nameでセッションを識別しやすくする
role-session-name: GitHubActions-${{ github.run_id }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "~> 1.9"
- name: Terraform Init
run: terraform init
- name: Terraform Plan
if: github.event_name == 'pull_request'
run: terraform plan -no-color
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve
6. アクセスキー方式との比較
| 比較軸 | OIDC | アクセスキー |
|---|---|---|
| 認証情報の有効期限 | 一時的(15分〜12時間) | 永続(手動ローテーション必要) |
| シークレット管理 | 不要 | GitHub Secretsで管理 |
| ローテーション | 不要(自動) | 定期的に手動で実施 |
| 権限の絞り込み | ブランチ・環境単位で可能 | 全ジョブで同一キー |
| 漏洩リスク | 低(一時的トークン) | 高(長期間有効なキー) |
7. 関連記事
- GitHub ActionsでTerraformを実行する方法 — 基本ワークフロー
- GitHub Actions: 複数AWSアカウントへのデプロイ — マルチアカウント
- Terraform CI/CDのシークレット管理 — 認証情報の安全な扱い
- Terraform Cloud vs GitHub Actions — プラットフォーム比較
- variable(入力変数)の使い方 — sensitive変数との組み合わせ
- sensitive変数 — 機密値のマスクとstateへの記録 — シークレット管理
8. まとめ
- OIDCを使うとIAMアクセスキーなしでGitHub ActionsからAWSを操作できる
- GitHub OIDCプロバイダー(IAMの設定)とIAMロールをTerraformで一度だけ作成する
permissions: id-token: writeをワークフローに設定することでOIDCトークンが発行される- conditionでリポジトリ・ブランチ・環境を絞ることで最小権限の原則を守れる
- アクセスキー方式より安全で管理コストも低い。新規構築時はOIDCを選択する
対象バージョン: Terraform >= 1.9 / GitHub Actions (2024) 公式ドキュメント: https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services