Traffine I/O

日本語

2023-03-13

Terraformにおけるディレクトリ構造パターン

Terraformにおけるディレクトリ構造パターン

Terraformプロジェクトのディレクトリ構造は、インフラストラクチャの管理と拡張性に大きな影響を与えます。よく整理された構造は、コードが理解しやすく、デバッグしやすいです。

Terraformの柔軟性により、インフラストラクチャの複雑さとチームの好みに応じて、ファイルとディレクトリをさまざまな方法で組織化することができます。この記事では、Terraformのディレクトリを構造化するための3つの一般的なパターンに焦点を当てます。

  • ワークスペース
    この方法では、Terraformのワークスペース機能を使用して、同じTerraformリソース内で環境を切り替えます。

  • 環境ディレクトリの分離
    このパターンでは、各環境ごとにディレクトリを分割し、個別のTerraformリソースを管理します。

  • モジュール
    このアプローチでは、モジュールを活用してリソースの作成をテンプレート化し、モジュールを呼び出す際に変数を通じて環境の違いを実現します。

ワークスペース

Terraformのワークスペースは、単一のTerraform構成内で複数の環境状態を管理する方法を提供します。各環境に個別のディレクトリを作成する代わりに、ワークスペース機能を使用して同じTerraformリソース内で環境を切り替えることができます。

次のシンプルなTerraformコードの断片を見てみます。

# Define constants per environment
variable "env_vars" {
  type = map(object({
    region = string
    cidr   = string
  }))

  default = {
    development = {
      region = "us-west-2"
      cidr   = "10.0.0.0/16"
    }

    production = {
      region = "us-east-1"
      cidr   = "10.1.0.0/16"
    }
  }
}

resource "aws_vpc" "main" {
  cidr_block = var.env_vars[terraform.workspace].cidr
  region     = var.env_vars[terraform.workspace].region

  tags = {
    Name = "${terraform.workspace}-vpc"
  }
}

この例では、Terraform構成内の各環境に対してregioncidrの変数を定義し、AWS VPCを作成する際に正しい変数セットを選択するためにワークスペース名を使用しています。

ワークスペースの利点

Terraformでワークスペースを使用することには、いくつかの利点があります。

  • DRY(Don't Repeat Yourself)原則
    ワークスペース機能を使用すると、Terraform構成を重複せずに異なる環境を管理することができ、コードの再利用が促進されます。

  • 理解しやすさ
    環境変数はファイルの先頭で定義されており、環境間の違いを理解しやすくなっています。

ワークスペースの制約事項

ワークスペースの使用は特定のシナリオには適していない場合があります。

  • 多様なインフラストラクチャの制御不足
    インフラストラクチャの構造が環境間で大きく異なる場合、ワークスペースを使用して単一の構成内でこれらの変動を管理するのは困難です。

  • 異なる認証とアクセス制御には不適切
    異なる環境が固有の認証情報とアクセス制御を必要とする場合、ワークスペースは理想的ではありません。

また、Terraformの公式ドキュメントでは、ワークスペースをシステムの分離や別々の認証情報やアクセス制御が必要な場合に使用しないことを推奨しています。

Workspaces are not appropriate for system decomposition or deployments requiring separate credentials and access controls.

https://developer.hashicorp.com/terraform/language/state/workspaces

環境ディレクトリの分離

Terraform構成を管理する際の別の一般的なパターンは、環境ディレクトリの分離です。このパターンでは、各環境ごとにディレクトリを分割して個別のTerraformリソースを管理します。

以下は、このディレクトリ構造の例です。

.
├── development
│   ├── vpc.tf
│   └── instances.tf
├── staging
│   ├── vpc.tf
│   └── instances.tf
└── production
    ├── vpc.tf
    └── instances.tf

各環境フォルダ(developmentstagingproduction)には、異なるリソース(VPC、インスタンス)を管理するための個別のTerraformファイルがあります。これにより、各環境で必要な固有の構成やリソース割り当てを行うことができます。

環境ディレクトリの分離の利点

この方法でディレクトリを構造化することには、いくつかの利点があります。

  • 環境の違い
    環境が大きく異なる場合、この構造は適しています。必要に応じて各環境の構成をカスタマイズすることができます。

  • 実装の簡素化
    環境間に依存関係がないため、実装と管理が簡単になります。

環境ディレクトリの分離の制約事項

ただし、このアプローチには課題もあります。

  • コードの重複
    このアプローチの最大の欠点は、同じ構成を各環境のディレクトリに記述する必要があるため、コードの重複が発生することです。これはDRY原則に反するものです。

モジュール

Terraformのモジュールは、インフラストラクチャの再利用可能なコンポーネントを作成するために使用されます。これらは一度定義して、異なる環境で異なる入力変数を使用して呼び出すことができるため、リソースの管理に非常に効率的です。

以下は、モジュールを使用したディレクトリ構造の例です。

.
├── modules
|   ├── ec2_instance
|   |   ├── main.tf
|   |   ├── variables.tf
|   |   └── output.tf
|   └── vpc
|       ├── main.tf
|       ├── variables.tf
|       └── output.tf
├── development
│   └── main.tf
├── staging
│   └── main.tf
└── production
    └── main.tf

この構造では、EC2インスタンスやVPCなどの再利用可能なリソースをモジュールに抽象化します。その後、各環境はそれぞれの入力変数セットを使用してこれらのモジュールを呼び出します。例えば、development/main.tfファイルは次のようになります。

development/main.tf
module "vpc" {
  source  = "../modules/vpc"
  cidr    = "10.0.0.0/16"
  region  = "us-west-2"
}

module "ec2_instance" {
  source  = "../modules/ec2_instance"
  ami     = "ami-0c94855ba95c574c8"
  instance_type = "t2.micro"
  subnet_id = module.vpc.subnet_id
}

モジュールの利点

モジュールの使用の利点は次のとおりです。

  • DRY原則
    モジュールを使用することで、インフラストラクチャの再利用可能なコンポーネントを抽象化し、コードの再利用を促進できます。

モジュールの制約事項

モジュールの使用にはいくつかの課題があります。

  • 一般的なモジュールの作成の難しさ
    様々なシナリオで汎用的に再利用可能なモジュールを作成することは難しい場合があります。

  • Terraformの高度な理解が必要
    モジュールの設計と使用には、Terraformのしっかりとした理解が必要であり、初心者にとってはハードルとなるかもしれません。

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!