メインコンテンツへスキップ
  1. Blogs/

HCP Terraform Workspace 設計のベストプラクティス

· loading · loading · ·
Terraform HCP Terraform
Nimbus Craftsman
著者
Nimbus Craftsman
目次

はじめに 👋
#

こんにちは、ニンバスです!最近、コミュニティ版 Terraform から HCP Terraform への移行を支援するプロジェクトにいくつか携わることがありました。私はそれらのプロジェクトを通して、HCP Terraform の Workspace をうまく管理できているプロジェクトと、そうで無いプロジェクトには明確な違いがあるなと感じました。それが Workspace の設計方法です。

実は HCP Terraform には Workspace 設計のベストプラクティスがあることをご存知ですか?今回は「HCP Terraform Workspace のベストプラクティス」について触れていきたいと思います。この記事を読んで、Workspace 設計のポイントを押さえてもらえたら嬉しいです。それでは、Let’s Dive in! 🦄

Workspace の設計で失敗しがちなパターン 😅
#

まずは、よくある失敗パターンから見ていきましょう。私が実際に現場で見かけることが多いのは、以下のような構成です。

❌ 失敗パターン
#

Organization: ${organization-name}
└── Project: ${system-name}
    ├── ${system-name}-dev
    ├── ${system-name}-stage
    └── ${system-name}-prod

一見シンプルで分かりやすそうに見えます。しかし、実際は管理対象リソースが多すぎて管理しづらいケースもあります。

HCP Terraform の各 Workspace は単一の状態ファイルを管理し、状態ファイルはその Workspace が管理するリソースの集合体になります。Workspace 上で管理するインフラリソースが多いほど管理は複雑になります。

例えば、ただ単純に一つのリソースを変更したいだけなのに、Apply時には他のリソースにまで影響を与えてしまうケースもあります。必要最小限の変更を加えるためには、こういうケースはなるべく避けるべきです。

また、ある組織ではインフラチームが完全に Terraform を管理する(開発・運用保守する)こともあれば、ある組織では、セキュリティチーム、ネットワークチーム、アプリケーションチームとチームごとに Terraform を管理することもあります。

上記の構成だと、「責任の境界線」がないので、複数チームで Terraform を管理する場合には少しやりづらさがあると思います。

例えば:

  • ネットワークチームがVPCの設定を変更したいが、アプリケーションリソースも同じ Workspace にある
  • アプリケーションチームがECSのタスク数を調整したいが、データベース設定も含まれるため慎重になる必要がある
  • セキュリティチームがIAMポリシーを更新したいが、他チームの変更と競合する可能性がある

Workspace の設計で成功しているパターン 😎
#

⭕️ 成功パターン
#

次は、成功パターンから見ていきましょう。私が実際に現場で見て成功しているように思えたのは、以下のような構成です。 (後述している「HashiCorp 公式のベストプラクティス」に限りなく近い構成になっていると思います。)

Organization: ${organization-name}
└── Project: ${system-name}-dev-pj
|   ├── Workspace: ${system-name}-network-dev
|   ├── Workspace: ${system-name}-security-dev
|   ├── Workspace: ${system-name}-database-dev
|   └── Workspace: ${system-name}-app-dev
└── Project: ${system-name}-stg-pj
|   ├── Workspace: ${system-name}-network-stg
|   ├── Workspace: ${system-name}-security-stg
|   ├── Workspace: ${system-name}-database-stg
|   └── Workspace: ${system-name}-app-stg
└── Project: ${system-name}-prod-pj
    ├── Workspace: ${system-name}-network-prod
    ├── Workspace: ${system-name}-security-prod
    ├── Workspace: ${system-name}-database-prod
    └── Workspace: ${system-name}-app-prod

Workspace 名から見てわかるように「責任の境界線」が明確になっています。これにより「どのチームが、どの Workspace を管理するか」を決めやすくなり、Terraform コードおよび Workspace の管理も容易になります。

HashiCorp 公式のベストプラクティス 🎯
#

HashiCorp公式ドキュメントでは、以下の原則に基づいた Workspace 設計を推奨しています。これらの原則を実践することで、より安全で効率的な HCP Terraform 運用が実現できます。(以下、公式ドキュメントを参考に筆者が翻訳・編集)

1. 小さな影響範囲を保つ
#

HCP Terraform Workspace は、単一のステートファイルとそのリソースのライフサイクルを管理します。これは、HCP Terraform で管理されるインフラストラクチャの最小単位です。リソースに対する操作は、同じステートファイルで管理される他のリソースに影響を与える可能性があります。そのため、操作の影響範囲をできるだけ小さく保つことが望ましいです。これを行うには、可能な限りリソースを別々の Workspace で管理し、必要かつ論理的に関連するリソースのみをグループ化してください。例えば、アプリケーションがコンピューティングリソースとデータベースの両方を必要とする場合でも、これらのリソースは独立して動作するため、それぞれ独自の Workspace に配置すべきです。HCP TerraformとTerraform Enterpriseの採用初期段階で、構成の範囲を明確化し、 Workspace 戦略を計画することで、運用を簡素化し、安全性を高めることができます。

2. 公式推奨の命名規則
#

以下の命名規則を使用することをおすすめします。これにより、 Workspace をインフラストラクチャの特定のコンポーネントと関連付けて識別できます:

${ビジネスユニット}-${アプリ名}-${レイヤー}-${環境}
  • ビジネスユニット: Workspace を管理するビジネスユニットまたはチーム。
  • アプリ名: Workspace が管理するアプリケーションまたはサービスの名前。
  • レイヤー名: Workspace が管理するインフラストラクチャのレイヤー(例: ネットワーク、コンピューティング、ファイルストレージ)。
  • 環境名: Workspace が管理する環境(例: プロダクション、ステージング、QA、開発)。アプリケーションチームにレイヤーがない場合は、組織全体での一貫性を保つために、その代わりに「main」または「app」を使用してください。

例:

platform-webapp-network-prod
platform-webapp-compute-prod
platform-webapp-filestore-prod
platform-api-network-dev
platform-api-compute-dev
platform-api-database-dev

3. Volatility(変更頻度)によるグルーピング
#

Volatility とは、 Workspace 内のリソースの変化率を指します。データベース、VPC、サブネットなどのインフラストラクチャは、Web サーバーなどのインフラストラクチャに比べてはるかに頻繁に変化しません。長期にわたって存在するインフラストラクチャを不要な Volatility にさらすことで、意図しない変更のリスクが増加します。 Workspace の組織化を計画する際は、リソースを Volatility に基づいてグループ化してください。

Volatility(変更頻度)によるグルーピング

例:

platform-webapp-network-prod    # 低頻度変更
platform-webapp-security-prod   # 低頻度変更
platform-webapp-compute-prod    # 高頻度変更  
platform-webapp-filestore-prod  # 低頻度変更

変更頻度の例:

  • 高頻度: コンピュートインスタンス(1日に数回スケール)
  • 低頻度: データベースインスタンス(数ヶ月に1回程度)

4. Stateful / Stateless の分離
#

ステートフルリソースは、データベースやオブジェクトストレージなど、データを永続的に保持するため削除して再作成できないリソースです。ステートフルリソースをステートレスリソースから独立して管理することで(例えばデータベースをコンピューティングインスタンスから分離するなど)、リソースの再作成を引き起こす操作の影響範囲を限定し、誤ったデータ損失から保護するのに役立ちます。 Volatility セクションの Workspace 構造を検討してください。ファイルストアとデータベースリソースはどちらもステートフルリソースであるため、これらを一緒に管理する可能性があります。一方、コンピューティングリソースはステートレスであるため、依然として別々の Workspace に配置する必要があります。

# ✅ 良い例:Stateful と Stateless を分離
platform-webapp-network-prod    # Stateful
platform-webapp-filestore-prod  # Stateful  
platform-webapp-compute-prod    # Stateless

# ❌ 悪い例:混在させる
platform-webapp-all-prod        # Stateful + Stateless が混在

5. 「権限」と「責任」による分離
#

ベストプラクティスとして、チーム責任と必要な権限に基づいて Workspace を分割することが推奨されます。例えば、開発環境と本番環境を分離する必要があるアプリケーションの場合、それぞれに特別なネットワークとアプリケーションインフラストラクチャが要求されます。一つのアプローチとして、開発環境用に2つ、本番環境用に2つの合計4つの異なる Workspace を作成します。ネットワークチームのみがネットワーク Workspace へのアクセス権限を有します。

「権限」と「責任」による分離

この構成では、ネットワークチームのみがネットワーク Workspace 内のリソースを管理するための権限を必要とし、他のユーザーはそれらの Workspace リソースを管理できません。 Workspace の範囲が広すぎる場合、ユーザーは Workspace 内の操作を行うために適切な範囲を超える権限を必要とする可能性があります。 チームごとに Workspace を分割することで、各 Workspace の責任範囲を限定し、チームが独自の管理領域を維持できるようになります。他の Workspace で管理されているリソースの属性を参照する必要がある場合、tfe_outputs データソースを使用して出力を共有できます。各 Workspace の範囲を限定し、必要な出力のみを他者と共有することで、 Workspace の状態から機密情報が漏洩するリスクを軽減できます。 Workspace の出力を共有するには、 Workspace の設定でリモート状態共有を明示的に有効にする必要があります。

6. 大きな Terraform Plan/Apply を避ける
#

HCP Terraform および Terraform Enterprise は、エージェントを使用してワークロードを実行します。エージェントが Workspace の状態をリフレッシュするたびに、リソースの依存関係グラフを構築し、 Workspace 内の操作の順序を決定します。 Workspace が管理するリソースの数が増加するにつれ、これらのグラフはより大規模で複雑になります。グラフが拡大するにつれ、それらを構築するために必要なワーカーRAMも増加します。エージェントのパフォーマンスが低下したり、ワークロードの完了に時間がかかったりする場合は、 Workspace を分割して依存関係グラフのサイズを縮小する方法を検討することをおすすめします。

7. Workspace の並行処理と Terraform の並列処理を比較する
#

並行処理とは、HCP TerraformまたはTerraform Enterpriseが同時に実行できるプランと適用操作の数を指します。 HCP Terraformでは、エディションによって組織の最大並行処理数が制限されます。詳細については、HCP Terraformの料金プランをご確認ください。

Terraform Enterpriseでは並行実行数を設定できますが、デフォルトでは10並行実行が設定されています。並行実行数を増やすと、Terraform Enterpriseのインストールに必要なメモリ量も増加します。詳細については、容量とパフォーマンスのドキュメントを参照してください。

並列処理とは、Terraform CLIが単一のワークロード内で同時に実行するタスクの数です。デフォルトでは、Terraformは最大10の操作を並列実行します。terraform apply コマンドを実行する際、Terraform は状態ファイル内の各リソースをリフレッシュし、リモートオブジェクトと比較します。各リソースのリフレッシュ、作成、更新、または削除は個別の操作です。ワークロードが11つのリソースを作成する場合、Terraform は依存関係グラフ内の最初の10つのリソースを作成し、最初の10つのリソースの1つを作成し終えた後に11番目のリソースの作成を開始します。

Terraformの並列処理を増加させることは可能ですが、これにより実行時のCPU使用率が上昇します。可能な場合は、大規模なTerraform構成をリソースの少ない小さな構成に分割することをおすすめします。長時間実行されるTerraformワークロードは、肥大化した Workspace スコープの早期の兆候です。

運用時の継続的改善 🔄
#

最初からベストプラクティスに準拠できるのであれば最高なのですが、現実は様々な事情により準拠できないケースもあると思います。例えば、プロジェクトの期限、コスト、開発体制….上げだしたらキリがないです。ただし、そこで「ベストプラクティスを執らない」とはならないかと思います。個人的には「継続的にベストプラクティスに近づけること」が現場においては大事なのではないかと思います。初期構築段階、あるいはコミュニティ版 Terraform から HCP Terraform へ移行したばかりの段階では対応が難しい場合でも、日々の運用の中で継続的に改善していくことが重要なのです。

まとめ 🎉
#

かなり説得力のある観点が盛り込まれていたのではないでしょうか? 最後に HashiCorp 公式のベストプラクティスに基づく Workspace 設計のポイントをまとめたいと思います。

  1. 小さな影響範囲を保つ: 必要かつ論理的に関連するリソースのみをグループ化
  2. 公式推奨の命名規則: <business-unit>-<app-name>-<layer>-<env> の採用
  3. Volatility (変更頻度)によるグルーピング: 変更頻度に基づくグルーピング
  4. Stateful / Stateless の分離: データ損失リスクの最小化
  5. 「権限」と「責任」による分離: チーム境界に沿った適切な権限管理
  6. パフォーマンス重視: 大きすぎる Workspace は分割を検討、Terraform 実行時のパフォーマンスも考慮

これらの原則を実践することで、より安全で効率的な HCP Terraform 運用が実現できるのではないかと思います。

次回は「HCP Terraform におけるブランチ戦略」について、今回の Workspace のベストプラクティスを前提とした内容で詳しく解説する予定です。お楽しみに! 😊


この記事が参考になったら、是非 SNS でシェアしてください! Hashicorp 公式ベストプラクティスに基づいた設計・運用で、皆さんのインフラ管理がより良くなることを願っています