メインコンテンツにスキップ

属性をブロックとして

概要

多くのリソースタイプは、反復可能なネストされたブロックを使用して、プライマリリソースに関連するサブオブジェクトのコレクションを管理します。

まれに、一部のリソースタイプは、ネストされたブロックタイプと同じ名前の引数もサポートしており、その引数が空のリスト(<ATTR> = [])に設定されている場合、そのタイプのサブオブジェクトをすべて削除します。

ほとんどのユーザーは、この「ネストされたブロックまたは空のリスト」の動作について、これ以上の詳細を知る必要はありません。ただし、必要な場合は以下を読んでください。

  • このタイプのリソースでOpenTofuのJSON構文を使用する。
  • このタイプのリソースをラップする再利用可能なモジュールを作成する。

詳細

言語は、ブロック内で引数構文とネストされたブロック構文を区別します。

  • 引数構文は、包含オブジェクトの名前付き引数を設定します。属性にデフォルト値がある場合、明示的に指定された値は、そのデフォルト値を完全にオーバーライドします。

  • ネストされたブロック構文は、独自の引数セットを持つコンテナの関連する子オブジェクトを表します。このようなオブジェクトが複数可能な場合、同じタイプの複数のブロックが存在する可能性があります。ネストされた属性自体にデフォルト値がある場合、それらはネストされた各ブロックで個別に尊重され、明示的に定義された引数とマージされます。

これらの区別は、JSON構文では特に重要です。これは、特定の名前が引数かネストされたブロックタイプかによって、同じプリミティブなJSON構造(リストとオブジェクト)が異なる方法で解釈されるためです。

固定オブジェクトコレクション値の定義

このように動作するリソースタイプの引数を操作する場合、固定オブジェクトコレクションを定義するときは常にネストされたブロック構文を使用することをお勧めします。

コードブロック
example {
foo = "bar"
}
example {
foo = "baz"
}

上記は、example引数に割り当てられた2要素のオブジェクトリストを暗黙的に指定し、ネストされたブロックタイプであるかのように扱います。

ゼロ個のexampleオブジェクトを明示的に呼び出す必要がある場合は、空のリストを含む引数構文を使用する必要があります。

コードブロック
example = []

これらの2つの形式を混在させることはできません。明示的にゼロ個のexampleオブジェクトと明示的な単一のexampleブロックを同時に宣言することはできません。

この特別な動作が適用されない真のネストされたブロックの場合、引数構文を使用して[]を割り当てることは有効ではありません。タイプのゼロオブジェクトを指定する通常の方法は、ネストされたブロックをまったく記述しないことです。

引数構文を使用した任意の式

可読性のために単純なケースではブロック構文を使用することをお勧めしますが、このモードで機能する名前は引数として定義されているため、式が予期される結果型を持っている限り、引数構文を使用して任意の動的式を割り当てることができます。

コードブロック
example = [
for name in var.names: {
foo = name
}
]
コードブロック
# Not recommended, but valid: a constant list-of-objects expression
example = [
{
foo = "bar"
},
{
foo = "baz"
},
]

このような引数宣言はデフォルト値を完全にオーバーライドするというルールがあるため、オブジェクトのリスト式を直接作成する場合、オプションの引数の通常の処理は適用されないため、明示的なnullであっても、すべての引数に値を割り当てる必要があります。

コードブロック
example = [
{
# Cannot omit foo in this case, even though it would be optional in the
# nested block syntax.
foo = null
},
]

このような引数に割り当てるオブジェクトのリストを呼び出し元が渡せるような再利用可能なモジュールを作成している場合は、ユーザーが明示的に設定しなかった属性を入力するためにmerge関数を使用すると、モジュールユーザーにオプションの引数の効果を与えることができます。

コードブロック
example = [
for ex in var.examples: merge({
foo = null # (or any other suitable default value)
}, ex)
]

属性をブロックとして使用するモードを使用する引数の場合、上記のほうがdynamicブロックを使用するよりも優れたパターンです。これは、呼び出し元が空のリストを提供した場合、値をまったく割り当てずに既存のオブジェクトを保持および無視するのではなく、空のリスト値を明示的に割り当てることになるためです。ただし、dynamicブロックは、通常のネストされたブロックを動的に生成するために必要です。

JSON構文の場合

この特別なモードを使用する引数は、常にJSON式マッピングを使用して、JSON構文でオブジェクトのリストを生成するように指定されます。

したがって、JSON構文でのこれらの値の解釈は、上記の引数構文を使用した任意の式で説明した内容と同等ですが、JSON構文で表現されています。

JSON構文のあいまいさのため、入力だけに基づいて引数とネストされたブロックの使用法を区別する方法がないため、JSON構文はこれらの引数に対するネストされたブロック処理モードをサポートできません。これは残念ながら、既存のプロバイダーのデザインパターンとの互換性を実現するために実用的に行われた、ネイティブ構文とJSON構文の同等性に関する1つの必要な譲歩です。プロバイダーは、将来のメジャーリリースでこのようなパターンを段階的に廃止する可能性があります。