地道にAWS構築自動化に取り組んでいるお話し〜第2話『哀しみのROLLBACK_IN_PROGRESS』〜

記事タイトルとURLをコピーする

こんにちは。技術二課の永田(@nagaaki46)です。

いやー、MotoGP2015、アツかったですね〜。
ロッシをaprilia時代から見守ってきた自分としては残念な結果になってしまいました。
悲しいけどこれGPなのよね。
というわけで、ここで強引に雑誌『RACERS』(三栄書房)をご紹介させてください。
RACERS

こちら、過去のレース車両の単なる解説本ではありません。
完璧に見えた勝利でも、実は紙一重の結果だったりします。
当時チームがどのような困難に直面していたのか。
いかにして課題を解決してきたのか。
選手・エンジニアのドラマが、当時の関係者のインタビューもまじえながら描かれています。
モータースポーツは一般的なスポーツと異なり、選手とテクノロジー両方の要素が必要不可欠です。
テクノロジー面においては、はじめから最高の車体が完成することはありません。
ルール・時間・予算etc...限られた制約の中でのエンジニアの地道なトライ&エラーが、
いつか結果に繋がるわけです。
これって、僕らエンジニアも同じなんですよね。

というわけで、今年夏にご紹介した『地道にAWS構築自動化に取り組んでいるお話し』からの半年間のトライをみてみましょう〜。

半年間の歩み

YAML駆動+CloudFormation(以下、CFn)という構成は変わらずです。

が、実プロジェクトからのフィードバックで、より痒いところに手が届くよう日々改訂が加えられていきました。
今回は、3つの主な改訂ポイントをご説明します。
 

Before(2015.07時点)

Yambda201512

After(2015.12現在)

Yambda201512

 

1)より変化に強く

当初の仕組みでは、VPCからEC2、RDS等全てのリソースを
ひとつのCFn用テンプレートJSONとして生成していました。
その場合、以下のような課題がありました。

・必要とされるリソースから個別にリリースしていくことができない
・CFn用テンプレートJSONの事前検証に時間がかかる
・CFn用テンプレートJSON内で宣言できるリソース数の上限200に達するケースがある

そこで今は特定のリソース毎にCFn用テンプレートJSONを分割し、
S3にJSONを出力生成するようにしています。

Yambda201512_cfn
柔軟性は上がりましたが、以下のようなデメリットも生まれました。

・JSONの数だけ実行が必要
・Stack数がすぐ上限に達してしまい、上限緩和申請手続きが必要となる
・パラメータで依存リソースIDの指定が必要(※)

※CFnは、作成したリソースID(SubnetIDなど)を意識することなく、
CFn用テンプレートJSON内の後続の構築対象リソース(EC2など)に渡せることが売りです。
しかし、CFn用テンプレートJSONを分割し、個別実行可能としてしまうことで、
他テンプレートで作成したリソースIDの参照ができなくなります。

サーバーワークスにとって、どのリソースをどの単位で個別JSONとして切り出すのがベストなのか、
いかにシンプルに解決していくか、
まだまだ試行錯誤中です。

2)お手軽にRUN

CFnはdry-runができません。
実際に実行してみるしかないわけです。
そこで、少しでもお手軽に試せるように、
事前検証用の振る舞いもCFn用テンプレートJSONに組み込んでいます。
具体的には、CFn実行時にprod(本番)とtest(検証)の切り替えを行えるようにしています。(下記「CFn実行イメージ」と、「prodとtest時の挙動の違い」参照)


cfn_params

 

prod(本番)とtest(検証)時の挙動の違い

 prod(本番)test(検証)
インスタンスタイプ定義書の値を採用t2.micro
冗長化(RDSの場合のみ)定義書の値を採用シングル
Stack削除時の振る舞い全リソースを残す全リソースを消す


本番では高価なインスタンスタイプを適用することも多いです。
検証では大きめの課金は避けたいので、お安く試せるようにしています。
また、Stack削除時の振る舞いは、CFnのDeletionPolicy属性の切り替えで実現しています。
なぜ、Stack削除時の振る舞いを切替えるのか。
サーバーワークスでは、構成管理のためにCFnを使っているわけではありません。
あくまで初期構築のイチ手段として使っています。
DeletionPolicy属性の明示的な指定がない場合、
本番リリース後、誤ってStackが消去されると構築済みリソースも消えてしまいます。
DeletionPolicy属性がRetainであればそのような心配はありません。
(更に、構築後にStackを予め削除しておくことで、
先述の課題であげたStack数の上限緩和申請手続きも不要になります。)
検証時についてはDeletionPolicy属性をDeleteで動作させることで、
検証後に綺麗な状態に戻せるわけです。

3)不安をテストにする

定義書YAMLから生成されたCFn用テンプレートJSONを使えば、設計通りに構築できるハズです。

ほんまか??

テストしているとはいえ、生成プログラムが予期せぬ動作をする可能性もあるでしょう。
また、CFnは想定外のパラメータの組み合わせでも、エラーなく動作してしまうこともあります。
ですので、実プロジェクトで構築した際、ちゃんと構築できてるだろうな〜と思いつつ、
やっぱり目視で確認してしまいますね。
そんな確認の手間を省きたい。不安を取り除きたい。
そこで、aws-specによる自動テストです。
よく言われる「不安をテストにする」ってやつです。
期待値は定義書YAMLに記載されています。
そして一般的なアプリケーションやWEBサービスのテストと異なり、テストパターンが定形化されているので、
aws-specによるテストコードも自動生成しちゃいます。

 

Yambda201512_spec

例えば、こちらEC2のテストコードイメージになります。

Yambda_aws-spec.png

EC2インスタンスの有無、適用しているインスタンスタイプ、
ボリュームの数等がYAML定義の設定と同じか一通り確認することができます。
しかし、テスト実行にエンジニアの手間がかかっては使い物になりません。
今後どれだけお手軽な仕組みにしていけるかがポイントかなと思ってます。
そして何よりも、自動テストという新しい文化も醸成していかなければなりません。
ツールを作ることが重要なのではなく、本当に現場で使える仕組みとして浸透させることが大切です。
更に数ヶ月から半年は必要かなあ。

最後に

今年は、CFnで構築するという新しい文化が生まれた一年でした。
しかし、まだまだこれからですね。
一歩ずつ確実に前進しているのですが、やればやるほど克服すべき新たな課題が見つかり、
ゴールが遠ざかっていきます。

『何もしないなら、何も得られはしない。』
(名メカニックのジェレミー・バージェスが、保守的なチームに所属してたときの言葉らしい。)

日々、目の前の業務に追われ、改善の余裕はありません。
だからこそ、改善し続ける必要があるんです。
尋常じゃない情熱で地道にトライ&エラーを継続していけるのがサーバーワークスです。
自動化の仕組み作りは超地味で、華やかさは大してありません。
しかし、デリバリースピードをあげるために、
そして定形作業にではなく本当に価値ある業務に注力するためには、欠かせない重要な裏方といえます。
プロのAWSインテグレーターとして、来年も引き続き構築自動化を追求していきます。