TerraformでVPC Service Controlsを管理する際、モジュール間でのAccess Level連携でエラーに遭遇することがよくあります。本記事では、実際の開発で遭遇した「Reference to undeclared input variable」エラーの原因と解決方法を詳しく解説します。
発生したエラー
VPC-SC設定を他環境に合わせて修正した際、以下のエラーが発生しました:
1
2
3
4
5
6
| │ Error: Reference to undeclared input variable
│
│ on ../../us_modules/service_perimeter/locals.tf line 6, in locals:
│ 6: var.access_level_service_accounts["analysis_project"].id,
│
│ An input variable with the name "access_level_service_accounts" has not been declared.
|
エラーの原因分析
このエラーの根本原因は、モジュール間の変数連携が不完全だったことです。
正常に動作している環境Aの構成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # env_a_modules/access_level/outputs.tf
output "access_level_service_accounts" {
value = google_access_context_manager_access_level.service_accounts
}
# env_a_modules/service_perimeter/variables.tf
variable "access_level_service_accounts" {}
# jp_main.tf
module "service_perimeter" {
source = "../../jp_modules/service_perimeter"
access_level_service_accounts = module.access_level.access_level_service_accounts
# 他の変数...
}
|
問題があったUS環境の構成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # env_b_modules/access_level/outputs.tf (不足していた)
output "access_level_office_and_vpn_ips" {
value = google_access_context_manager_access_level.office_and_vpn_ips_us
}
# access_level_service_accountsのoutputが無い!
# env_b_modules/service_perimeter/variables.tf (不足していた)
variable "access_level_office_and_vpn_ips" {}
# access_level_service_accountsの変数宣言が無い!
# us_main.tf (不足していた)
module "service_perimeter" {
source = "../../us_modules/service_perimeter"
access_level_office_and_vpn_ips = module.access_level.access_level_office_and_vpn_ips
# access_level_service_accountsの受け渡しが無い!
}
|
解決手順
ステップ1: access_levelモジュールにOutputを追加
1
2
3
4
5
6
7
8
| # env_b_modules/access_level/outputs.tf
output "access_level_office_and_vpn_ips" {
value = google_access_context_manager_access_level.office_and_vpn_ips_us
}
+ output "access_level_service_accounts" {
+ value = google_access_context_manager_access_level.service_accounts
+ }
|
ステップ2: service_perimeterモジュールに変数を追加
1
2
3
4
5
6
7
8
9
| # env_b_modules/service_perimeter/variables.tf
variable "env" {}
variable "env_type" {}
variable "region" {}
variable "google_projects" {}
variable "scoped_policy" {}
variable "supported_services" {}
variable "access_level_office_and_vpn_ips" {}
+ variable "access_level_service_accounts" {}
|
ステップ3: メインファイルで変数を受け渡し
1
2
3
4
5
6
7
8
9
10
11
12
| # us_main.tf
module "service_perimeter" {
source = "../../us_modules/service_perimeter"
env = var.env
env_type = var.env_type
region = var.region
google_projects = data.google_project._
scoped_policy = data.google_access_context_manager_access_policy._[var.env].name
access_level_office_and_vpn_ips = module.access_level.access_level_office_and_vpn_ips
+ access_level_service_accounts = module.access_level.access_level_service_accounts
supported_services = var.supported_services
}
|
1. 段階的なモジュール設計
1
2
3
| access_level → service_perimeter → ingress_policy
↓ ↓ ↓
outputs variables variables
|
2. 変数命名の一貫性
- Output名とVariable名を一致させる
- モジュール間で統一した命名規則を使用
1
2
3
4
5
6
7
| # Good: 一貫した命名
output "access_level_service_accounts" { ... }
variable "access_level_service_accounts" { ... }
# Bad: 不一致な命名
output "service_account_access_levels" { ... }
variable "access_level_service_accounts" { ... }
|
3. 段階的な実装とテスト
1
2
3
4
5
6
7
| # 各ステップでvalidationを実行
terraform validate
terraform plan
# モジュールごとの変更を確認
terraform plan -target=module.access_level
terraform plan -target=module.service_perimeter
|
デバッグのコツ
エラーメッセージの読み方
1
2
3
| Error: Reference to undeclared input variable
│ on ../../us_modules/service_perimeter/locals.tf line 6
│ variable "access_level_service_accounts" has not been declared
|
この場合のチェック順序:
- variables.tf: 該当変数が宣言されているか
- メインファイル: モジュール呼び出し時に変数を渡しているか
- outputs.tf: 参照元モジュールでoutputが定義されているか
1
| terraform graph | dot -Tsvg > graph.svg
|
モジュール間の依存関係を視覚的に確認できます。
まとめ
Terraformモジュール間でのAccess Level連携では、以下の3つの要素が正しく設定されている必要があります:
- Output: 提供側モジュールでの値の公開
- Variable: 受け取り側モジュールでの変数宣言
- パススルー: メインファイルでのモジュール間連携
一つでも欠けると「Reference to undeclared input variable」エラーが発生します。エラーが発生した場合は、この3要素を順番に確認することで、効率的に問題を特定・解決できます。
複雑なインフラをTerraformで管理する際は、モジュール設計の初期段階でこれらの連携パターンを統一しておくことが、長期的な保守性向上の鍵となります。