📑
Terraform 1.10のEphemeralでシークレット管理しましょう
はじめに
インフラストラクチャーコード(IaC)の普及に伴い、運用効率が大幅に向上しましたが、シークレット(パスワードやAPIキー)の安全な管理は依然として大きな課題です。Terraform 1.09まで、シークレットがステートファイルに保存されるリスクがありましたが、「エフェメラル値」機能の登場により、この課題が根本的に解決されました。今回Terraform 1.10のEphemeral値シークレット管理をしてみました。
比較:ランダム文字列 vs Ephemeral値
①ランダム文字列(random_string)の使用
Terraformのrandom_string
を使うことで、手軽に資格情報を生成できますが、この方法では生成されたシークレットがステートファイルに保存されるため、漏洩リスクが高まります。
random_string
リソースを使ったTerraformファイル
例: resource "random_string" "resource_password" {
length = 16
special = true
upper = true
lower = true
numeric = true
}
問題点:
- 生成されたパスワード(random_string.resource_password.result)がステートファイルに保存される。
- ステートファイルが誤管理された場合、シークレットが漏洩する可能性がある。
結果のterraform.tfstate例:
{
"version": 4,
"terraform_version": "1.10.0",
"serial": 4,
"lineage": "b1dfe50f-aa0c-aed2-c925-cd56062b4dad",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "random_string",
"name": "resource_password",
"provider": "provider[\"registry.terraform.io/hashicorp/random\"]",
"instances": [
{
"schema_version": 2,
"attributes": {
"id": "1dJdLfmM$evgk\u003cue",
"keepers": null,
"length": 16,
"lower": true,
"min_lower": 0,
"min_numeric": 0,
"min_special": 0,
"min_upper": 0,
"number": true,
"numeric": true,
"override_special": null,
"result": "1dJdLfmM$evgk\u003cue",
"special": true,
"upper": true
},
"sensitive_attributes": []
}
]
}
],
"check_results": null
}
②エフェメラル値とAWS Secrets Managerの使用
Terraform 1.10では、エフェメラル値により、シークレットがステートファイルやプランファイルに保存されることを防ぎます。この方法では、シークレットはTerraformの実行フェーズ中のみ一時的に利用されます。
例: エフェメラル値を使ったTerraformファイル
terraform {
required_version = ">= 1.10.0"
}
provider "aws" {
region = "ap-northeast-1"
}
ephemeral "aws_secretsmanager_secret_version" "test_secret" {
# AWS SecretのARN
secret_id = "arn:aws:secretsmanager:ap-northeast-1:1234567890:secret:secret-arn"
}
利点:
- シークレットがステートファイルに保存されない。
- シークレットはTerraformの実行中のみ存在し、永続化されない。
結果のterraform.tfstate例:
{
"resources": []
}
エフェメラル値を使用することで、例えばRDSデータベースの認証情報を安全に管理できます。以下はその一例です。
エフェメラル値を使ったRDS MySQLデータベースのプロビジョニング
locals {
mysql_credentials = jsondecode(ephemeral.aws_secretsmanager_secret_version.test_secret.secret_string)
}
resource "aws_db_instance" "default" {
allocated_storage = 10
db_name = "mydb"
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3.micro"
username = local.mysql_credentials["username"]
password = local.mysql_credentials["password"]
vpc_security_group_ids = [aws_security_group.mysql_sg.id]
skip_final_snapshot = true
parameter_group_name = "default.mysql8.0"
}
結論
エフェメラル値により、シークレットがTerraformのアーティファクトに保存されるリスクがなく、インフラ運用もより安全でシンプルになります。これからのシークレット管理は、エフェメラル値の活用が標準となり、セキュリティの強化と運用効率も向上するでしょう。
参考資料:
Discussion