Terraform Pulumi、 こんな 感じで比較されてますよね。
なるほど・・・と思う点と、そうかぁ?(笑)と思う点があります。
The major difference
の2点目は少し納得。
ただそれを読んでいて、ここがすごく気になった。
We have a tool, tf2pulumi, that converts Terraform HCL to Pulumi. It is open source on GitHub, and works for most projects we have come across; if you run into a snag, Issues and Pull Requests are welcome! Download and use it now.
tf2pulumi
・・・?
確かに僕にPulumiを教えてくれた人も、 Pulumiって主要クラウドしかサポートしてないけど、Terraformのプロバイダさえあれば何でも出来るらしい
ということを言っていた。
そんな中、 前回の記事 にもコメントを頂き納得。
TerraformのProviderがあればPulumiのProviderも比較的簡単に作れる
ということなんですね。
で、実際にやってみました。
Providerを変換してみた
いろいろ調べていたら ここ にたどり着きました。
まずはgvmで新しいpkgset作って、 Building and Testing
までは終わらせる。
makeしても何も起きないなーと思っていたのですが、 This repo on its own isn't particularly interesting, until it is used to create a new Pulumi provider.
ってことのようですね。ここまでは前提だと。
中段に Adapting a New Terraform Provider
という一節があり、ここからが本番のようです。
これによると、
- cmd/pulumi-tfgen-aws/
- cmd/pulumi-resource-aws/
- resources.go
を用意すればいいとある。(上の2つはディレクトリになってるけど、実際はその中のmain.goを書く)
自分の場合は、作っているプロバイダが、 terraform-provider-ecl なので、
- cmd/pulumi-tfgen-ecl/
- cmd/pulumi-resource-ecl/
- resources.go
となりますね。
事前作業
前提としてECL(Enterprise Cloud)のProviderはOpenStackのをベースにしてるんで、
- まずは pulumi/openstack をForkしてきて名前を変える。
- sdkフォルダを空にする
ってのをやりました。
で、そのリポジトリが、 ここ 。
その上で、
- PULUMI_ROOTも然るべき場所に設定しておく。自分の場合は ~/.pulumi/
とし、
- Gopkg.lock等、dep関連の各種ライブラリの参照パスやプロバイダ名などを変えていく。要らないものを消す。
- dep ensureする
みたいなことをやっていきました。
1つハマったのは、dep ensureした後、事前に vendor/github.com/pulumi/pulumi-terraform/pkg/tfgen/gitinfo.go
の以下を書き換えておかないと駄目でしたね。
Enterprise Cloudのプロバイダはterraform-providers配下には存在しないのでハードコードされていると困る。
const (
tfGitHub = "github.com"
tfProvidersOrg = "nttcom" <-- ここに terraform-providersがハードコードされてたのを修正
tfProviderPrefix = "terraform-provider"
)
さてここからmakeに向けて進んでいきます。
pulumi-ecl の Makefile 修正
僕の場合はvirtualenv使っているんで、pulumi-eclのMakefileの以下を修正する必要がありました。
pip install --user
はエラーとなるので、 --user
を除去。
install::
GOBIN=$(PULUMI_BIN) go install -ldflags "-X github.com/keiichi-hikita/pulumi-ecl/pkg/version.Version=${VERSION}" ${PROJECT}/cmd/${PROVIDER}
[ ! -e "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)" ] || rm -rf "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)"
mkdir -p "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)"
cp -r ${PACKDIR}/nodejs/bin/. "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)"
rm -rf "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)/node_modules"
cd "$(PULUMI_NODE_MODULES)/$(NODE_MODULE_NAME)" && \
yarn install --offline --production && \
(yarn unlink > /dev/null 2>&1 || true) && \
yarn link
cd ${PACKDIR}/python/bin && $(PIP) install -e . <-- ここにあった --user を除去
ちなみに僕の場合、python2環境じゃないとmakeができませんでした。
なぜかMakefileの $PYTHON が python2 になってしまう。。。
これって仕様?(多分違うと思うけど)
ですが、実際に生成されるpulumi_eclをimportする段階で型宣言文でsyntax error引くので、pulumi providerを利用するvirtualenvはpython3ベースで作りましょう。
とりあえず上記の変更をしてMakefileはコミットしてありますが分岐しないと何でしょうね本当は。
この2つはIssueでも切って提案してみようかなぁ。。
(でも修正点2は自分自身で解決策がわからないけど。自身がvirtualenvかどうかって判別できるんかな)
ファイル修正
その上で下記3点を修正する。それがこれら。
cmd/pulumi-tfgen-ecl/main.go
cmd/pulumi-resource-ecl/
resources.go
これでmakeの準備は整いました。
make してみよう
この状態で、 pulumi-ecl
配下で make
すると、以下のようなドキュメントが無いよwarningが大量に出るけどsdkは出力されました。
warning: Could not find docs for resource ecl_compute_volume_attach_v2; consider overriding doc source location
warning: Could not find docs for resource ecl_compute_volume_v2; consider overriding doc source location
warning: Could not find docs for resource ecl_imagestorages_image_v2; consider overriding doc source location
...
当然dep利用なんで、コンパイル対象は $GOPATH/src
配下の然るべきパスで無いと駄目です。
適当な場所にcloneしてる場合はsymlinkでも貼っておきましょう。
makeの一番最後の処理で、該当のvirtualenv配下にpip install -eでインストールされているので、importも出来る状態になってます。
% python (git)-[initial-setup]
Python 3.6.6 (default, Oct 3 2018, 13:51:45)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.10.44.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pulumi_ecl import compute
>>>
エラー出ません。行けましたね。
実際にPulumiから発動
こんな main.py を作ってリソース作成をしてみます。
% cat __main__.py
import pulumi
from pulumi_ecl import compute
# Create an OpenStack resource (Compute Keypair)
keypair = compute.Keypair('pulumi-keypair1')
# Create an OpenStack resource (Compute Instance)
instance = compute.Instance('instance01',
name='instance01-pulumi',
flavor_name='1CPU-4GB',
key_pair=keypair.name,
image_name='Ubuntu-18.04.1_64_virtual-server_02')
# Export the IP of the instance
pulumi.export('instance_ip', instance.access_ip_v4)
無事行けました〜
% pulumi up
Previewing update (dev):
Type Name Plan
+ pulumi:pulumi:Stack pulumi_work-dev create
+ ├─ ecl:compute:Keypair pulumi-keypair1 create
+ └─ ecl:compute:Instance instance01 create
Resources:
+ 3 to create
Do you want to perform this update? yes
Updating (dev):
Type Name Status
+ pulumi:pulumi:Stack pulumi_work-dev created
+ ├─ ecl:compute:Keypair pulumi-keypair1 created
+ └─ ecl:compute:Instance instance01 created
Outputs:
instance_ip: "192.168.99.11"
Resources:
+ 3 created
Duration: 17s
Permalink: https://app.pulumi.com/keiichi-hikita/pulumi_work/dev/updates/22
以上、Terraform-ProviderからPulumiのProviderにConvert成功しました。
公式プロバイダではないためにいろいろハマりましたがいけますね。
こりゃー便利ですが、Terraform的にはいいところどりされて悔しい感はないのだろうかと思ってしまいます。