1. 概要
- Terraform CI/CDにおけるシークレットの種類
- GitHub Actionsでのシークレット管理
- AWS Secrets Manager / SSM Parameter Storeとの連携
- シークレットをコードに埋め込まないためのベストプラクティス
Terraform CI/CDで扱うシークレットには「AWSクレデンシャル」「DBパスワード」「APIキー」などがあります。これらをソースコードやCI設定ファイルに直接書くのは非常に危険です。
2. シークレットの種類と管理場所
| シークレット種別 | 管理場所 | 理由 |
|---|---|---|
| AWS認証情報 | OIDCで不要化(推奨) / GitHub Secrets | 長期アクセスキーを排除 |
| Terraform Cloud APIトークン | GitHub Secrets | CI/CDからTF Cloudを操作する場合 |
| DBパスワード | AWS Secrets Manager / SSM Parameter Store | アプリが実行時に取得 |
| APIキー | AWS Secrets Manager | ローテーションが必要な場合 |
| SSH秘密鍵 | GitHub Secrets | プロビジョニング用 |
3. GitHub SecretsをTerraformに渡す
# .github/workflows/terraform.yml
name: Terraform
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 推奨: OIDCでAWS認証(GitHub Secretsにアクセスキー不要)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "~> 1.9"
- name: Terraform Init
run: terraform init
# GitHub SecretsをTerraform変数として渡す
- name: Terraform Apply
env:
TF_VAR_db_password: ${{ secrets.DB_PASSWORD }}
TF_VAR_api_key: ${{ secrets.THIRD_PARTY_API_KEY }}
run: terraform apply -auto-approve
4. TerraformコードでのSecrets Manager連携
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 "db_password" {
description = "RDSマスターパスワード"
type = string
sensitive = true # plan/apply出力でマスク
}
# Secrets Managerにシークレットを保存(Terraformで作成する場合)
resource "aws_secretsmanager_secret" "db" {
name = "/${var.environment}/app/db"
tags = {
Name = "${var.environment}-db-secret"
Environment = var.environment
ManagedBy = "terraform"
}
}
resource "aws_secretsmanager_secret_version" "db" {
secret_id = aws_secretsmanager_secret.db.id
secret_string = jsonencode({
username = "admin"
password = var.db_password # CI/CDからTF_VAR_db_passwordで渡す
})
}
# アプリが実行時にSecrets Managerから取得するための参照例
data "aws_secretsmanager_secret_version" "db" {
secret_id = aws_secretsmanager_secret.db.id
depends_on = [aws_secretsmanager_secret_version.db]
}
5. SSM Parameter StoreをTerraformで管理する
# SSM Parameter Storeにシークレットを保存
resource "aws_ssm_parameter" "api_key" {
name = "/${var.environment}/app/api-key"
type = "SecureString" # KMSで暗号化
value = var.api_key
tags = {
Name = "${var.environment}-api-key"
Environment = var.environment
ManagedBy = "terraform"
}
}
variable "api_key" {
description = "サードパーティAPIキー"
type = string
sensitive = true
}
6. 絶対にやってはいけないこと
# ❌ 絶対NG: シークレットをコードに直書き
resource "aws_db_instance" "bad" {
password = "SuperSecret123!" # コードにパスワードを書かない
}
# ❌ 絶対NG: tfvarsファイルをGitにコミット
# terraform.tfvars(Gitignoreに追加すること)
# db_password = "SuperSecret123!"
# ✅ 推奨: 環境変数経由(CI/CDでは自動設定される)
# TF_VAR_db_password=xxxx terraform apply
.gitignoreに必ず追加する:
# Terraform
*.tfvars
*.tfvars.json
.terraform/
terraform.tfstate
terraform.tfstate.backup
7. 関連記事
- GitHub Actions: OIDC認証でAWSクレデンシャルを排除する — OIDC設定
- GitHub ActionsでTerraformを実行する方法 — 基本ワークフロー
- sensitive変数 — 機密値のマスクとstateへの記録 — sensitiveの使い方
- tfsec — TerraformコードのIaCセキュリティスキャン — セキュリティスキャン
- Checkov — Terraformコードの静的解析 — 静的解析
- variable(入力変数)の使い方 — 変数の定義
8. まとめ
- AWSクレデンシャルはOIDCで不要化するのが最優先。アクセスキーはGitHub Secretsに保存しない
- DBパスワード等はCI/CD変数(GitHub Secrets)として管理し、
TF_VAR_*でTerraformに渡す - Secrets Manager / SSM Parameter Storeを活用してアプリが実行時に取得する設計にする
.tfvarsファイルは.gitignoreに追加してコミットしない
対象バージョン: Terraform >= 1.9 / GitHub Actions (2024) 公式ドキュメント: https://developer.hashicorp.com/terraform/language/values/variables#environment-variables