- OpenTofu言語
- 状態
- OpenTofuの状態の目的
OpenTofuの状態の目的
状態は、OpenTofuが機能するために必要な要件です。OpenTofuが状態なしで動作するかどうか、または状態を使用せずに毎回現実世界の資源を検査するかどうかは、よくある質問です。このページでは、OpenTofuの状態が必要な理由を説明します。
下記の理由からわかるように、状態は必須です。OpenTofuが状態なしで済むシナリオでも、そうしようとすると、複雑性の大きな部分をある場所(状態)から別の場所(代替概念)に移す必要があります。
現実世界へのマッピング
OpenTofuは、OpenTofuの設定を現実世界にマッピングするためのデータベースの一種を必要とします。たとえば、設定にresource "aws_instance" "foo"
というリソースがある場合、OpenTofuはこのマッピングを使用して、resource "aws_instance" "foo"
というリソースが、リモートシステム上のインスタンスIDi-abcd1234
を持つ現実世界のオブジェクトを表していることを認識します。
AWSなどのプロバイダの中には、OpenTofuがAWSタグのようなものを使用できるものもあります。OpenTofuの初期のプロトタイプは実際には状態ファイルがなく、この方法を使用していました。しかし、すぐに問題に遭遇しました。最初の大きな問題は単純なものでした。すべてのリソースがタグをサポートしているわけではなく、すべてのクラウドプロバイダがタグをサポートしているわけではありません。
したがって、設定と現実世界の資源のマッピングのために、OpenTofuは独自のステート構造を使用します。
OpenTofuは、各リモートオブジェクトが設定内の1つのリソースインスタンスのみにバインドされていることを想定しています。リモートオブジェクトが複数のリソースインスタンスにバインドされている場合、設定からリモートオブジェクトへの状態のマッピングが曖昧になり、OpenTofuが予期せず動作する可能性があります。OpenTofuは、オブジェクトを作成し、その識別子を状態に記録することで、一対一の対応を保証できます。OpenTofu以外で作成されたオブジェクトをインポートする場合は、各個別のオブジェクトが1つのリソースインスタンスのみにインポートされていることを確認する必要があります。
メタデータ
リソースとリモートオブジェクト間のマッピングに加えて、OpenTofuはリソースの依存関係などのメタデータも追跡する必要があります。
OpenTofuは通常、設定を使用して依存関係の順序を決定します。ただし、OpenTofuの設定からリソースを削除すると、OpenTofuはリモートシステムからそのリソースを削除する方法を知る必要があります。OpenTofuは、設定に存在しないリソースの状態ファイルにマッピングが存在し、削除を計画していることを認識できます。ただし、設定が存在しなくなったため、設定だけでは順序を決定できません。
正しい動作を確保するために、OpenTofuは最新の依存関係セットのコピーを状態内に保持します。これで、設定から1つ以上の項目を削除した場合でも、OpenTofuは状態から削除の正しい順序を決定できます。
これを回避する1つの方法は、OpenTofuがリソースタイプ間の必要な順序を認識することです。たとえば、OpenTofuは、サーバーはそれが属するサブネットの前に削除する必要があることを認識できます。ただし、このアプローチの複雑さは急速に増加します。OpenTofuがすべてのプロバイダのすべてのリソースの順序付けのセマンティクスを理解する必要があることに加えて、OpenTofuはプロバイダ間の順序付けも理解する必要があります。
OpenTofuは、複数のエイリアスの付いたプロバイダが存在する場合に、リソースで最後に使用されたプロバイダ設定へのポインタなど、同様の理由でその他のメタデータも保存します。
パフォーマンス
基本的なマッピングに加えて、OpenTofuは状態内のすべてのリソースの属性値のキャッシュを保存します。これはOpenTofuの状態の最もオプション的な機能であり、パフォーマンス向上のためだけに実行されます。
tofu plan
を実行する場合、OpenTofuは目的の設定に到達するために必要な変更を効果的に判断するために、リソースの現在の状態を知る必要があります。
小規模なインフラストラクチャの場合、OpenTofuはプロバイダをクエリし、すべてのリソースから最新の属性を同期できます。これはOpenTofuのデフォルトの動作です。すべての計画と適用に対して、OpenTofuは状態内のすべてのリソースを同期します。
大規模なインフラストラクチャの場合、すべてのリソースをクエリするには時間がかかりすぎます。多くのクラウドプロバイダは、一度に複数のリソースをクエリするAPIを提供しておらず、各リソースのラウンドトリップ時間は数百ミリ秒です。さらに、クラウドプロバイダはほぼ常にAPIレート制限があるため、OpenTofuは一定期間に特定数のリソースのみを要求できます。OpenTofuの大規模ユーザーは、これに対処するために-refresh=false
フラグと-target
フラグを多用しています。このようなシナリオでは、キャッシュされた状態が真実の記録として扱われます。
同期
デフォルトの設定では、OpenTofuは状態をOpenTofuが実行された現在の作業ディレクトリにファイルとして保存します。これは開始するには問題ありませんが、チームでOpenTofuを使用する場合は、すべての人が同じ状態を使用して作業することが重要です。そうすることで、操作が同じリモートオブジェクトに適用されます。
リモート状態はこの問題に対する推奨される解決策です。フル機能の状態バックエンドを使用すると、OpenTofuはリモートロックを使用して、2人以上の異なるユーザーが同時にOpenTofuを実行しないようにし、各OpenTofuの実行が最新の更新された状態から開始されるようにすることができます。