Terraformのプロバイダ認証設計 — キーレス認証への移行判断

TerraformによるインフラのCI/CD化が定着するにつれ、プロバイダ認証の設計が本番環境の安全性を左右する判断ポイントになっています。静的アクセスキーを慣習的に使い続けることで、侵害時の影響範囲が広がりやすい構造が生まれます。本記事では、OIDC federationによるキーレス認証への移行判断、IAMロール連鎖の設計指針、ローカル・CI・マルチアカウントそれぞれの認証戦略を体系的に解説します。移行コストより先に「移行しないコスト」を見極めることが、設計判断の起点です。

静的アクセスキーをTerraformで使い続けることのリスク

キーの棚卸し不足が招く侵害経路の拡散

Terraformのプロバイダ設定に静的アクセスキーを渡す構成は、初期セットアップの手軽さゆえに広く使われています。しかし、CIパイプラインのシークレット変数・ローカルの.envファイル・tfvarsファイル・コンテナイメージの環境変数と、キーを渡す経路が増えるほど、どこに何世代のキーが残っているかを追跡するコストが跳ね上がります。一般的には、プロジェクト初期から数年運用したTerraformリポジトリを調査すると、有効なままローテーションされていないキーが複数のCIシステムにまたがって残存しているケースが少なくありません。棚卸しができていないキーは「使われていない可能性が高い」と放置されがちですが、削除すると壊れるパイプラインへの不安から誰も手を付けられない状態に陥ります。

TerraformのCI環境で静的キーが漏洩する典型パターン

よくあるつまずきとして、CI設定ファイル(.gitlab-ci.ymlやJenkinsfileなど)に環境変数としてキーを埋め込んだまま、リポジトリをフォークしたり公開設定を誤ったりするケースがあります。Terraformのterraform plan出力をアーティファクトとして保存するパイプラインでは、プロバイダの設定ブロックに含まれるアクセスキーIDがログに平文で残ることもあります。また、ステートファイル(terraform.tfstate)をローカルで管理している環境では、ステートファイル自体に認証情報が混入するリスクがあります。これらはいずれも「キーが長期的に存在すること」に起因する問題であり、有効期限のないクレデンシャルを発行しない設計に切り替えることで根本的に回避できます。

最小権限原則の形骸化が起きる構造的な理由

静的キーを使い続ける環境では、最小権限原則の維持が困難になりがちです。理由の一つは、キーに紐付くIAMユーザーに付与された権限が「いつ何のために付けたか」の文脈を失いやすいことです。Terraformが扱うリソースは時間とともに増えるため、既存のキーに対して権限を追加するだけで対応が終わってしまい、削除の機会が生まれません。結果として、当初は限定的だったはずのIAMユーザーが、最終的にはほぼ管理者相当の権限を持つ構成になっていることがあります。キーレス認証への移行を検討するタイミングの一つは、このIAMユーザーの権限棚卸しに工数がかかりすぎると感じた時です。

OIDC federationでCIからキーレス認証する設計

OIDCトークン発行の仕組みと信頼関係の設定

OIDC(OpenID Connect)federationを使うと、CIプラットフォームが発行した短命のJWTトークンをAWSのSTSが検証し、一時クレデンシャルを発行する仕組みを実現できます。AWSでは、IDプロバイダとしてCIプラットフォームのOIDC URLを登録し、IAMロールの信頼ポリシーに「特定のリポジトリ・ブランチから発行されたトークンのみ引き受けを許可する」条件を記述します。トークンの有効期限はCIプラットフォーム側のセッション設定に依存しますが、AWSのSTSが発行する一時クレデンシャルの有効期間は最短で15分から設定できます。長期間有効な静的キーと比べると、侵害が起きた場合の被害時間窓が大幅に狭まります。

GitHub ActionsとAWSを繋ぐ設計判断のポイント

GitHub ActionsでOIDCを使う場合、IAMロールの信頼ポリシーに設定する条件として、token.actions.githubusercontent.com:subクレームを使ったリポジトリ・ブランチ・環境のフィルタリングが重要です。repo:org/repo:ref:refs/heads/mainのように具体的な条件を絞ることで、フォークリポジトリや意図しないブランチからのロール引き受けを防ぎます。よくある設計ミスは、subクレームの条件をrepo:org/*のようにワイルドカードで広げすぎることです。想定例として、10以上のリポジトリが同一のIAMロールを引き受けられる設定になっていた場合、一つのリポジトリへの不正アクセスが他のリポジトリのデプロイ権限にも波及するリスクがあります。条件の粒度はリポジトリ単位を原則とし、共有が必要な場合は意図を明文化したうえで設計します。

GitLab CIやBitbucket Pipelinesへの適用判断

OIDC federationはGitHub Actionsに限らず、GitLab CI(バージョン15.7以降)やAtlassian Bitbucket Pipelinesでも利用できます。ただし、各プラットフォームで発行されるクレームの構造が異なるため、IAMロールの信頼ポリシーに設定する条件キーもプラットフォームに合わせて変える必要があります。GitLab CIではgitlab.com:subクレームにプロジェクトパスとブランチ情報が含まれ、Bitbucketではari:cloud:bitbucket::workspace/形式のクレームを使います。複数のCIプラットフォームを並行して使っている環境では、プラットフォームごとにIDプロバイダとIAMロールを分離することで、設定の見通しを保ちながらスコープを絞ることができます。

IAMロール引き受け連鎖をどこまで短くするか

ロール連鎖が深くなるアンチパターン

AWSのAssumeRoleはロールからさらに別のロールを引き受ける「連鎖(chaining)」が可能ですが、連鎖が深くなるほど問題が生じやすくなります。一般的には、CIのOIDCロール → 中間委譲ロール → デプロイ用ロール → リソース操作ロールのように3段以上の連鎖が生まれた場合、どの段で権限不足が起きているかのデバッグに時間を取られます。また、AWSのAssumeRole連鎖にはセッション継承の制約(--role-session-nameやタグの引き継ぎ制限)があり、ポリシーでセッションタグを使った属性ベースアクセス制御(ABAC)を導入しようとすると、連鎖の途中でタグが消える問題に直面することがあります。ロール連鎖は「必要最小限に留める」という設計原則を最初から組み込んでおくことが重要です。

推奨する連鎖の深さと判断基準

設計判断の目安として、ロール連鎖は2段(CIロール → デプロイ対象アカウントのロール)を上限とすることを検討してください。3段以上が必要に感じる場合は、権限の分割方法かアカウント構造の見直しで解消できることが多いです。チェックリストとして、連鎖を増やす前に次の点を確認することを推奨します。

  • 中間ロールが「権限の委譲」以外の目的(ログ記録・タグ付け・監査)を担っているか
  • 中間ロールを削除してデプロイ対象ロールに直接信頼ポリシーを付けることで同等の制御が実現できないか
  • 連鎖の各段でセッションの最大有効期間(デフォルト1時間)がterraform applyの実行時間に収まるか
  • 連鎖による一時クレデンシャルの入れ子構造がTerraformのプロバイダ設定で正しく解決されるか

連鎖を短縮するためのアカウント設計との関係

ロール連鎖が深くなりがちな環境は、マルチアカウント構成における「誰がどこから何にアクセスするか」の設計が曖昧なことが多いです。Organizations構成でSCPを適切に設定していれば、各デプロイ対象アカウントに直接信頼ポリシーを付与するだけで、中間ロールなしに目的の操作権限を持つロールを引き受けられます。ロール連鎖の段数を増やす設計判断を行う前に、アカウント境界とSCPによる制御で代替できないかを先に検討することが、シンプルな認証チェーンを維持する鍵です。

ローカル開発でのaws-vaultとインスタンスプロファイルの使い分け

aws-vaultが解決する問題とその設計上の位置づけ

aws-vaultは、ローカル開発者のマシン上でAWS認証情報をOSのキーチェーン(macOS Keychain・Linux Secret Service)に保管し、プロセス単位で一時クレデンシャルを注入するツールです。静的キーを~/.aws/credentialsにプレーンテキストで保管することと比較すると、マシンが盗難にあった場合のリスクを低減できます。設計判断として重要なのは、aws-vaultは「静的キーの保管場所を安全にする」ツールであり、静的キーそのものを排除するものではない点です。aws-vaultを使っても、背後にはIAMユーザーの長期クレデンシャルが存在します。したがって、aws-vaultは「静的キーを今すぐゼロにできない環境での暫定的な保護策」として位置づけ、最終的にはキーレス認証への移行を見据えた設計をとることが望ましいです。

インスタンスプロファイルとEC2開発環境での選択判断

開発作業をEC2インスタンスやCloud9上で行う環境では、インスタンスプロファイルによる認証が選択肢として浮上します。IMDSv2(Instance Metadata Service v2)経由で取得する一時クレデンシャルは、インスタンス単位でIAMロールを割り当てることで管理でき、個人の静的キーを一切発行せずにTerraformを実行できます。ただし、複数の開発者が同一インスタンスを共有する構成では、誰がどの操作を行ったかの追跡が困難になります。想定例として、5人の開発チームが共有EC2で作業する場合、CloudTrailのログに記録されるPrincipalが全員同じIAMロールになるため、個人の操作を事後に追跡できなくなります。インスタンスプロファイルを使うなら、開発者1人あたり1インスタンスを割り当てる、またはCloud9のように個人ワークスペースに対してプロファイルが紐付く仕組みを選ぶことで、追跡可能性を確保できます。

環境ごとの認証方式を統一しない設計の是非

ローカル開発はaws-vault、CIはOIDC、本番デプロイはIRSA(IAM Roles for Service Accounts)というように、環境ごとに認証方式が異なることは避けられません。重要なのは、方式の違いをTerraformのプロバイダ設定でどう吸収するかの設計判断です。AWS_PROFILE環境変数とプロファイルの切り替えを使う方法は、CI環境でプロファイルファイルが存在しないときに失敗しやすいです。各環境で共通して機能する方法は、プロバイダブロックに認証方式を明示せず、AWS SDKのデフォルトの認証チェーン(環境変数 → インスタンスメタデータ → プロファイル)に委ねる設計です。ただし、この方法は「何がどの順序で使われているか」が見えにくくなるため、CI設定とローカル実行手順に明示的なドキュメントを用意することとセットで採用してください。

複数アカウントをまたぐ認証チェーンの設計

Organizations構成での認証ハブアカウントパターン

AWS Organizationsを使ったマルチアカウント構成では、CI/CDからのTerraform実行のための認証を「ツールアカウント」に集約するパターンが広く採用されています。CIはツールアカウントのIAMロールをOIDC経由で引き受け、そこからデプロイ対象の各アカウントへのクロスアカウントAssumeRoleを行う設計です。このパターンの利点は、OIDCプロバイダの設定とCI固有の信頼ポリシーを一つのアカウントに集約でき、各ワークロードアカウントにはシンプルなクロスアカウント信頼ポリシーだけを持てばよい点です。想定例として、20以上のアカウントを持つOrganizationsであれば、各アカウントにOIDCプロバイダを個別に設定するより、ツールアカウント経由の一元管理の方が設定の変更コストを大幅に下げられます。

クロスアカウントロール信頼ポリシーの設計判断

クロスアカウントのAssumeRoleを設計する際の判断ポイントは、「どのプリンシパルからの引き受けを許可するか」の粒度です。ツールアカウントのIAMロールARNを直接指定する方法は明確ですが、ロールARNが変わるたびに全対象アカウントの信頼ポリシーを更新する必要があります。代替として、Organizations全体または特定OUからの引き受けを許可するaws:PrincipalOrgID条件キーを使うと、ARN変更への対応が不要になります。ただし、この方法はOrganizations内の任意のアカウントからの引き受けを許可するリスクもあるため、aws:PrincipalTagを組み合わせた属性ベースの絞り込みを検討することが重要です。

アカウント数の増加に対応するスケール設計

アカウント数が30を超えるあたりから、各アカウントへの認証設定の管理をTerraform自体で自動化する設計が現実的になります。ツールアカウントのIAMロールと各ワークロードアカウントの信頼ポリシーをTerraformのモジュールとして管理し、新規アカウント追加時に自動でロールが作成されるパイプラインを組む設計です。この自動化を機能させるには、Organizations管理アカウント(またはDelegated Administrator)からメンバーアカウントへのIAM操作権限をどう付与するかという、鶏と卵の問題に直面します。一般的な解決策は、Account Vending Machine(AVM)やControl Towerのカスタマイゼーションで初期ロールを作成し、その後はTerraformが管理を引き継ぐ設計です。

プロバイダ認証情報のローテーション設計

静的キーのローテーション頻度の設計判断

完全なキーレス化が困難な環境で静的キーを使い続ける場合、ローテーション頻度の設計が重要です。90日以内のローテーションがセキュリティガイドラインの基準とされることが多いですが、ローテーションを手動で行う運用は実際には徹底されにくいです。設計として有効なのは、ローテーションを自動化するかロール設計でローテーション不要な構成に変えるかの二択を明確にすることです。AWS Secrets ManagerのIAMクレデンシャル自動ローテーション機能や、CI側でシークレットの有効期限を検出してアラートを上げる仕組みを組み込まない限り、90日ルールは形骸化します。

キーレス認証でのトークン有効期限設計

OIDCやインスタンスプロファイルによる一時クレデンシャルは、有効期限がSTSの発行ポリシーで制御されます。terraform applyが長時間に及ぶ大規模なデプロイでは、途中でクレデンシャルが期限切れになりデプロイが失敗するリスクがあります。想定例として、100以上のリソースを一度に作成・変更するapplyが2時間を超えた場合、STSの一時クレデンシャルのデフォルト有効期間(1時間)を超えて失敗するケースがあります。対策として、IAMロールの最大セッション期間を4〜8時間に設定する、または大規模なapplyを小さなtarget単位に分割する設計判断が必要です。

ローテーション自動化を組み込むタイミングの判断

認証情報のローテーション自動化は「後で追加する」と判断すると後回しになりがちです。設計原則として、パイプラインの初期構築時にローテーション・期限切れ検出の仕組みを含めることを推奨します。静的キーが残る環境であれば、CIパイプラインの中でキーの最終ローテーション日をAWS APIで確認し、閾値(例:60日)を超えたらデプロイをブロックするステップを入れることが有効です。これはローテーションを強制するための仕組みであり、運用ルールだけに頼る設計との大きな違いです。キーレス化後はこのステップが不要になるため、移行の完了を検証する指標としても機能します。

認証方式比較表(静的キー/OIDC/IRSA/インスタンスプロファイル)

各認証方式の特性を設計判断の観点で整理します。「どの環境で何を重視するか」の選定基準として活用してください。

認証方式 主な使用環境 クレデンシャルの有効期限 静的キー発行の要否 設定の複雑さ 主な設計上の注意点
静的アクセスキー(IAMユーザー) ローカル開発・レガシーCI 無期限(手動ローテーション) 必要 低 漏洩時の有効期間が長い。棚卸しコストが増大しやすい
OIDC federation(GitHub Actions等) CI/CDパイプライン 15分〜8時間(STSで制御) 不要 中 信頼ポリシーのクレーム条件を絞らないと過剰な引き受けが可能になる
IRSA(IAM Roles for Service Accounts) EKS上のTerraform実行Pod 短命(Kubernetesトークン連動) 不要 高 EKS OIDCプロバイダとServiceAccountのアノテーション設定が必要。EKS外では使えない
インスタンスプロファイル EC2・Cloud9での開発・CI 短命(IMDSv2で自動更新) 不要 低〜中 共有インスタンスでは個人操作の追跡が困難。IMDSv2の強制有効化が前提
aws-vault(静的キーの保護) ローカル開発者マシン 無期限(バックの静的キー依存) 必要 低 静的キーを排除するものではなく、保管場所を安全にする暫定策

選定の判断フローとして、まず「CIパイプライン上でTerraformを実行するか」を確認します。CIから実行するならOIDC federationを第一候補とし、EKS上での実行であればIRSAを選択します。ローカル開発では、静的キーを完全に廃止できないならaws-vaultと合わせて使いつつ、開発環境をEC2に統一できるならインスタンスプロファイルへの移行が長期的な設計として有利です。静的キーを残す環境では、キーの有効期限監視と90日以内のローテーション自動化を必ずセットで設計に組み込んでください。

▶ 手を動かして本番まで到達する

設計の型は掴めても、本番でTerraformを通しきる経験は別物です

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

2日間の集中ハンズオンで、AWS上にIaCで構築しきる経験を持ち帰れます。設計判断を、動くコードと本番環境の手応えに変える場です。

TerraformのキーレスOIDC認証設計を実践するTerraformコースへ →

Terraformマスターセミナー|2日間ハンズオンでAWS上にIaCで本番構築