Microservices Demo: Sock Shopの CloudFormation TemplateをTerraformとPulumiに移植したので、それに関するメモを残しておく。
最近仕事ではTerraformを触っている時間が一番多いので、研究もこの辺りのツールに関連する技術を対象とした方が良いのでは、と考えた。研究を行うためには、類似ツールの比較が必要だし、比較のためには、サンプルコード程度のものではなく、実際の環境に近い状態を再現できるコードが必要、というのが移植のモチベーションになっている。
Deployment on Amazon EC/2 Container ServiceにAmazon ECSへのデプロイ手順が載っているが、肝心のCloudFormation Templateは、元リポジトリではDeplicated扱いで削除されている。
なので、markfink-splunk/sock-shop: Deployments of the Weaveworks Sock Shop application instrumented with SignalFx.にあるファイル(ecs-fargate/cfn-stack-app-only.yaml)を移植元コードとして使うことにした。
個人用に使っている検証用AWSアカウント、惰性で使っていてぐちゃぐちゃになってきたので、いったん不要なリソースを全削除して、AWS Organizationsでマルチアカウント化、AWS Single Sign-Onで各アカウントにSSOできるようにした。
アカウント管理用のTerraformコード、最初はprivateにしていたけど、別に見えてまずい情報もないな、と思ったのでpublicにした。
これにより、CloudFormation、Terraform、Pulumiそれぞれの検証環境をアカウントごと分離できるようにした。
まずは大元となるCloudFormation Templateがデプロイできるものになっていないと話にならないので、ここから着手。元ファイルのままでは動かなかったり、そのままでは不便なところなどあったので、微修正している。差分は以下の通り。
CloudFormation Templateがデプロイできたところで、Terraformへの移植を行った。移植はおおまかには以下のような手順で行った。
上記の作業を80ほどあるリソース全てに対して行った。
Terraformerはいまいち使い勝手が悪いし、ひとつひとつどのようなリソースがあるか確認しておいた方が、後々捗りそうなので、人力で移植した。
先日行われたHashiTalks: 日本での、Quipperの鈴木さんのプレゼンで知ったtfmigratorを使えば、Terraformerのいまいちさを補えたっぽいので、今度機会があれば使ってみたい。
Terraformerがどういまいち使い勝手が悪いのか、とか、tfmigratorの使い方なんかは、鈴木さんのブログエントリに詳しく書いてあるので、興味ある方はこちらからどうぞ。
移植の最終確認として、Terraform用アカウントにapplyしたリソースをいったんdestroyして、最初から全リソースのapplyを行った。
が、上記手順4で「差分がなくなるよう必須以外のArgumentsを記述」とあるが、planで差分がなくなっても、別アカウントにapplyすると、明示してないArgumentが原因でうまくapplyできないリソースがあったので、その辺りの修正を行った。
Pulumiへの移植も、Terraformへの移植と同様に、CloudFormation用アカウント上のリソースをひとつひとつインポートしながら進めていった。
tf2pulumiやcf2pulumiといったツールもオフィシャルに提供されているけど、自分がわかりやすいようにコードやファイルを分割したかったので、これらのツールは使わなかった。
PulumiはTypeScript、JavaScript、Python、Go、C#から記述言語が選べるが、この中で一番慣れているGoで記述を行った。
Pulumiのリソースインポートは、Terraformと違いコードの生成まで行ってくれる。
たとえば、
$ pulumi import aws:cloudwatch/logGroup:LogGroup \
sock_shop \
sock-shop
といったコマンドでCloudWatch Logs log groupをインポートすると、以下のようなコードを吐いてくれる。
ただ、pulumi import
ではエラーになってうまくインポートできない場合もあり、そういう場合は、先に以下の様なコードを書いてから、pulumi up
を実行してインポートした。最後のpulumi.Import()
がポイント。
また、希にpulumi import
が吐くコードが間違っていることもあって、そういう場合は手で修正を行った。
Pulumi、サンプルコード程度しか触ったことがなかったけど、今回の移植作業でだいぶ把握できた気がする。
最初の方でもリンクを張っているけど、移植したコードはここに置いてあります。