先日、ついにterraform 0.12.0[GA]がリリースされました...!
早速、使用してみたいと思います。
HCL2では設定ファイルだけど、演算や式評価などプログラミング言語的な要素を持ち合わせています。
拡張された箇所以外の構文はほぼ一緒ですが、HCL2は後方互換がありません。
tfenvで0.11.14と0.12.xを使い分ける運用でもいいかもしれません。
手順
terraform v0.11.14にupgradeする
0.11.14で0.12checklist
というヘルプコマンドが追加されています。
$ terraform -help
Common commands:
apply Builds or changes infrastructure
console Interactive console for Terraform interpolations
destroy Destroy Terraform-managed infrastructure
env Workspace management
fmt Rewrites config files to canonical format
get Download and install modules for the configuration
graph Create a visual graph of Terraform resources
import Import existing infrastructure into Terraform
init Initialize a Terraform working directory
output Read an output from a state file
plan Generate and show an execution plan
providers Prints a tree of the providers used in the configuration
push Upload this Terraform module to Atlas to run
refresh Update local state file against real resources
show Inspect Terraform state or plan
taint Manually mark a resource for recreation
untaint Manually unmark a resource as tainted
validate Validates the Terraform files
version Prints the Terraform version
workspace Workspace management
All other commands:
0.12checklist Checks whether the configuration is ready for Terraform v0.12
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
state Advanced state management
-
terraform init
で必要なプラグインが全てインストールされているか確認する 問題なければ下記MSGが表示される
Looks good! We did not detect any problems that ought to be addressed before upgrading to Terraform v0.12 This tool is not perfect though, so please check the v0.12 upgrade guide for additional guidance, and for next steps: https://www.terraform.io/upgrade-guides/0-12.html
tfevfをinstallする
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
$ ln -s ~/.tfenv/bin/* /usr/local/bin
0.12.0をインストールする
$ tfenv install 0.12.0
$ tfenv list
0.12.0
* 0.11.14 (set by /Users/kazumineigahara/.tfenv/version)
$ tfenv use 0.12.0
[INFO] Switching to v0.12.0
[INFO] Switching completed
terraform設定をアップグレードする
初期化された作業ディレクトリで0.12upgrade
を実行して、HCL2の構文に自動変更させます。
移行失敗した構成についてはファイル中に特別なマーカーとしてTF-UPGRADE-TODO
がコメントされるので手動で更新します。
$ terraform 0.12upgrade
This command will rewrite the configuration files in the given directory so
that they use the new syntax features from Terraform v0.12, and will identify
any constructs that may need to be adjusted for correct operation with
Terraform v0.12.
We recommend using this command in a clean version control work tree, so that
you can easily see the proposed changes as a diff against the latest commit.
If you have uncommited changes already present, we recommend aborting this
command and dealing with them before running this command again.
Would you like to upgrade the module in the current directory?
Only 'yes' will be accepted to confirm.
Enter a value: yes
-----------------------------------------------------------------------------
Error: failed to load provider "aws": Incompatible API version with plugin. Plugin version: 4, Client versions: [5]
プラグインと互換性のないAPIバージョンだとしてエラーが出たので、古いプラグインを削除して新しいものをインストールします。
$ rm -r .terraform && terraform init
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (terraform-providers/aws) 2.12.0...
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.aws: version = "~> 2.12"
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.
ソースコードの書き換えが完了したらversions.tf
というファイルが作成され下記MSGが出ます。
Upgrade complete!
The configuration files were upgraded successfully. Use your version control
system to review the proposed changes, make any necessary adjustments, and
then commit.
- versions.tf
モジュールがv0.12のみの機能を使用するようにアップグレードされたことを示しています。
tf
terraform {
required_version = ">= 0.12"
}
書き換えされた場所を見てみます。
- security_group.tf ```tf resource "aws_security_group" "xxxxxxxxxxxxxx" { vpc_id = var.VPCId name = "xxxxxxxxxxxxxx"
ingress {
from_port = "22"
to_port = "22"
protocol = "tcp"
security_groups = ["sg-xxxxxxxx"] // comment
}
ingress {
from_port = "22"
to_port = "22"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = "0"
to_port = "0"
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "xxxxxxxxxxxxxx"
Service = "xxxxxxxxxxxxxx"
Environment = "xxxxxxxxxxxxxx"
Description = "Managed by Terraform"
}
}
```
HCL2では式を直接利用できるようになっているのでvpc_id = "${var.VPCId}"
がvpc_id = var.VPCId
となり補完シーケンスは不要となります。
terraform planでの可読性も上がっている...
$ terraform plan
# aws_security_group.subnet_change_int_sg will be created
+ resource "aws_security_group" "xxxxxxxxxxxxxx" {
+ arn = (known after apply)
+ description = "allow internal traffic"
+ egress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = ""
+ from_port = 0
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "-1"
+ security_groups = []
+ self = false
+ to_port = 0
},
]
+ id = (known after apply)
+ ingress = [
+ {
+ cidr_blocks = []
+ description = ""
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = true
+ to_port = 22
},
]
+ name = "xxxxxxxxxxxxxx"
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Description" = "Managed by Terraform"
+ "Name" = "xxxxxxxxxxxxxx"
}
+ vpc_id = (known after apply)
}
上記は単純な変更で済んでいますが、複雑な設定になってくると手動で解決しないといけないケースが出てくるはずです。