web-dev-qa-db-ja.com

モジュールでのTerraformプロバイダー/変数の共有

プロジェクトで定義されているすべてのモジュールのプロバイダーを抽象化する方法はありますか。

たとえば、私はこのプロジェクトを持っています

├── modules
│   ├── RDS
│   └── VPC
└── stacks
    ├── production
    │   └── main.tf
    └── staging
        └── main.tf

そしてそれはうまく動作します...問題はモジュールの定義にあります

├── RDS
│   ├── README.md
│   ├── main.tf
│   ├── providers.tf
│   └── variables.tf
└── VPC
    ├── README.md
    ├── main.tf
    ├── providers.tf
    └── variables.tf

これら両方のモジュールのプロバイダーはまったく同じです

# providers.tf
provider "aws" {
  region = "${var.region}"
  version = "~> 1.26"
}

また、各モジュールの変数は異なりますが、すべてregion変数を持っています。

# variables.tf
variable "region" {
  default     = "eu-central-1"
  description = "AWS region."
}
# other module dependent variables...

モジュールレベルでこれらの情報を定義する方法はありますか?

├── modules
│   ├── providers.tf  <<< include the *shared* provider definition block
│   ├── variables.tf  <<< include the *shared* region vaiable definition block
│   ├── RDS
│   │   ├── README.md
│   │   ├── main.tf
│   │   └── variables.tf
│   └── VPC
│       ├── README.md
│       ├── main.tf
│       └── variables.tf

最後に、ほとんどの場合、モジュール定義にはリソース属性があります(Terraformレジストリからモジュールをプルしています...したがって、レジストリからのソースとベースモジュールの両方を継承できるかどうかはわかりません)

11
a14m

今のところそれを達成することは不可能です。以下の問題で同じトピックについてgithubで以前の議論がありました:

TL; DR
モジュール間での変数の共有は、テラフォームのコアの明快さ/説明の原則に反しています。

回避策
回避策は、*shared*ファイルを親ディレクトリに配置し、シンボリックリンクを使用してモジュールに追加します。

4
a14m

terragrunt を知っている場合、これはまったく問題ありません。

Terragruntは、複数のTerraformモジュールを操作するための追加ツールを提供するTerraformの薄いラッパーです。

それはあなたがちょうど行き詰まった問題のために設計されています。

account
 └ _global
 └ region
    └ _global
    └ environment
       └ resource

クイックスタート

terragrunt-infrastructure-modules-example および terragrunt-infrastructure-live-example これらの機能を示す完全に機能するサンプルコードのリポジトリを確認してください。

グローバル変数にprod/terraform.tfvarsまたはprod/account.tfvarsを使用するか、tfvarsファイルを_globalフォルダーの下に配置できます。

2
BMW

使用するプロバイダーエイリアスを渡すことで、プロバイダーパラメーターをモジュールから抽象化できます。これにより、Regionなどを参照せずにモジュールを作成し、呼び出し時にそれらの詳細を渡すことができます。

ユースケースでは、スタックフォルダーでエイリアスプロバイダーを定義できます(おそらくこれをファイルで定義し、各スタックフォルダーのシンボリックリンクを作成するのが最善です)。

# stacks/{staging,production}/providers.tf
provider "aws" {
  alias  = "us-east-1"
  region = "us-east-1"
}

provider "aws" {
  alias   = "us-east-2"
  region  = "us-east-2"
}

次に、モジュールを呼び出すときに、使用するプロバイダーエイリアスを渡します(これは、モジュールが特定のプロバイダータイプのうち1つだけを使用することを前提としています)。

# stacks/{staging,production}/main.tf
module "VPC-us-east-1" {
  source = "../../modules/VPC"

  providers = {
    aws      = "aws.us-east-1"
  }
}

module "VPC-us-east-2" {
  source = "../../modules/VPC"

  providers = {
    aws      = "aws.us-east-2"
  }
}
1
Eric M. Johnson