先日 Terraform 0.7 がリリースされました。
Terraform 0.7 の目玉機能は、なんと言っても既存リソースの import terraform import
ではないでしょうか。全世界の Terraform ユーザが長年待ちわびていた機能がついに搭載されたことになります。
あ、あと terraform.tfstate
のバージョンが 1 から 3 に上がったので後方互換性が地味に失われているのも大きいですね…
さて、自分は1年以上前から既存リソースをコード化する手段として Terraforming を開発し今に至るまでメンテナンスしてきました。
https://github.com/dtan4/terraforming
現在ではそれなりの認知をいただき、リソース追加などで Pull Request も多くもらうようになりました。 そんなことをしていたので、既存リソース import の公式対応には注目している、むしろしなければならないような立ち位置となっています。
本記事では、terraform import
を試しつつ Terraforming がこの先生きのこれるのかどうかを見ていきたいと思います。
terraform import
概要
terraform import
は、既存のリソースを Terraform の管理下に置くための機能です。Terraform 0.7 時点では、tfstate(Terraform がリソース管理状態を把握する JSON)のみ生成できます。人間が書く tf ファイルの生成はできません。
公式ドキュメントはこれ => Import - Terraform by HashiCorp
This is a great way to slowly transition infrastructure to Terraform
とのことです。楽しみですね。
A future version of Terraform will fully generate configuration significantly simplifying this process.
とも言ってるので、いずれは tf の生成にも対応するのでしょう。
対応リソース
公式が提供しているだけあって、リリース時点で数多くのリソースが import 機能に対応しています。逆に言うとすべてのリソースが対応しているわけではありません。
対応リソース一覧 => Import: Resource Importability - Terraform by HashiCorp
上にあるリソースを数えてみたところ ((Chrome DevTool Console で $('#main-content > div > ul > li’).length)) 、107種類のリソースが import に対応しています。AWS だけでなく、Azure や DigitalOcean、OpenStack など複数 provider に対応しているのも公式の強みですね。 意外と S3 系のリソースは対応していなかったりします。
実際に使ってみる
適当に EC2 インスタンスを1台立てました(以降、EC2 インスタンスの情報は一部マスキングした状態でお届けします)。
おもむろに terraform import
します。引数に Terraform 上でのリソース名 (tf ファイルの resource
につける名前) と import するリソースの ID (ここでは EC2 instance ID) を指定してあげます。
実行すると、カレントディレクトリに terraform.tfstate
が生成されます。
$ terraform import aws_instance.great-instance i-96163a09
aws_instance.great-instance: Importing from ID "i-96163a09"...
aws_instance.great-instance: Import complete!
Imported aws_instance (ID: i-96163a09)
aws_instance.great-instance: Refreshing state... (ID: i-96163a09)
Import success! The resources imported are shown above. These are
now in your Terraform state. Import does not currently generate
configuration, so you must do this next. If you do not create configuration
for the above resources, then the next `terraform plan` will mark
them for destruction.
$ ls
terraform.tfstate
中身はこんな感じ。当たり前ですがちゃんと tfstate が生成されています。
{
"version": 3,
"terraform_version": "0.7.0",
"serial": 0,
"lineage": "c1f9c929-52e9-4b4a-897f-6c5be268e505",
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {
"aws_instance.great-instance": {
"type": "aws_instance",
"primary": {
"id": "i-96163a09",
"attributes": {
"ami": "ami-374db956",
"availability_zone": "ap-northeast-1a",
"disable_api_termination": "false",
"ebs_block_device.#": "0",
"ebs_optimized": "false",
"ephemeral_block_device.#": "0",
"iam_instance_profile": "",
"id": "i-96163a09",
"instance_state": "running",
"instance_type": "t2.micro",
"key_name": "****",
"monitoring": "false",
"network_interface_id": "eni-********",
"private_dns": "ip-172-31-7-232.ap-northeast-1.compute.internal",
"private_ip": "172.31.7.232",
"public_dns": "ec2-52-196-13-225.ap-northeast-1.compute.amazonaws.com",
"public_ip": "52.196.13.225",
"root_block_device.#": "1",
"root_block_device.0.delete_on_termination": "true",
"root_block_device.0.iops": "100",
"root_block_device.0.volume_size": "8",
"root_block_device.0.volume_type": "gp2",
"security_groups.#": "0",
"source_dest_check": "true",
"subnet_id": "subnet-********",
"tags.%": "1",
"tags.Name": "great-instance",
"tenancy": "default",
"vpc_security_group_ids.#": "1",
"vpc_security_group_ids.**********": "sg-********"
},
"meta": {
"schema_version": "1"
}
},
"provider": "aws"
}
}
}
]
}
ところで、terraform.tfstate
がすでにある状態で terraform import
するとどうなるのでしょうか。
もう一台インスタンスを立てて試してみました。
import はちゃんとできます。
$ envchain dtan4 terraform import aws_instance.awesome-instance i-60103cff
aws_instance.awesome-instance: Importing from ID "i-60103cff"...
aws_instance.awesome-instance: Import complete!
Imported aws_instance (ID: i-60103cff)
aws_instance.awesome-instance: Refreshing state... (ID: i-60103cff)
Import success! The resources imported are shown above. These are
now in your Terraform state. Import does not currently generate
configuration, so you must do this next. If you do not create configuration
for the above resources, then the next `terraform plan` will mark
them for destruction.
tfstate もきっちりマージされた状態になっています。serial
もインクリメントされているのでこのまま terraform plan
を実行しても問題ありません。
{
"version": 3,
"terraform_version": "0.7.0",
"serial": 1,
"lineage": "c1f9c929-52e9-4b4a-897f-6c5be268e505",
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {
"aws_instance.awesome-instance": {
"type": "aws_instance",
"primary": {
"id": "i-60103cff",
"attributes": {
"ami": "ami-374db956",
"availability_zone": "ap-northeast-1a",
"disable_api_termination": "false",
"ebs_block_device.#": "0",
"ebs_optimized": "false",
"ephemeral_block_device.#": "0",
"iam_instance_profile": "",
"id": "i-60103cff",
"instance_state": "running",
"instance_type": "t2.micro",
"key_name": "****",
"monitoring": "false",
"network_interface_id": "eni-********",
"private_dns": "ip-172-31-15-63.ap-northeast-1.compute.internal",
"private_ip": "172.31.15.63",
"public_dns": "ec2-52-198-18-169.ap-northeast-1.compute.amazonaws.com",
"public_ip": "52.198.18.169",
"root_block_device.#": "1",
"root_block_device.0.delete_on_termination": "true",
"root_block_device.0.iops": "100",
"root_block_device.0.volume_size": "8",
"root_block_device.0.volume_type": "gp2",
"security_groups.#": "0",
"source_dest_check": "true",
"subnet_id": "subnet-********",
"tags.%": "1",
"tags.Name": "awesome-instance",
"tenancy": "default",
"vpc_security_group_ids.#": "1",
"vpc_security_group_ids.**********": "sg-********"
},
"meta": {
"schema_version": "1"
}
},
"provider": "aws"
},
"aws_instance.great-instance": {
"type": "aws_instance",
"primary": {
"id": "i-96163a09",
"attributes": {
"ami": "ami-374db956",
"availability_zone": "ap-northeast-1a",
"disable_api_termination": "false",
"ebs_block_device.#": "0",
"ebs_optimized": "false",
"ephemeral_block_device.#": "0",
"iam_instance_profile": "",
"id": "i-96163a09",
"instance_state": "running",
"instance_type": "t2.micro",
"key_name": "****",
"monitoring": "false",
"network_interface_id": "eni-********",
"private_dns": "ip-172-31-7-232.ap-northeast-1.compute.internal",
"private_ip": "172.31.7.232",
"public_dns": "ec2-52-196-13-225.ap-northeast-1.compute.amazonaws.com",
"public_ip": "52.196.13.225",
"root_block_device.#": "1",
"root_block_device.0.delete_on_termination": "true",
"root_block_device.0.iops": "100",
"root_block_device.0.volume_size": "8",
"root_block_device.0.volume_type": "gp2",
"security_groups.#": "0",
"source_dest_check": "true",
"subnet_id": "subnet-********",
"tags.%": "1",
"tags.Name": "great-instance",
"tenancy": "default",
"vpc_security_group_ids.#": "1",
"vpc_security_group_ids.**********": "sg-********"
},
"meta": {
"schema_version": "1"
}
},
"provider": "aws"
}
}
}
]
}
あとは、この tfstate や Management Console で得られる情報を元に tf ファイルを書き、terraform plan
で差分が出なければ既存リソースの import は完了です(今回はそこまでしません…)。
Terraforming との比較
それぞれ機能の比較をしてみました。
terraform import | Terraforming | |
---|---|---|
メンテナ | HashiCorp | @dtan4 |
対応リソース数 | 107 | 37 |
(↑うち AWS) | 67 | 35 |
AWS 以外の provider | Azure, DigitalOcean, Fastly, OpenStack, Triton | DNSimple, Datadog |
全リソース一括 import | x | o (resource type 単位) |
リソースを指定した import | o | x |
tfstate の import | o | o |
tf の import | x | o |
メンテナ
まず、terraform import
は言わずもがな HashiCorp 本家がやっているので安心感があります。Terraform でのリソースパラメータ追加にもリアルタイムで追従できるものと思われます。
たまにあるんですよね。Terraform のバージョンが上がってパラメータ足されたから、Terraforming の生成結果が仕様を満たさなくなることが…。
一方で Terraforming は @dtan4 が(ほぼ)プライベートの時間でメンテナンスをしています。最近 Issue, PR の消化が追いつかなくなってきて危機感を感じています。
リソース数
対応リソース数は歴然とした差があります。特に Terraforming は AWS 以外がめっぽう弱いです。AWS も基本自分が触るリソースを中心に対応しているので、ある程度偏りが出てしまうのは否めません。
AWS 以外の provider
AWS 以外の provider は、terraform import
と Terraforming できっかり分かれました。ちなみに DNSimple と Datadog は、会社で使っているので特別に開発したという経緯があります。
全リソース / リソースを指定した import 機能
terraform import
は全リソース一括 import ができないのが痛いですね。数台程度ならまだしも、多くの場合だと数十から数百のリソースを一気にコードに落とし込みたいケースになるのではないでしょうか。
awscli と連携すればできなくもなさそうですが…。この辺、Terraforming は普通に全リソースを攫ってくるようになっています。
逆に Terraforming リソース個別の import には対応していません。前々から要望はあったりするのですが、なかなか導入する気になれず…
tf の import
terraform import
は tf の生成ができないのも現時点だと難しいですね。tfstate に比べるとまだ書きやすいですが、terraform plan
で差分が出ないようきっちり書こうと思うとかなり神経を使います。
Terraforming は既存リソースの import をすべてツールに任せる思想で初めから開発していたので、tf 生成は対応しています。もちろん terraform plan
で差分が出ないようチェックも行っています。
というわけで
自分の結論としては、現時点ではまだ Terraforming が生き残れるということです。
安心感とリソース対応数という点では完敗です。しかし、いま実際既存 AWS インフラのリソースを Terraform コードに落とし込みたい場合に使うとなると圧倒的に Terraforming の方がお手軽だといえます(リソースが対応している場合)。
コマンド一発で自分のアカウントが管理するリソースを一括 import する機能と tf の import、この2つが terraform import
に実装される日までは Terraforming が使われて続けていくでしょう。使われ続けてほしい。雑なまとめだ!
今後も多くの場面で使ってもらえるよう、Terraforming のメンテナンスは精力的に続けていきます。みなさん引き続きご支援をよろしくお願いいたします。Issue, Pull Request 大歓迎です!
とりあえず Terraforming v0.10 をいい加減今週中に出さないとですね…
(This post was imported from https://dtan4.hatenablog.com/entry/2016/08/18/010652)