Summary of Terraform v0.10

terraformのv0.10が出ましたね。 ✨

v0.10の概要とv0.9からの移行方法をメモしておきます。

v0.10の概要

以下の大きめの変更があるようです。

  • プロバイダの分離
  • 多数のプロバイダの改善
  • State Environmentsの名前の変更

プロバイダの分離がだいぶ大きな変更ですね。今まではterraformのバイナリにプロバイダのリソースが含まれていましたが、これからはtarraformのコアのバイナリとプロバイダのバイナリが分離されます。

プロバイダのリソースはそれぞれのプロバイダ毎の単一のバイナリファイルとなり、terraformにインクルードされて使われる様になります。

また、terraformのリポジトリもコアのリポジトリとプロバイダのリポジトリで分離されるようになります。

このような変更を行った目的として、terraformを改善していく速度を加速させることが挙げられています。

今まではプロバイダのリソースがterraformのバイナリに含まれていたのでプロバイダのリソースに問題があれば都度修正バージョンを出さなければいけませんでしたが、プロバイダが分離されることでterraformのコアのバージョンとは無関係にプロバイダの開発できるようになりました。的なイメージでしょうか。

このお陰でプロバイダのバージョンをロックすることもできるようになっています。

v0.9からの移行方法

例によってアップグレードガイドあります。

基本的にはterraform initするだけでOKですが、以下のケースの場合は注意が必要っぽいです。

  • サードパーティ製のプロバイダプラグインを使っている場合
    • しばらくは従来の方法でサードパーティ製のプラグインを利用できる
    • まだ公式でサードパーティ製のプラグインのincludeはサポートされていない
    • できれば今のうちにプロバイダプラグインのメンテナはバイナリにバージョン番号を含めるなど、対応を進めておくと良い
  • -targetオプションを使っている場合
    • -targetで対象のリソースを指定してplanなどを実行できる
    • 今までは-targetでモジュールを指定した場合の挙動は、指定されたモジュールのみが対象だったが、v0.10からは指定されたモジュールが読み込んでいる別のモジュールも再帰的に認識して対象となる
    • 今までの感覚で-targetオプションを利用していると、子モジュールでの変更が予期せず読み込まれてしまう可能性もあるので注意が必要
  • terraformコマンドをラップしたスクリプト、ツールを使用している場合
    • v0.10からapplyに対話的に適用するモードが追加された
    • 対話モードはv0.10ではデフォルトでOFFになっているが、将来的にデフォルトの挙動となる
    • このとき、terraformコマンドをラップしているスクリプトで影響が出る可能性がある(applyしたいのに対話モードになって処理が止まったり)

私の環境ではinitするだけでよさそう。

早速やっていきます。

terraformをv0.10にアップデート後、そのままplanを実行すると以下のようにエラーになります。

$ terraform plan
Plugin reinitialization required. Please run "terraform init".  
Reason: Could not satisfy plugin requirements.

Plugins are external binaries that Terraform uses to access and manipulate  
resources. The configuration provided requires plugins which can't be located,  
don't satisfy the version constraints, or are otherwise incompatible.

3 error(s) occurred:

* provider.vault: no suitable version installed
  version requirements: "(any version)"
  versions installed: none
* provider.digitalocean: no suitable version installed
  version requirements: "(any version)"
  versions installed: none
* provider.mailgun: no suitable version installed
  version requirements: "(any version)"
  versions installed: none

Terraform automatically discovers provider requirements from your  
configuration, including providers used in child modules. To see the  
requirements and constraints from each module, run "terraform providers".

error satisfying plugin requirements  

プロバイダが無いよ!と言われていますね。

initでインクルードしてあげます。必要なプロバイダプラグインは自動で認識されます。

$ terraform init
Downloading modules...  
Get: file:///Users/lorentzca/.ghq/github.com/lorentzca/ponpokopon.me/terraform/modules/digitalocean/droplet  
Get: file:///Users/lorentzca/.ghq/github.com/lorentzca/ponpokopon.me/terraform/modules/digitalocean/networking  
Get: file:///Users/lorentzca/.ghq/github.com/lorentzca/ponpokopon.me/terraform/modules/mailgun/domain  
Get: file:///Users/lorentzca/.ghq/github.com/lorentzca/ponpokopon.me/terraform/modules/digitalocean/dns  
Get: file:///Users/lorentzca/.ghq/github.com/lorentzca/ponpokopon.me/terraform/modules/digitalocean/dns

Initializing the backend...

Initializing provider plugins...  
- Downloading plugin for provider "vault"...
- Downloading plugin for provider "digitalocean"...
- Downloading plugin for provider "mailgun"...

The following providers do not have any version constraints in configuration,  
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking  
changes, it is recommended to add version = "..." constraints to the  
corresponding provider blocks in configuration, with the constraint strings  
suggested below.

* provider.digitalocean: version = "~> 0.1"
* provider.mailgun: version = "~> 0.1"
* provider.vault: version = "~> 0.1"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see  
any changes that are required for your infrastructure. All Terraform commands  
should now work.

If you ever set or change modules or backend configuration for Terraform,  
rerun this command to reinitialize your working directory. If you forget, other  
commands will detect it and remind you to do so if necessary.  

プロバイダがプラグインとしてダウンロードされている様子が見れますね。 ✨

Initializing provider plugins...  
- Downloading plugin for provider "vault"...
- Downloading plugin for provider "digitalocean"...
- Downloading plugin for provider "mailgun"...

プロバイダのプラグイン(バイナリ)は以下の様に.terraform/plugins/アーキテクチャ/以下に置かれていました。

.terraform
├── modules
│   └── ...
├── plugins
│   └── darwin_amd64
│       ├── lock.json
│       ├── terraform-provider-digitalocean_v0.1.2_x4
│       ├── terraform-provider-mailgun_v0.1.0_x4
│       └── terraform-provider-vault_v0.1.0_x4
└── terraform.tfstate

8 directories, 5 files  

引き続きplanで差分がないことを確認。

$ terraform plan
Acquiring state lock. This may take a few moments...  
Refreshing Terraform state in-memory prior to plan...  
The refreshed state will be used to calculate this plan, but will not be  
persisted to local or remote state storage.

...

No changes. Infrastructure is up-to-date.  

これで移行は完了。tfファイルをいじる必要はありません。 ✨

感想

今回のアップデートはどちらかと言うとterraformを開発する際のメリットが大きい内容だと思いました。プロバイダが分離されたことでより興味のあるプロバイダの開発状況が追いやすくなりましたね!

initで自動的に必要なプロバイダを認識してくれるのもありがたい。

参考リンク