複数リージョンや複数アカウントを扱うとき、Terraformではproviderブロックのaliasと、resourceのproviderメタ引数、さらにmoduleのprovidersマップを正しく組み合わせます。
Associate試験では、デフォルト継承・リソース単位の切り替え・モジュール境界での引き渡しの違いと、configuration_aliasesの宣言有無が頻出です。
Terraformでは、同じプロバイダ種別に対して複数の設定を持てます。無名の設定がデフォルト、alias属性を持つ設定が別名付き設定です。resourceやdataは、providerメタ引数を指定しない場合はデフォルト設定を継承し、指定した場合は対応する別名設定を使います。
モジュール境界をまたぐときは、ルート側でmoduleブロックのprovidersマップを使って、子モジュールへ明示的にプロバイダ設定を渡せます。子モジュール側はterraform.required_providers内でconfiguration_aliasesを宣言して、受け取る別名を許可する必要があります。
ポイントは次の3層です。1) プロバイダ設定を定義する層、2) リソースでどの設定を使うか選ぶ層、3) モジュール間で設定を受け渡す層。これを混同しないことが安定運用と試験対策の近道です。
複数プロバイダ構成の流れ(デフォルト継承と別名受け渡し)
最小構成の例(デフォルトと別名、リソースでの切り替え)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "ue1"
region = "us-east-1"
}
provider "aws" {
alias = "uw2"
region = "us-west-2"
}
resource "aws_s3_bucket" "primary" {
bucket = "example-primary-1234"
}
resource "aws_s3_bucket" "replica" {
bucket = "example-replica-1234"
provider = aws.ue1
}resourceやdataブロックでは、providerメタ引数で使用するプロバイダ設定を明示できます。書式は provider = <PROVIDER_ADDRESS>(例: aws.ue1)のように設定参照であり、文字列ではありません。
条件式で複数の設定を切り替えることも可能です。ただし、条件式の両側で参照されるプロバイダ設定は同一モジュール内で事前に定義されている必要があります。存在しない設定を参照すると計画段階でエラーになります。
注意点として、providerメタ引数はモジュールブロックには存在しません。モジュールへはprovidersマップで渡します。resourceやdataでproviderを指定する場合も、当該モジュール内に該当するプロバイダ設定が無ければなりません。
条件でプロバイダを切り替える例
variable "primary_region_is_east" {
type = bool
default = true
}
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "uw2"
region = "us-west-2"
}
resource "aws_kms_key" "example" {
description = "Example KMS key"
# eastを使うかwestを使うかを切り替え
provider = var.primary_region_is_east ? aws : aws.uw2
}子モジュールに特定のプロバイダ設定(デフォルトや別名)を渡すには、ルート側でmoduleブロックのprovidersマップを使います。マップのキーは子モジュール側のプロバイダアドレス(aws、aws.replica等)、値はルート側の実際の設定(aws、aws.ue1等)です。
子モジュール側は、terraform.required_providersの該当プロバイダにconfiguration_aliasesを宣言することで、受け取る別名を明示します。これがないと「モジュールがその別名を宣言していない」というエラーになります。
子モジュール内部のresourceでproviderメタ引数を使って、aws.replicaのように受け取った別名を選択できます。
ルート→子モジュールの受け渡し(正しい最小例)
# ルート側
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "ue1"
region = "us-east-1"
}
module "app" {
source = "./modules/app"
providers = {
aws = aws # 子のawsにデフォルトを割当て
aws.replica = aws.ue1 # 子のaws.replicaに別名設定を割当て
}
}
# 子モジュール側(./modules/app)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
configuration_aliases = [ aws.replica ]
}
}
}
resource "aws_iam_role" "main" {
name = "example-app-role"
}
resource "aws_iam_role" "replica" {
name = "example-app-role-replica"
provider = aws.replica
}マルチリージョン: 同一アカウントの複数リージョンでは、aliasにリージョン名や役割を付けます。例: aws.primary、aws.dr、aws.reportingなど。リソース側は明示的にproviderを指定し、意図しないデフォルト継承を避けます。
マルチアカウント: assume_roleや認証情報プロファイルでアカウントを分け、alias名にアカウントの意味合い(prod、stg、opsなど)を持たせます。子モジュールにはprovidersマップで必要な組み合わせのみを渡し、誤用の余地を減らします。
環境分離: ルートモジュールで環境別にプロバイダ設定を宣言し、ワークスペースや変数により切替。条件式でproviderを分岐させる際は、どの分岐でも参照する設定を事前に定義しておきます。
別アカウントへのassume_role(典型例)
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "ops"
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::123456789012:role/ops-admin"
session_name = "tf-ops"
}
}
resource "aws_ssm_parameter" "managed_by_ops" {
name = "/ops/managed"
type = "String"
value = "true"
provider = aws.ops
}どこで選ぶかにより適用範囲と落とし穴が変わります。Associate試験では、用語と適用範囲の取り違えがよく出ます。以下で要点を整理します。
| 手段 | 設定箇所 | 適用範囲 | 試験での注意 |
|---|---|---|---|
| デフォルト継承 | providerブロック(無名) | provider未指定の全resource/data | 別名を使いたい場合は明示指定が必要。混在時の意図確認 |
| providerメタ引数 | resource/dataブロック | そのブロックのみ | 書式は参照(aws.alias)。文字列ではない。未定義alias参照はエラー |
| module.providersマップ | moduleブロック(ルート側) | 子モジュール全体(キーは子のアドレス) | 子がconfiguration_aliasesを宣言していない別名は渡せない |
| configuration_aliases | 子モジュールのterraform.required_providers | 選択そのものではなく別名受け入れの宣言 | 宣言漏れで「provider alias未宣言」エラーが発生 |
試験に出やすいひっかけ(宣言漏れの例)
# ルート
provider "aws" { region = "us-east-1" }
provider "aws" { alias = "ue1" region = "us-east-1" }
module "bad" {
source = "./modules/bad"
providers = {
aws.replica = aws.ue1 # 子にaws.replicaを渡したい
}
}
# 子(./modules/bad) — これだとNG: configuration_aliases未宣言
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
# → 典型的エラー: Module does not declare provider alias named "aws.replica".初期化と依存の可視化で早期に不一致を検出します。特にmodule.providersとconfiguration_aliasesの整合性を常に確認してください。
プロバイダの有無や割り当てはterraform providersコマンドで俯瞰できます。計画は小さく切って確認し、指定ミスを局所化します。
チェックコマンド集
# 初期化
terraform init
# プロバイダの参照関係を確認
terraform providers
# 局所的に計画
terraform plan -target=module.app
terraform plan -target=aws_s3_bucket.replicaAssociate
問題 1
ルートモジュールから子モジュールへ、デフォルトのaws設定と、別名aws.ue1設定の両方を渡し、子モジュール内で一部リソースのみをaws.ue1で作成したい。正しい組み合わせはどれか。
正解: A
モジュール境界では、ルートのmodule.providersで子のプロバイダアドレスに対して実際の設定を割り当て、子側はrequired_providersでconfiguration_aliasesを宣言して受け取るのが正解。providerは参照で指定するため文字列指定は不可。別名設定は自動継承されない。変数でプロバイダを渡すことも不可。
デフォルト設定を作らず、全リソースで別名設定だけを使うことは可能ですか?
可能です。その場合は、全てのresource/dataでproviderメタ引数を明示し、モジュールへ渡す際もprovidersマップで必要な別名のみを割り当てます。デフォルトを参照するリソースが一つでもあるとエラーになるため、徹底が必要です。
providerメタ引数を変数で動的に組み立てられますか?
文字列連結のような動的組み立てはできません。providerメタ引数はプロバイダ設定への参照であり、条件式で複数の設定参照を切り替えることは可能ですが、いずれの参照先も同一モジュール内に事前定義されている必要があります。
子モジュールでaliasを使わない場合でもconfiguration_aliasesは必要ですか?
子モジュール内部で別名のproviderを参照しないなら不要です。デフォルト設定のみを受け取り、resource側でprovider指定を省略すればデフォルトが使われます。別名を使う可能性がある場合は、あらかじめconfiguration_aliasesを宣言しておくと後からの拡張が容易です。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...