SpinnakerのManual Judgementを自動化・代替する方法

SpinnakerのManual Judgementは必ずしもUI上からする必要はない。spin-deckになればなんでもできる。

January 29, 2020
spinnaker ci/cd automation

最近作ったSpinnakerのPipeline

僕が最も追っているプロダクトの一つにSpinnakerがあります。ここ2年は軽くしか追っていないです。しかし、幸いにも根本的なことは何も変わっておらず、今年度新卒入社した今の会社でSpinnakerが使われているため学生時代の知識が大いに役立っています。

その一つにSpinnakerのManual Judgementの自動化があります。
もちろんドキュメントなどはなく、そもそも自動化するものではないのですがSpinnakerのArchitectureと仕組みを知っていると簡単にできます。また、UIでManual Judgementを承認するのとは違う形で承認プロセスを行うことができます。

これらはSpinnakerでCI/CDを運用する上で、一つの自動化のお道具箱として使えるものなのでぜひご覧ください。

Spinnaker Architecture

Spinnakerのコンポーネント群
ref: Netflix Spinnaker: multi-cloud continuous integration tool

Spinnakerそのものの解説をしたいわけではないので詳しくはSpinnakerのDocumentにあたってください。また、CassandraやRedisは今は一般的に使われずMinioや外部Redis、オブジェクトストレージが広く使われていることに留意してください。もちろん使えないことはありませんが非推奨になっています。

ひとまず本記事を読むにあたって知っておくことはSpinnaker自身がマイクロサービスであり、API Gatewayアーキテクチャを取っていることです。

つまり、UIであるspin-deckとAPI Gatewayにあたるspin-gateが公開されており、それ以外のコンポーネント群はインターネットには公開されていません。

これは裏を返せば、spin-gateのAPIを知ることができればUI上でできることは自動化できるわけです。

Spinanker GateのAPIドキュメント

参考にしないほうがいいです。非常に雑なドキュメントになっています。

それでも見たい方はGATE_URL/swaggerを開くことによって見ることができますが、大した情報はありません。それでもみたいなら興味本位でどうぞご覧ください。

Manual Judgementとは

今回の対象であるManual Judgementとはどのようなものでしょうか。

「人間がそのPipelineを進めるかどうか判断するステージ」のことです。以下のようなステージ(Manual Judgement)を入れることによって実現します。

Manual JudgementがあるPipeline

これは広く一般的に使われていて、Spinnakerのコンポーネントが勝手にデプロイしたりすることを防ぐ役割もあったりします。

実際にPipelineを実行してみると以下のように停止します。

Manual JudgementでPipelineの実行が止まっている状態

例えば、Productionリリースの前に一旦、確認したいとします。人為的なミスによって誤ってリリースがされることを防ぎます。

リリース時は以下のように確認が求められます。

実際のManual Judgement

このようにManual JudgmentはProduction環境でSpinnakerを使うにあたっては有用な機能なのです。

自動化

これより自動化を進めていきます。

0. なぜ今回自動化をするのか

SpinnakerのManual Judgementをアプリケーションをつかって自動化することを示すことは以下の可能性を提示します。

Manual Judgementを別の形で半自動化ができること

例えば、自動化をアプリケーションをつかって実現できるならロジックを入れることができます。これは「Manual Judgement」が単なるボタンを押す行為ではなくてロジックを含み、インタフェースを変えられることができます。

このため、自動化ができるということは大きな可能性を秘めているわけです。

1. Manual Judgementを通知する

Manual Judgementと平行して自動化を担うServerへWebhookを送ります。

このときにspin-gateを叩くために必要な情報を集めるためのPipelineIDをSpELで渡します。必要な情報は以下の通りです。

  • Pipeline Execution ID: 実行されているPipelineのID
  • Stage ID: Manual JudgementのStageを特定するID

これはgetPipelineAPIとPipelineIDを元に求めることができます。

これを実現するには以下のようなステージを設けます。

Pipelineの作成例

このようにすることでManual Judgementが必要になったイベントをWebhookを使って通知することができます。

実際に実行するとManual JudgementのStageで実行がとまり、同時にWebhookによって通知されている状態になっています。

Manual JudgementでPipelineの実行が止まってWebhookがアプリケーションに通知している状態

2. Gateにリクエストを送る

以下のようなリクエストを送ることで承認をすることができます。

$ curl -X PATCH GATE_URL/pipelines/PIPELINE_EXECUTION_ID/stages/STAGE_ID -d '{"judgmentStatus":"continue"}' -H "Content-Type: application/json"

また逆に停止したいときは以下のようなリクエストを送ります。

$ curl -X PATCH GATE_URL/pipelines/PIPELINE_EXECUTION_ID/stages/STAGE_ID -d '{"judgmentStatus":"stop"}' -H "Content-Type: application/json"

もちろん、SSOによって認証をかけていたり、何かしらの方法でGATE_URLを守っていると思うのでその場合にはアクセストークンなどを追加してください。

このようにして自動化をすることができましたが、完全に自動化をするのではManual JudgementのStageを設ける意味がありません。

Option 3. Judgment Inputを必要とする場合

SpinnakerではManual JudgementにはContinueStopの選択肢以外にもPipelineで定義したInputを選択できる機能があります。

そのような場合には以下のようなリクエストを送るとよいです。

$ curl -X PATCH GATE_URL/pipelines/PIPELINE_EXECUTION_ID/stages/STAGE_ID -d '{"judgmentStatus":"stop", "judgementInput": ["keke"]}' -H "Content-Type: application/json"

注意点ですがJudementStatusは必須です。


自動化によるアプリケーションの例

ここまでで自動化の方法は説明しましたがどのような応用例があるでしょうか。

1. Slackによる承認

例えば以下のような構図にしている場合は、Manual JudgementをSlackで行うことができます。

Manual JudgementをSlackで承認する

このようにすることによっていちいちUI上で行う必要がなくなります。

2. ロジックの実装

1.でCloud Functionsを用いましたが、どのようなアプリケーションでもいいです。重要なのはここでロジックを実装することができるようになる点です。

ぱっと思い浮かぶものではSlack上で承認者を選ぶことができてSpinnakerのApplicationに紐づく人しか承認できないようにしたり、それこそSpinnakerのRBACはGithub Teamsと紐付けることができるので、Slackでの承認をする際にはGithub APIを使って承認の可否を決めてもいいかもしれません。

少なからず、このようにお道具箱として知ることはいいのではないかなと思います。


まとめ

Spinnakerはそれ自体がマイクロサービスになっているため、どのコンポーネントをみても面白いです。 ここ3年で大きな機能追加はないものの、UIがv2になったりすこしずつ変更点がありますが基本的な知識はずっと使えます。

アーキテクチャやマイクロサービスのそれぞれのコンポーネントを理解することによってより自動化・アプリ化の幅が広がるのではないかなと思います。

僕はもっと自分の所属している組織のCI/CDについて向きあっていきたいし、Agilityがより継続的デリバリーによって実現できたら嬉しい。 自分のプロダクトが自分が設計し、敷いたレール(=Deployment pipeline)によってデプロイされていたらきっとわくわくする。 もっと頑張りたいなと思った。

また、自分も久しぶりにSpinnakerの記事を書くことができ、いいリハビリになりました。 最後までありがとうございました。