- OpenTofuの内部
- リソースグラフ
リソースグラフ
OpenTofuは、OpenTofuの設定から依存関係グラフを構築し、このグラフをたどってプランの生成、状態の更新などを行います。このページでは、このグラフに含まれるものの詳細、ノードの種類、グラフのエッジがどのように決定されるかについて説明します。
このページでは、OpenTofuの技術的な詳細について説明します。OpenTofuを効果的に使用するために、これらの詳細を理解する必要はありません。これらの詳細は、ソースコードを掘り下げなくてもOpenTofuについて学びたい方のためにここに記述されています。
グラフ理論の背景と、OpenTofuがそれをどのように適用しているかの概要については、HashiCorpの2016年のプレゼンテーション Applying Graph Theory to Infrastructure as Code を参照してください。このプレゼンテーションでは、以下のガイドと同様のアイデアもいくつか取り上げています。
グラフノード
グラフ内に存在できるノードのタイプはわずかしかありません。それらがどのように決定され、構築されるかを説明する前に、まずそれらについて説明します。
-
リソースノード - 単一のリソースを表します。
count
メタパラメータを設定した場合、カウントごとにリソースノードが1つ存在します。変更中のリソースの設定、差分、状態などがこのノードにアタッチされます。 -
プロバイダー設定ノード - プロバイダーを完全に設定するタイミングを表します。これは、AWSのセキュリティ認証情報などのプロバイダー構成ブロックがプロバイダーに渡されるときです。
-
リソースメタノード - リソースのグループを表しますが、それ自体ではアクションを表しません。これは、依存関係を扱う際や、グラフをより見やすくするために行われます。このノードは、
count
パラメータが1より大きいリソースに対してのみ存在します。
tofu graph
で構成を視覚化すると、これらのノードがすべて存在することがわかります。
グラフの構築
グラフの構築は、一連の順次的なステップで行われます。
-
リソースノードは、構成に基づいて追加されます。差分(プラン)または状態が存在する場合、そのメタデータは各リソースノードにアタッチされます。
-
リソースは、定義されている場合はプロビジョナーにマッピングされます。これは、すべてのリソースノードが作成された後に行う必要があります。これにより、同じプロビジョナータイプを持つリソースがプロビジョナーの実装を共有できるようになります。
-
depends_on
メタパラメータからの明示的な依存関係は、リソース間にエッジを作成するために使用されます。 -
状態が存在する場合、すべての「孤立した」リソースがグラフに追加されます。孤立したリソースとは、構成には存在しなくなったが、状態ファイルには存在するリソースのことです。孤立したリソースには、状態ファイルに構成が保存されないため、構成が関連付けられることはありません。
-
リソースはプロバイダーにマッピングされます。プロバイダー構成ノードはこれらのプロバイダーに対して作成され、リソースがそれぞれのプロバイダーの設定に依存するようにエッジが作成されます。
-
リソースとプロバイダーの構成でインターポレーションが解析され、依存関係が決定されます。リソース属性への参照は、インターポレーションを持つリソースから参照されているリソースへの依存関係に変換されます。
-
ルートノードを作成します。ルートノードはすべてのリソースを指しており、依存関係グラフに単一のルートを持たせるために作成されます。グラフを走査するとき、ルートノードは無視されます。
-
差分が存在する場合、すべてのリソースノードを走査し、破棄されるリソースを検索します。これらのリソースノードは2つに分割されます。1つはリソースを破棄するノード、もう1つはリソースを作成するノード(再作成される場合)。ノードを分割する必要がある理由は、破棄順序が作成順序と異なることが多く、単一のグラフノードで表現できないためです。
-
グラフに循環がなく、単一のルートがあることを検証します。
グラフの走査
グラフを走査するには、標準の深さ優先探索が行われます。グラフの走査は並行して行われます。ノードはその依存関係がすべて走査されるとすぐに走査されます。
並列処理の量は、OpenTofuを実行しているマシンのリソースが過負荷にならないように、セマフォを使用して制限されます。デフォルトでは、グラフ内の最大10個のノードが同時に処理されます。この数は、plan、apply、およびdestroyコマンドで-parallelism
フラグを使用して設定できます。
-parallelism
を設定することは高度な操作と見なされ、OpenTofuの通常の使用には必要ありません。特定の特別なユースケースや、OpenTofuの問題をデバッグするのに役立つ場合があります。
一部のプロバイダー(たとえばAWS)は、それぞれのAPIクライアントにグレースフルバックオフ/リトライを実装することにより、より低いレベルでAPIレート制限の問題を処理することに注意してください。このため、OpenTofuはこのparallelism
機能を使用してAPIレート制限に直接対処することはありません。