TerraformからAWSへの権限の渡し方を整理と手順公開
どうも、拓田です。
TerraformでAWSを操作する際、「どうやってAWSに認証するか」の方法が複数あってわかりにくかったので整理しました。
またAWSにTerraformを使ってGitHub Actions + OIDC + S3 backendの組み合わせで構築してみたので、その手順を記載しておきます。
方法の一覧
| 方法 | 実行場所 | キーが必要か | 今回使う方式 |
|---|---|---|---|
| AWS CLI設定ファイル | ローカルPC | 必要 | ✅ |
| 環境変数 | ローカルPC | 必要 | |
| Providerブロック内のコンフィグ | main.tf | 必要(非推奨) | |
| IAMインスタンスプロファイル | EC2サーバー上 | 不要 | |
| GitHub OIDC | GitHub Actions | 不要 | ✅ |
| HCP Terraform Dynamic Provider Credentials | HCP Terraform | 不要 |
各方法の詳細
1. AWS CLI設定ファイル(aws configure)
ローカルPCで aws configure を実行し、IAMユーザーのアクセスキーを C:\Users\〇〇\.aws\credentials に保存する方法。TerraformもこのファイルをAWS CLIと共有して読み取ります。
aws configure
# AWS Access Key ID: (アクセスキーIDを入力)
# AWS Secret Access Key: (シークレットキーを入力)
# Default region name: ap-northeast-1
# Default output format: json
ローカル開発に最適な方法です。
2. 環境変数
AWS_ACCESS_KEY_ID などの環境変数にキーを設定する方法。セッション中のみメモリ上に存在し、ファイルとして残らないのが特徴です。
3. Providerブロック内のコンフィグ(非推奨)
main.tf のproviderブロックに直接キーを書く方法。
provider "aws" {
access_key = "AKIA..." # 絶対にやってはいけない
secret_key = "xxxx"
}
GitHubにpushするとキーが漏洩するため絶対に使わないこと。
4. IAMインスタンスプロファイル
EC2サーバー自体にIAMロールを割り当てる方法。EC2上でTerraformを実行する場合に使います。サーバー自身が権限を持つのでアクセスキーが不要です。自分のPCやGitHub Actionsから実行する場合は関係ありません。
5. GitHub OIDC(OpenID Connect)
GitHub ActionsからAWSに接続する際に、アクセスキーなしで認証する方法。チーム開発のベストプラクティスです。
OIDCとは?
「AがBに対して、自分はCという身元であると証明できる仕組み」です。
身近な例で言うと「Googleでログイン」ボタンがまさにOIDCです。
あるサービス → Googleに対して
「このユーザーは本当に〇〇@gmail.com ですか?」と確認
Googleが「はい、本人です」と証明する
パスワードを直接渡さずに、信頼できる第三者が身元を保証する仕組みです。
GitHub ActionsとAWSのOIDCの流れ
GitHub Actions
↓ 「私は正規のGitHub Actionsです」と証明(OIDC)
AWSが確認し、IAMロールの権限を一時的に貸し出す
↓
Terraformを実行
IAMユーザーとIAMロールの違い
| IAMユーザー | IAMロール | |
|---|---|---|
| 何か | 人間用のアカウント | 権限のセット。誰かに一時的に渡せる |
| アクセスキー | 発行する | 発行しない |
| 今回の使い方 | aws configure用 | GitHub Actions用 |
OIDCではIAMユーザーではなくIAMロールを作成します。アクセスキーが存在しないためキー漏洩リスクがゼロです。
GitHub Secretsに保存するもの
| 方式 | GitHub Secretsに保存するもの |
|---|---|
| アクセスキー方式 | アクセスキー+シークレットキー |
| OIDC方式 | AWSアカウントID・IAMロールのARN(キー情報ではない) |
6. HCP Terraform Dynamic Provider Credentials
HashiCorpのTerraform実行サービス(HCP Terraform)からAWSに接続する方法。GitHub ActionsのOIDCと似た概念ですが、出発点がGitHub ActionsではなくHCP Terraformです。
アクセスキー方式 vs OIDC方式(チーム開発)
| アクセスキー方式 | OIDC方式 | |
|---|---|---|
| キーの管理 | メンバーごとにIAMユーザー作成が必要 | IAMロール1つでOK |
| キー漏洩リスク | あり | なし(一時的な認証情報) |
| チーム開発 | 管理が煩雑 | シンプル |
| おすすめ度 | ローカル開発のみ | ✅ チーム開発のベストプラクティス |
今回の構成と構築する流れ
使う方法
ローカルPC → AWS CLI設定ファイル(aws configure)
GitHub Actions → OIDC(IAMロールのARNをGitHub Secretsに登録)
セットアップの流れ
① aws configure
IAMユーザーのアクセスキーをローカルに保存
→ 自分のPCからAWSをTerraformで操作できるようになる
↓
② GitHubにTerraformのリポジトリを作成
→ .gitignoreも忘れずに設定する
↓
③ OIDCの設定
AWSにIAMロールを作成し、GitHubからの接続を許可する
IAMロールのARNをGitHub Secretsに登録する
↓
④ S3 backendの設定(← main.tf作成前に必ずやること)
AWSにS3バケットを作成する
main.tfのterraformブロックにbackend設定を追加する
↓
⑤ main.tfを作成する(AWSリソースを定義する)
↓
⑥ GitHub Actionsのワークフローファイルを作成
↓
⑦ GitHubにpushすると自動でTerraformが実行され、AWSに反映される
→ stateファイルがS3に保存される
ポイント整理
- アクセスキーはローカルのみで使う(GitHubには登録しない)
- GitHub ActionsはOIDCでAWSに接続する(キー不要)
- GitHub Secretsにはロールの情報のみ保存(キー情報は保存しない)
- S3 backendは必ずmain.tf作成前に設定する(順番を守らないとstate管理の問題が発生する)
実際のセットアップ手順
① aws configure(ローカルPC → AWSの接続設定)
aws configure
# AWS Access Key ID: (IAMユーザーのアクセスキーIDを入力)
# AWS Secret Access Key: (シークレットキーを入力)
# Default region name: ap-northeast-1
# Default output format: json
設定後、以下のコマンドで接続確認します。
aws sts get-caller-identity
AWSアカウントの情報が表示されれば接続成功です。
② GitHubにTerraformのリポジトリを作成
GitHubにPrivateリポジトリを作成します。
- リポジトリ名:
terraform-aws-practice - Visibility:Private
作成後、ローカルのプロジェクトフォルダと紐付けます。
cd C:\Users\nisit\Documents\myproject
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/(ユーザー名)/terraform-aws-practice.git
git push -u origin main
.gitignoreの設定
Terraformが自動生成するファイルはGitHubに上げる必要がありません。.gitignore ファイルを作成して除外します。
.gitignore を作成する際、Windowsのメモ帳などで保存すると .gitignore.txt と拡張子がついてしまうことがあります。その場合は以下で修正してください。
Rename-Item .gitignore.txt .gitignore
.gitignore の内容:
# Terraformが自動生成するファイル
.terraform/
.terraform.lock.hcl
terraform.tfstate
terraform.tfstate.backup
作成後、GitHubに反映します。
git add .gitignore
git commit -m "Add .gitignore"
git push origin main
③ OIDCの設定(GitHub Actions → AWSの接続)
Step 1: IAM Identity Providerの登録
AWSコンソール → IAM → 左メニュー「IDプロバイダー」→「プロバイダーを追加」
| 項目 | 値 |
|---|---|
| プロバイダーのタイプ | OpenID Connect |
| プロバイダーのURL | https://token.actions.githubusercontent.com |
| 対象者 | sts.amazonaws.com |
Step 2: IAMロールの作成
AWSコンソール → IAM → 左メニュー「ロール」→「ロールを作成」
| 項目 | 値 |
|---|---|
| 信頼されたエンティティタイプ | ウェブアイデンティティ |
| IDプロバイダー | token.actions.githubusercontent.com |
| 対象者 | sts.amazonaws.com |
| GitHub organization | (GitHubのユーザー名) |
| GitHub repository | terraform-aws-practice |
| GitHub branch | main |
許可ポリシーは AdministratorAccess を選択。
ロール名は github-actions-terraform-role として作成します。
Step 3: GitHub SecretsにARNを登録
作成したロールのARNをコピーし、GitHubに登録します。
GitHubリポジトリ → Settings → Secrets and variables → Actions → 「New repository secret」
| Name | Value |
|---|---|
AWS_ROLE_ARN |
コピーしたARN(arn:aws:iam::〇〇:role/github-actions-terraform-role) |
AWS_REGION |
ap-northeast-1 |
TF_VAR_db_password |
RDSに設定するパスワード(8文字以上) |
④ S3 backendの設定(stateファイルの保存先)
S3 backendはmain.tfを作成する前に必ず設定してください。
設定しないとTerraformがstateファイルを保存できず、GitHub Actionsで実行するたびに「リソースが既に存在する」エラーが発生します。
Step 1: S3バケットを作成する
AWSコンソール → S3 →「バケットを作成」
| 項目 | 値 |
|---|---|
| バケット名 |
terraform-state-(任意の文字列) ※世界で一意 |
| リージョン |
ap-northeast-1(東京) |
| パブリックアクセス | すべてブロック ✅ |
| バージョニング | 有効にする ✅ |
| 暗号化 | SSE-S3 ✅ |
Step 2: main.tfにbackend設定を追加する
main.tf の terraform {} ブロック内に以下を追加します。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "terraform-state-(バケット名)"
key = "terraform.tfstate"
region = "ap-northeast-1"
}
}
これでTerraformの実行結果(stateファイル)がS3に保存され、GitHub Actionsが何度実行されても状態を正しく引き継げます。
⑤ GitHub Actionsのワークフローファイルを作成
.github/workflows/terraform.yml を作成します。
name: Terraform
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
jobs:
terraform:
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: ${{ secrets.AWS_REGION }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan
env:
TF_VAR_db_password: ${{ secrets.TF_VAR_db_password }}
- name: Terraform Apply
run: terraform apply -auto-approve
env:
TF_VAR_db_password: ${{ secrets.TF_VAR_db_password }}
mainブランチにpushするたびに自動でTerraformが実行されます。
⑥ pushして動作確認
git add .
git commit -m "Add AWS Terraform configuration with GitHub Actions"
git push origin main
GitHubリポジトリの Actionsタブ でワークフローの実行状況を確認できます。
成功するとAWSに以下のリソースが作成されます。
| リソース | 名前 |
|---|---|
| VPC | terraform-vpc |
| EC2 | terraform-wordpress |
| RDS | terraform-mysql |
⑦ 演習終了後は必ず削除する
演習が終わったら必ず削除してください。起動したままにすると無料枠を超えた時点で課金が発生します。
S3 backendを設定しているので、以下のコマンド一発で全リソースを削除できます。
terraform destroy
まとめ
今回やったことを振り返ります。
認証まわり
| やったこと | 理由 |
|---|---|
| IAMユーザーを作成してアクセスキーを発行 | ローカルPCからAWSに接続するため |
| aws configureでキーをローカルに保存 | TerraformがAWSを操作できるようにするため |
| IAM Identity Providerを登録 | GitHubからのOIDCリクエストを信頼するため |
| IAMロールを作成 | GitHub Actionsに一時的な権限を渡すため |
| GitHub SecretsにロールARNを登録 | キー情報をGitHubに置かずに済むため |
Terraform stateまわり
| やったこと | 理由 |
|---|---|
| S3バケットを作成 | stateファイルの保存先を用意するため |
| main.tfにbackend設定を追加 | GitHub Actionsがstateを共有できるようにするため |
GitHub Actions + OIDC + S3 backendの組み合わせで構築
アクセスキーが存在しない → キー漏洩リスクゼロ
stateファイルがS3に保存される → 何度pushしても状態が正しく引き継がれる
pushするだけでAWSに反映される → 手動操作ミスがなくなる
今回はこの3つを組み合わせで構築しました。
S3 + DynamoDB構成、というのもありますが、それはまた別途やってみようかと思います。