by shigemk2

当面は技術的なことしか書かない

ワンクリックデプロイ いつまで手でデプロイしてるんですか? #devsumiA

吉羽龍太郎 Ryuzee.com アジャイルコーチ

アジャイル開発のお手伝いです
SCRUM BOOT CAMP THE BOOK

はじめに

本当に必要なものが分かるか?
(往々にして受託開発はクライアントの要望とどんどんズレていく)

期待のマネジメントに失敗してる

システムの開発の利用割合
「全く使わない」45%
「いつも使う」7%
「よく使う」12%

実際リリースすべきものは1/3で経費も1/3ですむ。
作りすぎのムダが多すぎる

トヨタ生産方式

加工のムダ
生産のムダ
在庫のムダ
動作のムダ
運搬のムダ
不良を作るムダ
手持ちのムダ
作りすぎのムダ

コストの見積りは正しいか
不確実性コーンと呼ばれるもの
(1000万のコストがかかったものなら、250万-4000万の間で見積られている)

ウォーターフォール(V字)

要件定義→受け入れ試験(ここに時間がかかりすぎる。下手をするとその間に要求が変わっているかもしれない)
基本設計
詳細設計
製造

よくみかける光景

  • 要件定義は順調
  • 設計は順調
  • 開発は遅れているが挽回可能です
  • 結合試験で重大な問題が出ています(がんばります なんとかします)
  • 受け入れ試験でニーズ不一致
  • リリースできません

多くのリスクが後半になって顕在化する顕在化した時点では取り返しがつかない

アジャイルマニフェスト

ケントベック マーティンファウラー ケンシュウェイバーなどが作った

  • 人と人同士の相互作用を重視
  • 動作するソフトウェア
  • 顧客との協調
  • 変化に対応

アジャイルはドキュメントを書かないんでしょ?ドキュメントも書きますが、それが重要ではない。
顧客満足を最優先し、価値のあるソフトウエアを速く継続的に提供する。

マーケットに製品を早期に投入して、投資を回収し、利益に結びつける必要性がある
長い時間をかけては作らない
MVPとフィードバックループ
ビジネスの成長とプロダクトの成長を同期させる

こういうことが出来るとアジャイルな開発が出来ていると言える
スクラムやXPのプラクティスを取り入れるだけでは無意味

「高速に石橋を叩いて渡る開発環境」を構築するためには、テクニカルなサポートが必ず必要。

毎日何回も本番環境にデプロイできているか?
顧客に頻繁に価値を届けられているか?

頻繁にリリースが出来ていれば価値を届けられる

Amazon 1000+ deploys / hour

よくある光景
てめーもっとちゃんとアプリ作れ vs 運用でなんとかすんのがあんたらの仕事だろ
あのービジネスのことちゃんと考えてよ セクショナリズムの弊害

これら5つが実践されているか?
製品そのものをAgileな状態に保つ 技術的負債を少なく保つ

継続的デリバリー(いつまで手動でデリバリーしていますか?)

継続的デリバリーの原則

  1. 繰り返し可能
  2. すべてを自動化
  3. 何回なことや苦痛なことを繰り返し行い自動化の方法を考える
  4. すべてのソースコード管理システムで管理
  5. 完了は「リリースされたこと」を意味する
  6. 品質を作りこむ
  7. すべての人にリリースプロセスに対しての責任がある
  8. 継続的に改善する

継続的デリバリーのプラクティス(一部)

  1. バイナリは1度だけビルド
  2. すべての環境にデプロイするのに完全に同一のメカニズムを使う
  3. デプロイメントでスモークテストを実施する
  4. 問題が起こったらラインを止める

テスト自動化の必要性
アジャイルかどうかに関係なくソフトウェアのライフサイクルを考慮する必要がある
小規模リリースのたびに手動でテストするとコードベースが大きくなるにつれてテストコストが膨らむ
自動化にはコストがかかるが、テストサイクルの実行回数が大きくなると、手動によるテストのコストが膨らんでいく。
そして、すぐに手動によるテストのコストのほうが上回る

修正までの時間
要求や設計 5分
コードやユニットテスト 15分
リリース後 1日

デプロイのたびに人手でテストするのは無理

テストしていないものを目を瞑ってデプロイしてはいけない(設定ファイル1行のみの修正でも危ない)
清水の舞台から飛び降りない

アジャイルテストの4象限
自動化できるものと出来ないものがある

自動テストに求められるもの

繰り返し可能
独立性
自己検証(画面に出てくる標準出力を見るようなことはしない)
簡単実行

webアプリケーションだと

モデル ヘルパー コンポーネント単位で
自信のない箇所をテスト
テストの実行時間を短く

完了の定義を作る
何をもって出荷可能かを定める
全部を短い間隔で出来れば頻繁にリリース可能
コードレビュー チェックイン ユニットテスト カバレッジ75%など…

フィーチャー単位で完了

XPやのプラクティスの利用

Jenkins 継続的インテグレーション

  • CIサーバ はプロジェクト初期の段階でコードがなくても構築する
  • 常にグリーンを保つ 赤に慣れない
  • アトミックな単位での作業、マイグレーションとの連携、チームのコミットに対する態度

アンチパターン

  • メインラインのみで大きなブランチをCI対象にしていないのはNG
  • ビルドの失敗に気付かない
  • ビルドが失敗しても放置
  • 何も変更していないのにビルドが落ちたり落ちなかったり
  • 通知メッセージが大量
  • 何も通知しない
  • 結果が出るまで時間がかかりすぎる
  • 静的解析をCIで行わずに人手で行う
  • CIサーバがおかしくなったときに直せる人がいない

バージョン管理

いわずもがな、全ての起点はここにある
コードの共同所有の原則への理解
環境によって異なる設定値が書かれた設定ファイルもバージョン管理する

さすがにマージって何?って言う人はいないだろう
バージョン管理は開発者の躾
どの断面でも再現可能か?
前のバージョンに即座に戻せる?

マイグレーション

データベースのスキーマの状態とリリースの状態を関連づけることによって再現可能とする

既存のアプローチの問題
SQLスクリプトファイルは管理が煩雑
SQLスクリプトは自動実行に向かない
SQLの実行順序で状態が変わってしまう

気付かずに本番にリリースすると絶対にトラブルが起こる

というところで、マイグレーションを利用する
ソースコードを利用する

前後関係は規約によって判断される
マイグレーションによってバージョンを戻したり進めたりすることが出来る

RoRのマイグレーションは多いですよね。

環境構築の自動化が必要となるわけ

そもそも時間がかかる
数が増えれば単純作業の繰り返し
人手による単純作業はミスを誘発
本番環境しかミスを検知する仕掛けがない

いつでもクリーンな動作環境を作れるようになる
設定やインストールの自動化

本番環境と開発環境の各種バージョンを合わせられる
設定やインストールの自動化

不要なリスクを負う必要がなくなる。

ミドルウェアのバージョンアップなども自動でできる

Chef / Chef Solo

Chefの概要

Ruby製のシステム管理ツール

出来ること
OSのパッケージのインストールや管理など。

バージョンを指定してパッケージをインストールすることが可能

多数のRecipeがOSSで公開されてる

仮想化と自動化(Vagrant)
Sandbox機能を使うことで、ミドルウェアのバージョンアップの検証、構成の変更を検証できる
Stampパターンで自由にインスタンスを複製可能

環境構築自動化の敷居が下がっている
環境構築でTDDを行う例も登場

有償ソフトウェアのライセンス管理は今後の課題

当たり前の話

ゼロデプロイを設計する

プロジェクトのあいだ、ずっとデプロイスクリプトを使うことで、プロセスがテストされ続ける
開発環境、本番環境問わず、同じ方法でデプロイする。

デプロイが失敗した場合、ロールバックできるようにする
デプロイが途中で失敗した場合、その先を手動でやらない!!
一回ロールバックしてもう1回!!

Capistrano!!
capコマンド

画面上デプロイはwebistranoで。
pythonはfebricで。

メンテページに差し替えた後に手でデプロイする方法はよくある。

データベースの不可逆な変更を避けるようにアプリケーションを作りこんだほうが
よい場合が多い。

一回冗長な作りにしておいて、成功したらそのトリガーを外すのがよい。

ビルドパイプライン
各種テストや静的解析、ステージング環境リリース、本番環境リリースなど、一元的に管理出来る

Action!!

通常のリリース

障害時に1日でリリースできる(?)のであれば、今のリリースプロセスには組織的なムダがある。
ワンクリックでデプロイできたとしても、意思決定に時間がかかるようであれば無意味

変化しないとゆるやかに死ぬ
というか、変えようとしても無駄っていうマインドがあると社員はどんどん離れていくだろう。

まとめ

  • ビジネスのために継続的な効果を届ける
  • そのためにはアジャイルなやりかたが必要
  • テストの自動化は必須
  • 常に出荷可能な状態に保つ
  • デプロイや環境構築も自動化
  • 改善をずっと続ける