Terraformのprovider設定とバージョン管理|required_providersとterraform.lock.hclでチーム開発を安定させる方法

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Terraform > Terraformのprovider設定とバージョン管理|required_providersとterraform.lock.hclでチーム開発を安定させる方法
「terraform initをチームで実行したら自分のPCでは動くのに同僚の環境では動かない」「先月まで動いていたTerraformコードが急に別のプロバイダーバージョンを要求してくる」
Terraformで複数人の開発や複数環境(dev・staging・prod)の管理を始めると、プロバイダーのバージョン管理のズレが原因でこうした問題が起きます。TerraformのAWSプロバイダーは本体とは独立して頻繁に更新されるため、バージョン指定を適切に設計していないと静かに環境差異が生まれます。

この記事では、required_providers ブロックによるバージョン制約の設計と、terraform.lock.hcl を使ったチーム全体での環境固定方法を解説します。バージョン制約演算子の使い分け・複数プロバイダーの設定・provider alias による複数リージョン構成と、よくあるエラーの対処法も合わせて説明します。

動作確認環境: RHEL 9.4 / Ubuntu 24.04 LTS + Terraform v1.9.x + hashicorp/aws v5.x

この記事のポイント

・required_providers でプロバイダーのsource・バージョン制約を必ず明示するのが基本
・~> 演算子でメジャーバージョンを固定しつつセキュリティパッチを自動取り込みできる
・terraform.lock.hcl は必ずGitにコミットしてチーム全体の環境を固定する
・provider alias で複数リージョン・クロスアカウント構成を1コードベースで扱える


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜプロバイダーのバージョン管理が崩れやすいのか

Terraformのプロバイダー(AWSの場合は hashicorp/aws)はTerraform本体とは独立して更新されます。AWS Providerは月に数回マイナーバージョンがリリースされ、新しいリソース属性の追加だけでなく既存の動作に影響するバグ修正も含まれます。

バージョン管理が崩れやすい典型的なパターンを3つ挙げます。

バージョン制約なし:terraform init を実行するたびにその時点での最新プロバイダーがダウンロードされます。1週間後に別のメンバーが terraform init すると異なるバージョンが入り、挙動の差異が生まれます
バージョンを完全固定しすぎ:= 5.31.0 のように完全固定すると、セキュリティパッチを含む更新が一切取り込まれません。毎回手動でバージョンを書き換える運用負荷が発生します
lock.hclをGitignoreしている:チームメンバーそれぞれが独自のバージョンで作業し、CIパイプラインではまた別のバージョンが使われます。「自分のPCでは動く」問題の最大原因がこれです

プロバイダーのバージョン管理には「制約の設計(required_providers)」と「固定の仕組み(lock.hcl)」の両輪が必要です。どちらか一方だけでは不十分です。

required_providersブロックの書き方

1. 基本構文とsource指定

required_providersterraform ブロックの中に記述します。required_version でTerraform本体のバージョン制約と合わせて管理するのが標準的なパターンです。

# versions.tf(専用ファイルに分離するのが慣習) terraform { required_version = ">= 1.5.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } # provider.tf(リージョン・認証設定) provider "aws" { region = "ap-northeast-1" }

source の形式は <名前空間>/<プロバイダー名> です。HashiCorp公式プロバイダーは hashicorp/aws のように書きます。source を省略するとデフォルトで hashicorp/<プロバイダー名> と解釈されますが、コミュニティプロバイダー(例: integrations/github)を使う場合は省略できません。習慣として常に明示しておくことをお勧めします。

required_providersversions.tf という専用ファイルに分離するチームが多く、Terraform公式ドキュメントでも推奨されています。「どのプロバイダーが使われているか」を一か所で確認できる利点があります。

2. バージョン制約の演算子を使い分ける

Terraformのバージョン制約には5種類の演算子があります。実務で特に重要な3つを押さえておきましょう。
演算子 意味 許容範囲の例 用途
= 5.31.0 完全一致 5.31.0 のみ 再現性が最優先の場合
>= 5.0 以上 5.0以上すべて(6.xも含む) 下限だけ指定したい場合
~> 5.0 悲観的制約(マイナーを許容) 5.0以上かつ6.0未満 実務の標準パターン
~> 5.1.0 悲観的制約(パッチのみ許容) 5.1.0以上かつ5.2.0未満 安定性を最優先する本番環境
!= 5.2.1 除外 5.2.1以外のすべて バグのある特定バージョンを回避
実務のベストプラクティスは ~> 5.0 のように最右の数値を1つだけ持つ悲観的制約(チルダアロー)です。「5.x系の最新マイナーを許容するが6.0以上は使わない」という意味になります。

マイナーバージョンは後方互換性が保たれることが多く、セキュリティパッチや新リソースの追加が含まれます。メジャーバージョンはAPIの破壊的変更が含まれるため、意図的な確認のうえでアップグレードしたいケースに ~> 5.0 の制約が有効です。

~> 5.1.0(パッチのみ許容)はより安定性を重視した設定です。本番環境への影響を最小化したい場合はこちらを選びます。ただしマイナーバージョンアップは手動での書き換えが必要になるため、長期的な運用負荷が増えます。

3. 複数プロバイダーを同時に使う

AWSリソース以外に null プロバイダーや random プロバイダーを組み合わせるのは標準的なパターンです。

terraform { required_version = ">= 1.5.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } null = { source = "hashicorp/null" version = "~> 3.0" } random = { source = "hashicorp/random" version = "~> 3.0" } } }

nullプロバイダー:null_resource でローカルスクリプトの実行やリソース間の依存関係制御に使います。EC2インスタンス作成後にAnsibleプレイブックを呼び出すトリガーとして利用できます
randomプロバイダー:random_id でリソース名のユニークなサフィックスを生成します。S3バケット名のようにグローバルユニークが要求される場合に ${random_id.suffix.hex} を使います

terraform.lock.hclの役割とチーム運用

1. lock.hclの構造を読む

terraform init を実行すると .terraform.lock.hcl が自動生成または更新されます。バージョン制約の範囲内で実際にインストールされたバージョンと、プロバイダーバイナリのハッシュ値を記録するファイルです。

# .terraform.lock.hcl の実際の内容例(ハッシュ値はマスク済み) provider "registry.terraform.io/hashicorp/aws" { version = "5.84.0" constraints = "~> 5.0" hashes = [ "h1:Ab1Cd2Ef3Gh4Ij5Kl6Mn7Op8Qr9St0Uv1Wx2Yz3AA=", "zh:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c...", ] }

各フィールドの意味を説明します。

version:バージョン制約の中で実際にインストールされたバージョン
constraints:required_providers で指定した制約(記録用、変更不可)
hashes:プロバイダーバイナリの整合性チェック用ハッシュ。次回の terraform init でこのハッシュと一致するバイナリのみを受け入れ、改ざんやサプライチェーン攻撃を検知します

h1: で始まるハッシュはディレクトリハッシュ(zip内のファイル構成を含む)、zh: はzipファイル全体のハッシュです。Terraform 1.4以降は zh: ハッシュが優先されます。

2. Gitにコミットすべき理由

.terraform.lock.hcl.gitignore に追加せず、必ずリポジトリにコミットします。

コミットが必要な理由は3つあります。

チームの環境統一:lock.hcl をコミットしておくと、別のメンバーが terraform init したときに同じバージョンが自動でダウンロードされます。「自分のPCでは動く」問題を根本から排除できます
CIパイプラインの再現性:GitHub ActionsなどのCIでも lock.hcl に記録されたバージョンが使われるため、ローカルとCIで動作が一致します
サプライチェーン保護:ハッシュ値が記録されているため、Registry上のプロバイダーが改ざんされた場合に terraform init がエラーで止まります

.terraform/ ディレクトリ(プロバイダーバイナリ本体)は .gitignore で除外しますが、.terraform.lock.hcl だけは例外として必ずコミット対象にします。

3. terraform init -upgradeでバージョンを更新する

lock.hcl に記録されたバージョンを更新するには terraform init -upgrade を使います。バージョン制約の範囲内で最新のプロバイダーをダウンロードし、lock.hcl を書き換えます。

# バージョン制約の範囲内で最新にアップグレード $ terraform init -upgrade Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching "~> 5.0"... - Installing hashicorp/aws v5.84.0... - Installed hashicorp/aws v5.84.0 (signed by HashiCorp) Terraform has been successfully initialized! # lock.hcl が更新されたことを確認してコミットする $ git diff .terraform.lock.hcl $ git add .terraform.lock.hcl $ git commit -m "chore: upgrade hashicorp/aws to v5.84.0"

-upgrade なしの terraform init は lock.hcl に記録済みのバージョンを優先し、最新版があっても更新しません。セキュリティパッチの取り込みが必要な場合や新しいリソース属性を使いたい場合に限って -upgrade を実行し、terraform plan で既存リソースへの影響がないことを確認してから lock.hcl をコミットします。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、Terraformのprovider設定・tfstate設計・module設計を含む、チーム開発に使えるIaC運用スキルをハンズオン形式で習得できるセミナーを開催しています。
>> Terraform実践セミナーの詳細はこちら

provider aliasで複数リージョン・複数アカウントを扱う

1. aliasの基本設定

同じプロバイダーを異なる設定(別リージョン、別AWSアカウント)で使いたい場合は alias を使います。alias なしのプロバイダーブロックがデフォルトになり、alias を付けたものを特定のリソースやモジュールに明示的に割り当てます。

# デフォルトプロバイダー(alias なし = ap-northeast-1) provider "aws" { region = "ap-northeast-1" } # エイリアスプロバイダー(us-east-1 用) provider "aws" { alias = "us_east" region = "us-east-1" } # クロスアカウント例(別IAMロールを assume する) provider "aws" { alias = "dev_account" region = "ap-northeast-1" assume_role { role_arn = "arn:aws:iam::012345678901:role/TerraformCrossAccountRole" } }

alias が必要になる代表的なケースとして、CloudFrontのACM証明書があります。CloudFrontに紐づける証明書はus-east-1にしか作成できないため、東京リージョンのALB用証明書(ap-northeast-1)とCloudFront用証明書(us-east-1)を同一コードで管理する場合に alias が必要です。

2. リソースへのalias適用

alias を設定したプロバイダーはリソースブロックで provider 引数を使って明示的に指定します。指定しないリソースはすべてデフォルトプロバイダー(alias なし)が使われます。

# デフォルト(ap-northeast-1)に作るS3バケット resource "aws_s3_bucket" "logs_tokyo" { bucket = "my-logs-ap-northeast-1-abcd1234" # provider 指定なし → デフォルトプロバイダーが使われる } # us-east-1 に作るACM証明書(CloudFront用) resource "aws_acm_certificate" "cloudfront_cert" { domain_name = "example.com" validation_method = "DNS" provider = aws.us_east # エイリアスを明示 }

モジュールに alias プロバイダーを渡す場合は、モジュール呼び出し側で providers 引数を使います。

# モジュール呼び出し側(呼び出し元の root module) module "cdn_setup" { source = "./modules/cdn" providers = { aws = aws # デフォルトを渡す aws.us_east = aws.us_east # エイリアスも渡す } }

モジュール内部で aws.us_east を使っている場合、呼び出し側で providers を渡さないと「provider configuration not present」エラーが発生します。モジュールを作成する際は required_providersconfiguration_aliases を追記してaliasを宣言しておくことをお勧めします。

よくあるエラーと対処法

「Failed to install provider」エラー

Terraform Registryへの接続が失敗した場合に発生します。

$ terraform init │ Error: Failed to install provider │ │ Error while installing hashicorp/aws v5.84.0: could not query provider │ registry for registry.terraform.io/hashicorp/aws: failed to retrieve │ authentication checksums for provider: ...

主な原因と対処:

プロキシ環境の場合:HTTPS_PROXY 環境変数を設定して実行します

# プロキシ経由でterraform initを実行する $ HTTPS_PROXY=http://proxy.company.internal:8080 terraform init

エアギャップ環境の場合:プロバイダーバイナリをあらかじめミラーリングして --plugin-dir で指定します。社内にTerraformプロバイダーミラーを構築するか、HCP TerraformのPrivate Registryを使う選択肢もあります

「Incompatible provider version」エラー

lock.hcl が異なるOS/CPUアーキテクチャで作成された場合に発生します。M1/M2 MacのエンジニアがいるチームでLinux(amd64)上で lock.hcl が作成されていると起きやすいエラーです。

$ terraform init │ Error: Incompatible provider version │ │ Provider registry.terraform.io/hashicorp/aws v5.84.0 does not have a │ package available for your current platform, darwin_arm64.

terraform providers lock コマンドで複数プラットフォームのハッシュを追加します。

# linux_amd64(CIサーバー)とdarwin_arm64(M1/M2 Mac)のハッシュを追加 $ terraform providers lock -platform=linux_amd64 -platform=darwin_arm64 Providers are now locked to specific checksums using a hash function that is supported by all versions of Terraform.

このコマンドで更新された lock.hcl をコミットすると、M1 MacとLinux CIが混在するチームでも terraform init が成功します。

lock.hclのGitコンフリクト

複数のメンバーが同時に terraform init -upgrade を実行してプッシュするとコンフリクトが発生します。ハッシュ値の構造上、マージエディタで手動解決しようとすると整合性が壊れます。安全な対処手順は「削除して再生成」です。

# コンフリクトした lock.hcl を削除して再生成する $ rm .terraform.lock.hcl $ terraform init $ git add .terraform.lock.hcl $ git commit -m "chore: regenerate lock.hcl after merge conflict"

コンフリクトを防ぐには、プロバイダーのアップグレードをチームで1人が担当するルールを設けるか、Renovateなどのツールで依存関係更新を定期自動化する方法が有効です。

本記事のまとめ

Terraformのプロバイダー設定とバージョン管理の要点をまとめます。
設定・操作 役割 実務でのポイント
required_providers source・バージョン制約を宣言する ~> 演算子でメジャー固定・マイナー許容が基本
terraform.lock.hcl 実際のバージョンとハッシュを記録する 必ずGitにコミットする(.gitignore 禁止)
terraform init -upgrade 制約範囲内で最新バージョンに更新する plan確認後にlock.hclをコミットする手順で
provider alias 複数リージョン・複数アカウントを扱う CloudFront用ACM証明書(us-east-1)などに必須
terraform providers lock 複数プラットフォームのハッシュを追加する M1 Mac + Linux CIの混在チームで必要
チームでTerraformを運用するための基本ルールをまとめます。

required_providers にはsource・version(~> 5.0 形式)を必ず明示する
.terraform.lock.hcl.gitignore に追加せず、必ずリポジトリにコミットする
・プロバイダーのアップグレードは terraform init -upgradeterraform plan 確認 → lock.hclをコミットの手順で行う
・M1/M2 MacとLinux CIが混在するチームは terraform providers lock -platform=... でマルチプラットフォーム対応する

関連記事もあわせてご覧ください。
Terraformのtfstate管理とS3バックエンド設定|チーム運用で壊さないための基礎
TerraformのHCL変数設計|variable・locals・output・data sourceで構成を整理する方法
Terraformのlifecycleブロックで本番リソースを誤削除から守る方法
TerraformによるAWSインフラのコード化からチーム開発・CI/CDパイプライン統合まで、実機ハンズオン形式で体系的に習得したい方へ。プロバイダーバージョン管理・tfstate設計・module設計の実務パターンを含むセミナーを開催しています。
>> Terraform実践セミナーの詳細はこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。