Amazon Builders’ Libraryの「Going faster with continuous delivery」を読む [感想文]

2019.12.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、森です。

re:Invent2019で Amzon Builder's Library というサービスが発表されました。

Check out The Amazon Builders’ Library – This is How We Do It!

これはシステムの構築および実行方法を正確に説明する詳細な記事のコレクションで,学生、開発者、開発マネージャー、アーキテクト、およびCTOは全て役に立つと言及されています。現在は13の記事が掲載されていますが、今後拡張していくとのことです。

今回はその中の一つ、

Going faster with continuous delivery継続的デリバリーにより高速化

を読んだので、まとめや感想を書き連ねていこうかと思います。

※ 記事の引用が多めな内容となっております

Going faster with continuous delivery

著者: マーク・マンスール氏

Mark Mansourは、Amazon Web Servicesのソフトウェア開発のシニアマネージャーです。彼は2014年に入社し、ソフトウェアの展開と大規模なソフトウェアの継続的な配信に焦点を当てたさまざまな内部および外部サービスに取り組んできました。仕事をしていないとき、マークは時計をいじったり、ボードゲームをしたり、ゴルフを楽しんでいます。

継続的な改善とソフトウェアの自動化

10年以上前、Amazonではコードをチェックインしてから本番稼働するまで平均16日かかっていた

  • アイデアを実現するコードを書くことに1日半
  • 新しいコードの構築とデプロイに1時間もかからない
  • 残りの14日は、チームメンバーがビルドを開始し、デプロイを実行し、テストを実行するのを待つことだった

目標は、実行速度を上げるための継続的な改善プログラムにより品質を維持または改善しながら遅延をなくすことだった。 この決定は絶えず高い基準を持ち、継続的に水準を引き上げ、高品質の製品、サービス、プロセスを提供するというリーダーシップの原則に基づいている

Amazonは、ソフトウェアエンジニアの生産性を高めるためのソフトウェア開発ツールをすでに構築していた

  • サーバー上で一連のコマンドを実行して、展開可能なアーティファクトを生成する, Brazil
  • 独自の展開システムApollo

人がビルドを開始する必要があり、展開を開始する際にビルドアーティファクトをアップロードする必要がある状態だった。そこで、 業界で発生する継続的な配信への関心に触発され、BrazilとApollo間のソフトウェア配信プロセスを自動化する独自のシステムPipelinesを構築した。

〜〜〜〜〜〜〜〜〜

何よりもカスタマーを中心に考えること、常にシンプルな方法を模索する、常に学ぶ、ビジネスではスピードが重要 といったリーダーシップ原則が社員一人ひとりがこの原則に従って行動するよう心がけているとのことでしたが、現状に満足せず絶えず改善をするという文化が根付いているのがすごいと感じましたね。

より早く、正確に、確実なものを提供していく というのはどの業界でも求められると思いますが、失敗が怖くて保守的になっていくことも多々ありますよね。。。 リーダーシップ原則, これは是非とも参考にすべき考え方です。

パイプライン:継続的なデプロイツール

少数チームの配信プロセスを自動化するPILOTプログラムを開始し、ソースコードのチェックインから稼働まで90%の時間を削減できた。 このプロジェクトは、ソフトウェアを顧客にリリースするために必要なすべてのステップを定義する方法として、パイプラインの概念を検証することから始まった。

  • 一連のステップを経てアーティファクトをビルドする
  • 新しいコードの変更がお客様に悪影響を与える可能性があるリスクを軽減する
  • 各ステップは、ビルドアーティファクトに欠陥が含まれていないという自信を高める必要がある
  • 実環境に欠陥が含まれたら、できるだけ早く本番を健全な状態に戻したいと考えている

結果、アプリケーションごとに1つのリリースプロセスのみをモデル化でき、チームのリリースプロセスの一貫性、標準化、簡素化が促進された。これにより、欠陥が少なくなる。

パイプライン使用前は、バグ修正と主要な機能リリースのリリースプロセスが異なることが一般的だったが、他のチームは、自動配信を試験的に行ったチームの成功を見て、一貫性を改善できるように、手動管理のリリースプロセスをパイプラインに移行し始めた。さらにアプローチを再検討し、プロセスを簡素化する方法を見つけていった。

パイプラインチームは、パイプラインを使用してソフトウェアを実環境に展開するチームの数を測定し、自動化のレベルによってパイプラインを分類し、完全に自動化されたリリースに移行するという目標を達成するチームもいたが、一部の組織では、品質を測定する方法により、テストを行わずにチームがリリースプロセスを自動化できているということに気づいた。 この問題を対処するため、別のリーダーシップ原則であるOwnership(長期的な視野で考え、短期的な結果のために、長期的な価値を犠牲にしない)を使用した。

  • 製品を所有するということは、その製品の欠陥の結果も所有することになる
  • パイプライン実行速度の向上と本番環境の問題への対応との間の緊張は、チームが適切にテストする意欲があることを意味する

常にビジネスを妨害することなく、ソフトウェアリリースプロセスを改善するため動いている。

もう一つ直面した問題、それは チームがお互いからソフトウェアリリースのベストプラクティスを学んでいない ということだった。 エンジニアはデプロイの問題を個別に解決していた。

  • ニーズに対応するソリューションを見つけた場合、メーリングリスト、運用会議、その他のコミュニケーションチャネルを通じて他のエンジニアに技術を宣伝していたが、2つの問題があった。
    • これらのチャネルはベストエフォート型の通信チャネルであり、すべての人が新しい技術について学んだわけではないということ
    • チームが新しいベストプラクティスを採用することを奨励するリーダーは、チームが実際にベストプラクティスを採用するために必要な作業を行ったかどうかを理解する方法がないということ

これらを解決するために、

  • ソフトウェアの構築とリリースに使用するツールにベストプラクティスのチェックを追加し、学習を機械化することにした。
  • ある組織のベストプラクティスが別の組織のベストプラクティスではない可能性があるのでチェックを組織ごとに構成できるようにした

これにより、リーダーはビジネスのニーズに合わせてリリースプロセスを調整することが可能となった。 エンジニアが日常的に使用したツール内から警告を提供することから始めることができ、チームメンバーがベストプラクティスについて学習し、そのベストプラクティスがいつ有効になるかをほぼ保証した。

組織はベストプラクティスのチェックを繰り返して改善する機会があることがわかったため、最終的にはベストプラクティスの品質が向上し、エンジニアリングコミュニティからの賛同が得られた。

適用するベストプラクティスを体系的に特定

  • エンジニアのグループが、リリースが機能しない一般的な理由をカタログ化
  • そのリストを使用して、一連のベストプラクティスチェックを作成

このプロセスを通じて、最初に可用性を優先し、次に速度を上げル方がエンジニアにとって使いやすいということに気づいた。エンジニアは手間をかけずに、可用性を低下させることなく顧客に届けたいと思っているんだ。

〜〜〜〜〜〜〜〜〜

パイプラインの構築と改善の経験が説明されていましたね。自動化を適用することで作業時間がかなり短縮されるようになって来たが、 もちろん問題も出てくる。

その問題に対処するために組織・チーム同士が協力することによってよりパイプラインを改善し、最終的には顧客に満足してもらえる製品を送り出すんだ というのを感じました。この継続性が組織に根付いているのはすごいことだと思っています。

使って終わり、ではなく、改善していく これ大事。

欠陥が顧客に届くリスクを減らす

パイプラインやデプロイシステムなどのリリースプロセスは、顧客に影響を与えないように設計する必要がある。

リリースプロセスが正しく構成されていること、ビルドアーティファクトが意図したとおりに機能することを確認する必要があること。

Deployment hygiene


デプロイテストの最も基本的な形式は、新しくデプロイされたアーティファクトが開始され、作業に応答できることを確認します。

  • 新しくデプロイされたアーティファクトが開始され、トラフィックを処理していることを確認するクイックチェックを実行する。例えば、
    • AWS CodeDeploy AppSpecファイルでライフサイクルイベントフックを使用して、デプロイを停止、開始、検証するための簡単なスクリプトをトリガーします
    • CodeDeployに最低限の正常なホストなどの手法を構築し、常にお客様にサービスを提供するのに十分な容量があることを検証します
    • 展開エンジンが障害を検出できる場合、変更をロールバックして、顧客が欠陥を発見する時間を最小限に抑える必要があります

Testing prior to production


Amazonのベストプラクティスの1つは、ユニット、統合、および実稼働前のテストを自動化し、これらのテストをパイプラインに追加することです。

  • ユニットテスト、
    • スタイルチェック、コードカバレッジ、コードの複雑さなど、ビルドマシンで実行するすべてのテストを意味します
  • 統合テスト
    • 障害挿入、自動ブラウザーテストなどのすべてのオフボックステストが含まれると考えています

検証を多く実行する、リリースプロセスのできるだけ早い段階で欠陥を検出するよう努める、テストは小さくて高速

結果、欠陥がお客様に公開されるリスクが低くなる。

  • 実稼働前テスト

Amazonでは、実稼働前テストと呼ばれる手法も使用している。運用システムとまったく同じように動作する運用前環境で、運用前環境は、そのサービスを所有するチームによってのみ使用され、顧客からトラフィックが送信されることはありません。

このアプローチには2つの利点があります。

  • サービスが運用データストアを含むすべての運用リソースに正しく接続できることを確認
  • システムが依存する本番サービスのAPIと正しく対話することを保証

Validating in production


コードを顧客にリリースするとき、一度にすべてを行わない。もし欠陥があれば、影響の範囲が大きすぎるから。

少数のお客様にのみ新しい変更を確認し、新しいコードが機能しているかどうかについてフィードバックを収集するカナリアデプロイを行う。 カナリアデプロイデプロイ後にサービスが発するエラーの量を監視します。エラー率が上がると、変更が自動的にロールバックされます。

構造化された繰り返し可能なテストですべてのエラーをキャッチするよう努めているが、欠陥がすり抜ける事がある。

  • チーム以外のメンバーが問題を検出するかどうかを確認するため、新しい変更を一定期間そのままにする
  • 数時間待つチームもあれば、数分待つチームもある

肯定的なデータポイントを収集し、一定期間待つことで次のステップに進むための自信をつける。 そして新しいコードの変更をより多くの顧客に公開していく。

ビルドアーティファクトの信頼性が高まるにつれて、コード変更の検証に費やす時間を短縮します。 これにより、可能な限り迅速にチェックインから顧客に到達することを目指しているパターンになっていく。

顧客の要求に引き続き対応できるように、システムで合成トラフィックを生成するようにしている.

  • 実行中のプロセスが正常であり、すべての依存関係がテストされることを確認するために、合成テストを設計

Controlling when software is released


ソフトウェアリリースの安全性を制御するために、変更がパイプラインを移動する速度を制御できるメカニズムを構築した。

  • メトリックの変化に基づいてアラームが発生したときに展開を防ぐように構成
    • システムのアラームに対処するために、チームが修正プログラムを展開する必要がある場合、チームがアラームをオーバーライドして、変更がパイプラインを移動するのを防ぐ
  • ビルドアーティファクトの内容に基づいてパイプラインを停止する機能もある
    • 既知の不良パッケージまたは特定のGit参照を含むビルドアーティファクトをブロック
  • パイプラインを介して変更を進めることができる時間枠を指定
    • AWSチームは、デプロイが原因で発生する問題に迅速に対応して軽減できる人が多い場合、通常、営業時間中にのみ展開するように時間枠を設定します
    • Amazonの他のチームは、顧客のトラフィックが少ないときにソフトウェアをリリースすることを好みます。これらの時間枠は、必要に応じてオーバーライドできます

〜〜〜〜〜〜〜〜〜

高品質な製品をより早く顧客に展開するために何をやってきたか、どういう事が必要だったが示されていました。

デプロイ対象の健全性のチェック、本番前の環境でのテスト、カナリアリリースによる本番環境でのテスト、リリースタイミングの制御。 異常があるとすぐさまロールバックして顧客のビジネスに与える影響を限りなく少なくするため自動化プロセスを改善してきた事がわかりました。

これらをいきなり自分たちもやろうとすると結構難しいと思いますが、全てを自動化する前にひとつひとつの項目を手動でもいいから行ってデータを取り、自分たちのビジネスに最適化どうか判断する時間を作ってから先に進んでもいいかなと思っています。

実行速度にどのように近づいたか

皆、生活を改善する機能を構築して顧客にリリースすることに非常に意欲的で、継続的な配信がそれを持続可能にする。

自動化により面倒な手作業を排除しエンジニアが時間を節約できるようになった。継続的な展開が品質に良い影響を与えることを示した。

システムが新しい場合、テストする表面積は通常、ほとんどのチームメンバーが理解できるため、一部の手動テストは扱いやすくなるが、システムがより複雑になり、チームメンバーが変わると自動化の価値が高まる。

変更を顧客に伝えるプロセスを手で管理するのではなく、顧客の価値を高めることに集中できるようになる。

Amazonは長年にわたり、お客様にソフトウェアをリリースする速度とそれらのリリースの安全性に焦点を当てた継続的な改善プログラムを実行してきた

  • 継続的な改善プログラムは、組織のさまざまなレベルのビジネスリーダーによって実行される
    • 各ビジネスリーダーはソフトウェアリリースプロセスを調整して、ビジネスへのリスクと影響を一致させることができる
    • ルールには常に例外があることがわかっている
      • オプトアウトメカニズムがあるため、永続的または一時的な免除が必要なチームの速度を落とすことはない

最終的に、私たちのチーム(パイプライン開発チーム)はソフトウェアの動作を所有し、ソフトウェアリリースプロセスに適切に投資する責任がある。

  • 痛みの場所を測定し、対処し、反復することから始めた
    • 段階的に実行し、時間の経過とともに改善を称賛する必要があった
  • Amazonが最初にパイプラインの使用を開始したとき、多くのチームは継続的な展開が機能するかどうか確信を持っていなかった
    • 現在のリリースプロセス、手動手順、およびすべてをパイプラインでエンコードすることをチームに推奨
  • パイプラインは、リリースプロセスを通じてビルドアーティファクトを自動的に促進することなく、リリースプロセスへの視覚的なインターフェイスとして機能した
  • パイプラインのさまざまな段階で徐々に自動化を有効にし、パイプラインの任意のステップを手動でトリガーする必要がなくなった

〜〜〜〜〜〜〜〜〜

継続的にリリースする事で時間を短縮し、結果的に品質に良い影響を与える事がわかったとのこと。

全てのチェックやテストを始めたのではなく、長年の努力によりリスクを特定して軽減する方法を作っていけた、これは組織として継続的に改善していこうという意識がないとなかなかできないことだと思います。改善、称賛により自信が付いてくることも頷けます。AWSの機能追加や新サービスが早い勢いで出てくるのはこういうことを行なってきているからなんだなーと感心しました。

まとめ

かなり読み応えのあるドキュメントになっていました。全ては顧客を中心に考え、 より良いものを提供するためにどういう手法をとって来たのか、どのように考えているのかがわかる内容でした。 決して満足せずさらに改善していくことでデプロイのスピード、アーティファクトの品質のどちらも達成していこうとする文化はすごいですね。

Amazon Builders' Libraryには現在13個のドキュメントがありますので、引き続き他のドキュメントも読んでいきたいと思います。