はじめに
以前 PulumiのProviderをTerraformのProviderから実際に作成してみた という記事を書きましたが、Terrafofm 0.12が出たのと(0.12.1が出ているのは無視)、pulumi-terraformもmoduleモードに対応したようなので、改めてPulumiのプロバイダを作ってみました。
結果だけ書くと
本記事の内容を書いていくにあたって、 こちら の Pulumi Provider for Enterprise Cloud 2.0
が最新化されています。
今回やりたかったこと
- TerraformのプロバイダをPulumi用に変換する
- 変換対象のTerraformプロバイダは こちら
- nttcom organization配下にあるのがポイント
- go1.12で作業する
- 各種dep系の手順は無視してモジュールモード想定でやってみる
- で、その手順を本記事にまとめる
- (ちなみに自分のホームディレクトリは
/Users/yuzu
)
やってみてどうだった?
- 思ったよりはすんなり
- でも意外なところでハマりました
そのための手順 超概要
-
pulumi-terraform のバイナリをコンパイル
- 正確にはバイナリはどうでも良くて、そのためのbuildとかtestとかをやるため
- それを使って pulumi-ecl のsdkを再生成
1. pulumi-terraform のバイナリをコンパイル
基本的に pulumi-terraform のREADME に従って作業するのですが、
あたりを見ると、まだ $GOPATH
, dep
あたりを意識した形になってます。
とはいえgo1.12対応しているっぽいのと、 go.mod
とか置いてあってdep非依存になっていたので手順を無視して以下をやってみました。
Cloneしてくる
自分は Gitリポジトリはすべて ~/dev
配下にcloneしているので、
% cd ~/dev
% git clone https://github.com/pulumi/pulumi-terraform
gvm環境づくり
最初に go.1.12
ベースでgvm環境だけ作り直します。
% gvm use go1.12
Now using version go1.12
% gvm pkgset list
gvm go package sets (go1.12)
=> global
terraform-provider
% gvm pkgset create pulumi
% gvm pkgset use pulumi
Now using version go1.12@pulumi
% gvm pkgset list
gvm go package sets (go1.12)
global
=> pulumi
terraform-provider
これで専用のpkgsetになりました。
前回ハマった場所の書き換えは不要そう
前回、 事前作業 の中で、 tfProvidersOrg
がハードコードされていたのでどうにかならないかなぁ・・・と思っていましたが、現在は ProviderInfo
経由で渡せるようになっているようですね。
これはおそらく、 pulumi-ecl
側で tfgen
を呼び出しているところから何かしらで挿入可能なんだろうなと推測。
ということで今は何もしません。
make 開始
% cd ~/dev/pulumi-terraform
% makeする
go: finding github.com/hashicorp/terraform v0.12.0-rc1.0.20190509225429-28b2383eacae
go: finding github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709
go: finding github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f
...
=======================
Pulumi Terraform Bridge
=======================
go build github.com/pulumi/pulumi-terraform/pkg/tfgen
go build github.com/pulumi/pulumi-terraform/pkg/tfbridge
go install -ldflags "-X github.com/pulumi/pulumi-terraform/pkg/version.Version=v0.18.3-dev.1559684733+g7ace3e9" github.com/pulumi/pulumi-terraform/cmd/pulumi-resource-terraform
cd sdk/nodejs/ && \
yarn install && \
yarn run tsc
yarn install v1.12.3
warning ../../../package.json: No license field
info No lockfile found.
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
warning Your current version of Yarn is out of date. The latest version is "1.16.0", while you're on "1.12.3".
info To upgrade, run the following command:
$ brew upgrade yarn
✨ Done in 10.44s.
yarn run v1.12.3
warning ../../../package.json: No license field
$ /Users/yuzu/dev/pulumi-terraform/sdk/nodejs/node_modules/.bin/tsc
✨ Done in 3.07s.
cp LICENSE sdk/nodejs/package.json sdk/nodejs/yarn.lock \
sdk/nodejs/bin
cp README.package.md sdk/nodejs/bin/README.md
sed -i.bak 's/${VERSION}/v0.18.3-dev.1559684733+g7ace3e9/g' sdk/nodejs/bin/package.json
LINT:
golangci-lint run
/bin/bash: golangci-lint: command not found
make: *** [lint] Error 127
/bin/bash: golangci-lint: command not found
ほほう。
golangci-lint がありませんよ・・・と。
↑を見るとインストール方法が書いてあります。
その時点での最新版が v1.16.0
だったので、
% mkdir $GOPATH/bin
% curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b /Users/yuzu/.gvm/pkgsets/go1.12/global/bin v1.16.0
公式のやり方だとインストールパスの指定方法が、 $(go env GOPATH)/bin
だったのですが、gvmg使っていると$GOPATHが2つのパスを :
で結合した形で返ってしまうのでベタに指定しました。
ついでに自分は node.js 環境は ndenv を使っているのですが、これに関連して yarn についても こちら を使って最新化しておきました。(Warningが鬱陶しかったので)
では改めて、
% make
...
cp README.package.md sdk/nodejs/bin/README.md
sed -i.bak 's/${VERSION}/v0.18.3-dev.1559684733+g7ace3e9/g' sdk/nodejs/bin/package.json
LINT:
golangci-lint run // <-- 突破!
INSTALL:
mkdir: /opt/pulumi/bin: Permission denied <-- だめー
make: *** [install] Error 1
どうやら build/common.mk
で $PULUMI_ROOT
にディレクトリを作りに行ってしまうので、この時点でセットが必要。
% export PULUMI_ROOT=/Users/yuzu/.pulumi
% make
...
38891985'
[ -terraform/examples/localstate ] Wrote output to /var/folders/gd/b_32smw96wd66bhn3ttbyjdm0000gn/T/p-it-ug-30-hiki-localstate-34e3acc1-538891985/command-output/pulumi-stack-rm.20190605-151712.20da9.log
--- PASS: TestExamples (0.00s)
--- PASS: TestExamples//Users/yuzu/dev/pulumi-terraform/examples/localstate (44.34s)
PASS
coverage: 0.0% of statements
ok github.com/pulumi/pulumi-terraform/examples 44.365s coverage: 0.0% of statements
ということで pulumi-resource-terraform
が作成できました。
% cd ~/.gvm/pkgsets/go1.12/pulumi/bin <-- 要は$GOPATH/binです
% ls
dep* pulumi-resource-terraform*
2. それを使って pulumi-ecl のsdkを再生成
以前作った こちら をそのまま更新していくことにします。
masterが最新版なのでブランチ切って作業開始。
pulumi-ecl 側 Makefileの修正(を確認)
前回書いた こちら をベースに進めます。
特にしばらく触っていなかったので何ら問題ないですね。
ここ にあった、 --user
を消したのでしたね。
go.modの修正
一旦requireブロックを空にしちゃいます。
あと、 pulumi-terraform
をローカル参照に切り替え。(GitHubOrg問題が解決した今、実は現時点では必要なかったりしますが)
pulumi-eclのgo.mod
module github.com/keiichi-hikita/pulumi-ecl
require ( // <-- requireを空に(どうせmakeで埋まる)
)
replace (
github.com/pulumi/pulumi-terraform => ../pulumi-terraform
)
正式リリースしたので Terraformプロバイダへの参照パスを変更
その他import文を修正します。
当時のTerraformプロバイダは暫定パスで公開していたのですが、正式なパスである こちら に変更
結果が こちら です。
make開始
おさらいですが、コンパイルする際はpython環境をpython2にしておく必要があるっぽかった。
pyenvで2.7系の環境にスイッチしておきます。
また、先程書いたように ProviderInfo 経由で、 info.GitHubOrg
を渡してあげないといけないわけですね。
このために、
pulumi-ecl/cmd/pulumi-tfgen-ecl/main.go
を細工します。
tfgen.Main
の第3引数経由で渡せるようなので、 ここに追記をします。
...
prov := tfbridge.ProviderInfo{
P: p,
Name: "ecl",
GitHubOrg: "nttcom", // <-- こういう感じ
また、 $PULUMI_ROOT
の設定は同じく必要です。
で、makeしたのですが・・・
...
go: github.com/Nvveen/Gotty@v0.0.0-20170406111628-a8b993ba6abd: unknown revision a8b993ba6abd
go: error loading module requirements
なんだろう・・・と思ったら、どうやら pulumi-terraform
側でいくつか go.mod 内のreplaceをしてるんですね・・・。
pulumi-terraformのgo.mod
replace (
github.com/Nvveen/Gotty => github.com/ijc25/Gotty v0.0.0-20170406111628-a8b993ba6abd
github.com/golang/glog => github.com/pulumi/glog v0.0.0-20180820174630-7eaa6ffb71e4
)
ということで、 pulumi-ecl
側にもこの2行を追記。結果 pulumi-ecl
側のgo.modがこうなってます。
module github.com/keiichi-hikita/pulumi-ecl
replace (
github.com/Nvveen/Gotty => github.com/ijc25/Gotty v0.0.0-20170406111628-a8b993ba6abd
github.com/golang/glog => github.com/pulumi/glog v0.0.0-20180820174630-7eaa6ffb71e4
github.com/pulumi/pulumi-terraform => ../pulumi-terraform // <-- この行は別になくても困らない
)
で改めてmakeです。
% make (git)-[for_terraform_012]
=======================
Enteprise Cloud Package
=======================
BUILD:
go install -ldflags "-X github.com/pulumi/pulumi-ecl/pkg/version.Version=v0.17.1-dev.1552631198+g1a644ba.dirty" github.com/keiichi-hikita/pulumi-ecl/cmd/pulumi-tfgen-ecl
# github.com/pulumi/pulumi-terraform/pkg/tfbridge
../pulumi-terraform/pkg/tfbridge/provider.go:189:5: cannot use (*Provider)(nil) (type *Provider) as type pulumirpc.ResourceProviderServer in assignment:
*Provider does not implement pulumirpc.ResourceProviderServer (wrong type for Configure method)
have Configure("context".Context, *pulumirpc.ConfigureRequest) (*empty.Empty, error)
want Configure("context".Context, *pulumirpc.ConfigureRequest) (*pulumirpc.ConfigureResponse, error)
../pulumi-terraform/pkg/tfbridge/serve.go:30:21: cannot use NewProvider("context".TODO(), host, module, version, info.P, info) (type *Provider) as type pulumirpc.ResourceProviderServer in return argument:
*Provider does not implement pulumirpc.ResourceProviderServer (wrong type for Configure method)
have Configure("context".Context, *pulumirpc.ConfigureRequest) (*empty.Empty, error)
want Configure("context".Context, *pulumirpc.ConfigureRequest) (*pulumirpc.ConfigureResponse, error)
make: *** [build] Error 2
まだ出るかっ!!
とはいえコード見ると「あーたしかに」・・・って感じ。
type ResourceProviderServer interface を実装するにあたって、確かにメソッドはフルカバーしてますが、実装が正しくないわけですね。
要求としては、Configureメソッドは (*ConfigureResponse, error)
を返さないとだめなのに、 (*pbempty.Empty, error)
を返しているのでインタフェースとしての条件を満たしてない。
ということで以下2箇所を直します。
https://github.com/pulumi/pulumi-terraform/blob/master/pkg/tfbridge/provider.go#L319
変更前
func (p *Provider) Configure(ctx context.Context, req *pulumirpc.ConfigureRequest) (*pbempty.Empty, error) {
変更後
func (p *Provider) Configure(ctx context.Context, req *pulumirpc.ConfigureRequest) (*pulumirpc.ConfigureResponse, error) {
https://github.com/pulumi/pulumi-terraform/blob/master/pkg/tfbridge/provider.go#L414
変更前
return &pbempty.Empty{}, nil
変更後
return &pulumirpc.ConfigureResponse{}, nil
その他いろいろ修正
正式リリースに伴い追加されたり削除された機能をいろいろ修正。
pulumi-ecl/resources.go
の修正ですね。
ここでは省略します。
最後のmake !!
=======================
Enteprise Cloud Package
=======================
BUILD:
go install -ldflags "-X github.com/pulumi/pulumi-ecl/pkg/version.Version=v0.17.1-dev.1552631198+g1a644ba.dirty" github.com/keiichi-hikita/pulumi-ecl/cmd/pulumi-tfgen-ecl
go install -ldflags "-X github.com/pulumi/pulumi-ecl/pkg/version.Version=v0.17.1-dev.1552631198+g1a644ba.dirty" github.com/keiichi-hikita/pulumi-ecl/cmd/pulumi-resource-ecl
for LANGUAGE in "nodejs" "python" "go" ; do \
pulumi-tfgen-ecl $LANGUAGE --overlays overlays/$LANGUAGE/ --out sdk/$LANGUAGE/ || exit 3 ; \
done
warning: 18 documentation sections ignored
...
Successfully installed pulumi-ecl
LINT:
golangci-lint run
TEST FAST:
うっし、通った!!
sdkのsetup.pyをみると、
install_requires=[
'parver>=0.2.1',
'pulumi>=0.17.0,<0.18.0',
'semver>=2.8.1'
とかはいっているので parver
, semver
をpip install。
んで、sdkをimport !!
% python
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
>>>
通りますね。
ちなみにsdk群は install -e .
してますんで、コンパイルさえされれば即座に使えるようになってます。
% pip list
Package Version Location
---------------- -------------------------- -----------------------------------------
Arpeggio 1.9.0
attrs 19.1.0
grpcio 1.19.0
parver 0.2.1
pip 19.1.1
protobuf 3.7.0
pulumi 0.17.1
pulumi-ecl 0.17.1.dev1552631198+dirty /Users/yuzu/dev/pulumi-ecl/sdk/python/bin
pulumi-openstack 0.17.0
semver 2.8.1
setuptools 39.0.1
six 1.12.0
まとめ
ということで改めて作り直してみた pulumi-ecl です。
masterへのマージも完了したのでお使いいただけますです。
ちょいちょい苦労しましたが、もう少しすると安定的に、
- pulumi-terraformをCI的にmake
- pulumi-eclをmake
だけで行ける作業のようですが、まだいろいろ足したり引いたりが必要な状態ですね。
Interfaceがおかしかった件はパッチ投げても良いかもなぁとか思うけど、多分数日後には直ってるんだろう