はじめに
こちら の記事で terraformer というものを知ることができたので(ありがとうございます)すが、実際に自作Provider相当のリソースををこの terraformer
経由で引っこ抜くためにはどうすれば良いのかを具体的に知りたく、実際にやってみました。
その内容について書いてみたいと思います。
本記事の前提
- 自分たちが作ったProvider: https://github.com/nttcom/terraform-provider-ecl
- 自分が
terraformer
をいじっているリポジトリ(のブランチ): https://github.com/keiichi-hikita/terraformer/tree/nttcom_enterprise_cloud_support
おおよそのやることまとめ
1. terraformer/cmd
にファイルを足す
ここに自分のプロバイダ用のコマンドを足し込む。
今回は ecl.go
としてます。
実際のファイルは こちら。
2. terraform/cmd/import.go
にエントリを足す
上記で作成した cmd/ecl.go
へのつなぎを、こんな感じ で足してあげます。
3. terraformer/providers/ecl
を足す
ここに(今回は) ECLProvider
という struct を足し、然るべきメソッドを実装していきます。
これを上記のcmd経由で呼び出していく形になります。
その際、各リソースに対応した Generator
を定義し、それが []terraform_utils.Resource
を返せば良いようです。
おおよそどのリソースも同じ感じの実装で行ける感じです。
最終的に生成されるStateは本物の(Terraform側の)ProviderのReadメソッドに従って作成されるようです。
その際、形状がどうしても本来のtf定義と合わないような場合に、 PostConvertHook()
を使って変更を仕込むことができるようです。
実際のファイルは、こちら。
4. terraformer/providers/ecl/provider.go
にリソース群を追加する
別に provider.go
というファイル名には全く意味はありませんが、結局 ここ で呼ばれる子が、 map[string]terraform_utils.ServiceGenerator
を返す際に、リソース名とGeneratorの対を返せるようにエントリを追加していく必要があります。
[こんな](https://github.com/keiichi-hikita/terraformer/blob/nttcom_enterprise_cloud_support/providers/ecl/ecl_provider.go#L79-L82) イメージです。
コンパイルして動作確認
あとは公式通りにコンパイルして実行すればOKです。
OpenStack利用しているサービスなので、通常のgophercloud(僕らの場合はeclcloud)
で必要な環境変数とは別に、expor OS_DOMAIN_ID
しないと動きませんでしたが、
./terraformer import ecl --resources=computeServer,computeKeypair,networkNetwork,networkSubnet --connect=true --regions=jp4
な感じで、無事 generated
フォルダに .tf
とか terraform.state
とかエクスポートはされました。
問題点
まだリソース間の参照関係が正しくエクスポートされないようです。
例えば、 subnet.network_id => network.id
というような参照関係があるときに、いわゆる Interpolation Syntax に置き換わってくれません。
こうなってしまう
resource "ecl_network_subnet_v2" "subnet_1" {
allocation_pools {
end = "192.168.1.254"
start = "192.168.1.2"
}
cidr = "192.168.1.0/24"
enable_dhcp = true
gateway_ip = "192.168.1.1"
ip_version = "4"
name = "subnet_1"
network_id = "09a0222f-245d-4694-8c2c-00ccfc9c8917"
no_gateway = false
region = "jp4"
tags {}
tenant_id = "9ee80f2a926c49f88f166af47df4e9f5"
}
本当はこうなってほしい
resource "ecl_network_subnet_v2" "subnet_1" {
allocation_pools {
end = "192.168.1.254"
start = "192.168.1.2"
}
cidr = "192.168.1.0/24"
enable_dhcp = true
gateway_ip = "192.168.1.1"
ip_version = "4"
name = "subnet_1"
network_id = "${ecl_network_network_v2.net_1.id}"
no_gateway = false
region = "jp4"
tags {}
tenant_id = "9ee80f2a926c49f88f166af47df4e9f5"
}
gcpでnetwork/subnetworkつくって試したらちゃんと上記のようになるんですよね。
何かが悪いのだと思うのでちょっとコードを読み込んでみようかと。
また分かったらこちらに追記します。