Terraformコードのlocals.tfにARN(Amazon Resource Name)を直接、暗号化せずに記述することは、一般的には適切ではありません。
特に、そのARNが機密情報(データベースのARN、機密性の高いS3バケットのARNなど)を含んでいる場合や、本番環境で使用されるリソースを指している場合は、より注意が必要です。
なぜ適切ではないのか?
-
セキュリティリスク:
-
機密情報の露出: ARN自体が機密情報でなくても、そのARNが指すリソースが機密情報を含んでいる可能性があります。例えば、
arn:aws:s3:::my-secret-data-bucketのようなARNは、バケット名から内容が推測できる場合があり、悪意のある攻撃者にターゲットを絞られる可能性があります。 - アクセス制御の迂回: ARNを直接ハードコードすると、リソースへのアクセスを制御するポリシーの変更が困難になったり、意図せずアクセスを許可してしまうリスクがあります。
-
Gitリポジトリへのコミット:
locals.tfは通常、Gitなどのバージョン管理システムにコミットされます。これにより、ARNがリポジトリ履歴に残り、権限を持つ人が誰でも閲覧できるようになります。
-
機密情報の露出: ARN自体が機密情報でなくても、そのARNが指すリソースが機密情報を含んでいる可能性があります。例えば、
-
可搬性と再利用性の低下:
-
環境依存: 開発、ステージング、本番など、複数の環境で同じTerraformコードを使用する場合、環境ごとにARNが異なる可能性があります。
locals.tfに直接記述すると、環境ごとにファイルを変更する必要があり、コードの可搬性が低下します。 - リージョン依存: 異なるAWSリージョンでデプロイする場合も、ARNはリージョン固有の値を持つため、同様の問題が発生します。
-
環境依存: 開発、ステージング、本番など、複数の環境で同じTerraformコードを使用する場合、環境ごとにARNが異なる可能性があります。
-
管理の複雑化:
- リソースのARNが変わるたびに
locals.tfを更新する必要があり、手動での管理ミスが発生しやすくなります。
- リソースのARNが変わるたびに
代替案と適切なプラクティス
ARNを安全かつ柔軟に扱うためには、以下の方法が推奨されます。
-
Terraform Data Sources (データソース) を使用する:
ARNが既存のAWSリソースのものである場合、aws_s3_bucket、aws_iam_role、aws_vpcなどのTerraformデータソースを使用して、ARNを動的に取得するのが最も推奨される方法です。これにより、コードの再利用性が高まり、ARNの変更にも自動的に対応できます。# 例: 既存のS3バケットのARNを取得 data "aws_s3_bucket" "my_existing_bucket" { bucket = "my-existing-s3-bucket-name" } locals { # データソースからARNを参照 s3_bucket_arn = data.aws_s3_bucket.my_existing_bucket.arn } -
Terraform Output を参照する:
Terraformによって作成される他のモジュールやルートモジュールのリソースのARNを参照する場合、そのリソースを作成する側のモジュールでARNをoutputとして定義し、それを受け取る側でmodule参照やterraform_remote_stateデータソースを介して参照します。# resource_creator/outputs.tf output "created_resource_arn" { value = aws_resource.my_resource.arn description = "ARN of the created resource." } # consumer/main.tf module "resource_creator" { source = "../resource_creator" # ... } locals { resource_arn_from_module = module.resource_creator.created_resource_arn } -
Terraform Variables (変数) を使用する:
もしARNが外部から提供されるべき値であり、Terraformが動的に取得できない場合(例: 他のシステムから提供される特定のSaaSのARNなど)、変数として定義し、Terraformの実行時に渡すことができます。-
terraform.tfvarsファイルに記述(Gitから除外する.gitignoreに追記) - 環境変数 (
TF_VAR_my_arn) - コマンドライン引数 (
-var "my_arn=...") - CI/CDパイプラインのシークレット管理システムから注入
# variables.tf variable "my_sensitive_arn" { description = "The ARN of a sensitive resource." type = string sensitive = true # sensitiveフラグを付けると、terraform outputやplanで表示されにくくなります } # locals.tf (または他の場所) locals { my_arn = var.my_sensitive_arn }注意:
sensitive = trueは、コンソールへの出力などを抑制しますが、状態ファイルには平文で保存されます。 -
-
AWS Systems Manager Parameter Store や AWS Secrets Manager を使用する:
最もセキュアな方法の一つです。ARNをこれらのサービスに安全に保存し、Terraformのデータソースでそれらを参照して取得します。これにより、ARNはTerraformコードやGitリポジトリに直接現れることなく、AWSのセキュリティ機能によって保護されます。# 例: Parameter StoreからARNを取得 data "aws_ssm_parameter" "my_secret_arn" { name = "/my_app/prod/sensitive_arn" with_decryption = true # 暗号化されている場合 } locals { retrieved_arn = data.aws_ssm_parameter.my_secret_arn.value }
まとめ
ARNをlocals.tfに暗号化せずに直接記述することは、特に本番環境や機密性の高いリソースの場合、セキュリティリスクと管理の複雑さを増大させます。
推奨されるプラクティスは、Terraformのデータソースを活用してARNを動的に取得するか、variableを通じて安全に注入するか、あるいはAWSのシークレット管理サービスを利用することです。 これにより、コードの安全性、可搬性、およびメンテナンス性が向上します。