📗
【Terraform】Error: Unsupported attributeの解消(outputブロックの理解を深める)
Unsupported attribute
terraform plan
実行時に、Unsupported attribute
というエラーが発生しました。
$ terraform plan
╷
│ Error: Unsupported attribute
│
│ on outputs.tf line 2, in output "storage_account_name":
│ 2: value = module.storage_account.storage_account_name
│ ├────────────────
│ │ module.storage_account is a object
│
│ This object does not have an attribute named "storage_account_name".
╵
╷
│ Error: Unsupported attribute
│
│ on outputs.tf line 6, in output "container_name":
│ 6: value = module.storage_account.container_name
│ ├────────────────
│ │ module.storage_account is a object
│
│ This object does not have an attribute named "container_name".
module.storage_account
というオブジェクトがstorage_account_name
とcontainer_name
という属性を持っていないよというエラーです。
ディレクトリ構成とファイル内容
terraform-sample
|--modules
|--storage_account
|-- main.tf
|-- variables.tf
|--envs
|--development
|-- main.tf
|-- outputs.tf
|-- provider.tf
|-- backend.tf
|-- terraform.tfvars
|-- variables.tf
modules/storage_account/main.tf
# モジュール:AzureストレージアカウントとBlobコンテナを定義
resource "azurerm_storage_account" "sample_storage_account" {
name = var.storage_account_name
resource_group_name = var.resource_group_name
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_container" "sample_blob_container" {
name = var.container_name
storage_account_name = azurerm_storage_account.sample_storage_account.name
container_access_type = "private"
}
# モジュールを使いAzureストレージアカウントを宣言
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.location
}
module "storage_account" {
source = "../../modules/storage_account"
storage_account_name = var.storage_account_name
resource_group_name = azurerm_resource_group.rg.name
location = var.location
container_name = var.container_name
}
envs/development/outputs.tf
# メインディレクトリ側のoutput定義
output "storage_account_name" {
value = module.storage_account.storage_account_name
}
output "container_name" {
value = module.storage_account.container_name
}
結論: outputブロックについて
結論としては、以下のように、module側でもoutput
を定義する必要があります。
modules/storage_account/outputs.tf
output "storage_account_name" {
value = azurerm_storage_account.sample_storage_account.name
}
output "container_name" {
value = azurerm_storage_container.sample_blob_container.name
}
モジュール内でoutputを定義するのは、モジュール内部のリソースや変数を外部(メイン構成ファイル)に公開するためです。モジュールは、内部の詳細が外部から見えないようにカプセル化されています。そのため、モジュール内で定義した情報(ここではストレージアカウント名やBlobコンテナ名)をメイン側のoutputで利用する場合、モジュール側でoutputを定義し、公開しておく必要があります。
一方、メイン構成ファイル側でoutputを定義する理由は、terraform apply
実行時にコマンドラインに値を出力したり、その値を他のリソースや外部システムで利用するためです。
この辺りは、Output Valuesドキュメントに記載の通りでした。
Output values have several uses:
・A child module can use outputs to expose a subset of its resource attributes to a parent module.
・A root module can use outputs to print certain values in the CLI output after running terraform apply.
以上です。
Discussion