Azure Rock Star Community Day #2 - 年末年始はスキルアップ

azurerockstar.connpass.com

ここ1年 Azure DevOps を使っているので Connpass で Azure 関連の会を探す機会が増えました。 そこで、この会が目に止まりました。Rock Star とは一体、と。 どうやら日本で有志が運用している Azure コミュニティと Microsoft をつなぐ場のようです。 これによって、何の Azure コミュニティがあるのかを知ることができ、 Microsoft MVPMicrosoft Learn を知り、学んでいる人々を知り、学習機会が増えるということですね。 私が参加している TFSUG から発表があり、ものは試しと参加してみることにしました。

www.microsoft.com

Day #1 はプログラムとレポートを見るとコミュニティの紹介が中心のようですね。

対して Day #2 は Microsoft Learn に焦点が当てられていました。 Microsoft Learn は Microsoft 製品 を中心としたオンライントレーニングプラットフォームです。 個別のコンテンツを自分の好きなようにまとめることができ、まとめたものはコレクションと呼ばれます。 今回はいくつかのコミュニティが作成した Microsoft Learn コレクションが紹介されました。

しかも、それらのコレクションをこなすとちょっと豪華なノベルティグッズがもらえるという キャンペーンが行われているとのことです。似た取り組みは Microsoft IgniteMicrosoft Build でも 行われていて Cloud Skills Challenge と呼ばれたそうです。 今回も Cloud Skills Challenge と呼ばれていて、Day #2 Connpass のページに 対象の Microsoft Learn コレクションへのリンクがあります。 Challenge の期限は 2021/01/19 とのこと。

Day #2 は初めて Microsoft Learn で学ぶ人々のための紹介から始まりました。 以下、セッションごとにまとめます。箇条書きは聴講中のメモ。ほかは感想です。

Microsoft Learn 最初の一歩

  • Microsoft Learn は無料のオンライントレーニングプラットフォーム
  • Microsoft Learn という名前ではあるが MS 製品特有ではないコンテンツもある (例:データサイエンス)
  • 何を学ぶか、製品別に探す (Azure, Power BI…)、ロール別 (開発者、管理者、ソリューションアーキテクト、学生…)
  • 資格をとるにはこれを勉強すればよいというコレクションもある。Learn に似たコンテンツ似た問題が出る。
  • 自分のレベルと興味に合わせたコレクションを作ることもできる
  • チームメンバー向けにコレクションを作る。例えば、Azure に詳しくないメンバー向けに、これを最初に学んでおくと理解が深まるとすすめる。
  • CMU、オックスフォードなど大学が作ったコレクションもある
  • コードを書ける環境がついている場合もある (例:最初の C# コードを記述する .NET エディター)
  • 最後に知識チェックができる

大学もコレクションを作っているというのが新鮮でした。 チームメンバー向けにコレクションを作るのは言われてみればなるほどですが気づきませんでした。

Azureの機能を学ぶ前に抑えておくこと

  • Azure コミュニティのセッション中に当たり前のように出てくる、そして説明もなく流されるワードを学習できるように
  • 例:サブスクリプション、リソースグループ、リージョン、SLA、契約、サポート
  • コミュニティに参加したときのハードルが下がることが目的のコレクション
  • このコレクションを学べば、セッション中の?が減ること間違いなし

確かにどの Azure 機能を学ぶにしても前提としておきたい領域だと思いました。 Azure Fundamentals 試験(AZ-900) の学習にも良さそうです。

これからはじめるCI/CD(Azure Pipelines/GitHub Actions)

  • Azure DevOps には割といっぱい機能がある - Boards, Repos, Pipelines, Tests, Artifacts, ほかサービスとの連携, Azure のセキュリティ
  • まともに作ると20時間は軽く超えるコレクションになる
  • 効果が高いのは Pipelines ではないかと考えコレクションを作成

まともに作ると20時間+ は納得。効果が高いのは Pipelines と考えた理由を知りたいところ。

Cogbot Community スタッフが選ぶ Microsoft Learn コレクション 2020 Winter

  • Cogbot - Cognitive Services x Bot Framework, Bot Service, Virtual Agent
  • 4名で作ったのに6本もある。うち3つは大森さん作成、すごい。
  • 請求書を自動で読み取って構造化データとして活用する
    • 画像,PDFの請求書を Blog Storage に
    • Blog Trigger で Logic App 起動
    • Cognitive Services From Recognizer でフォームデータ解析 (最近日本語対応)
    • 解析したデータを Cosmos DB に保存
    • 問い合わせメールをDBに保存、緊急性の高いものは優先対応
  • 問い合わせメール、フォームを M365 Event Trigger で Logic App 起動
    • まずは One Drive にデータ保存
    • ネガポジ分析を Cognitive Services Text Analytics
    • キーワード抽出、文意クラス分け Cognitive Services Language Understanding
    • ネガティブまたはキーワードがあれば Outlook メール転送
  • 写真を整理&タグ付けして検索可能にする
    • Blog Storage に画像を保存すると Timer Trigger で Function 起動
    • メタデータを Cosmos DB に保存
    • サーチのインデックスを作成
    • 写っているものを Cognitive Services Computer Vision, Face, Custom Vision で判定してタグ付与
    • Web API で Search
  • ラムダアーキテクチャーを利用したデータのインジェストと Automated Machine Learning
  • Slack にアップロードされた人の顔の感情にマッチした絵文字を置き換えるボットを作る
    • Slack から webhook で Function 呼び出し
    • Cognitive Service Face API で画像
    • Azure Functions Core Tools

例がたくさんあって、トリガー、処理、保存に Azure の何が使えるのかという概観がつかめました。

(まだギリギリ) 2020 年から始め (られ) る Cosmos DB 入門

  • Japan Azure Cosmos DB User Group
  • これだけ押さえておけば大丈夫という内容、Open APIアプリ開発、Functions との連携、SignalR など
  • 8時間で完了できることを意識して作った。1日で Cloud Skill Challenge 達成できる。

1日で Cloud Skills Challenge を達成できるようにという配慮がユニークでした。 実は、私はデータベースなるものに全く縁がありません。 これを機にこのコレクションをやってみようかと思いました。

SQL Server 2019 on Linux Intro

Azure DevOps Server を少しだけ使ったときに SQL Server をインストールしたことを思い出しました。 てっきり Windows 用だと思ったのですがそうではないのですね。

おわりに、ついでに

この Day #2 の少し前に AZ-400 (DevOps の試験) に申し込んでいました。 そして、Microsoft Learn がたくさん紹介されたことを機に、まだ手のついていなかった AZ-400 関連の Microsoft Learn をこなし、12/26 に合格しました。 やっててよかった Microsoft Learn。 Cloud Skills Challenge はまだ達成できていないので引き続き学ぼうと思います。

Azure DevOps を1年間使ってみて押さえておくべきと思ったこと

これはAzure DevOpsアドベントカレンダー5日目の記事です。

qiita.com

仕事でも個人でも Azure DevOps Services を使って1年くらい経ちました。 Azure DevOps Services を選択してから現在までの経験の中で、これから使う方々が押さえておくべきであろう事柄の要点を綴ります。 機能や価格などは本記事執筆時点のものです。

割安

azure.microsoft.com

Basic Plan では Boards というプロジェクトマネジメント機能、Repos というリポジトリホスティングレビュー機能、 Pipelines というコミットや周期をトリガーとしたジョブ実行機能を使うことができます。 これらが連携することにより、計画、成果物更新、テストをつなげることができます。 荒っぽいですが、OSS で言えば Redmine + Gitea + Jenkins、アトラシアン製品で言えば JIRA + Bitbucket + Bamboo に相当します。

価格は1月1ユーザー672円です。 単純に、計画、成果物更新、テストを連携する機能の有無で比較するなら商用ツールとしてはとても割安だと思います。 もちろん UX や組織との親和性は別途熟慮する必要はありますが、機能でみればという意味です。 Pipelines でたくさんのジョブを実行するとなると別料金がかかります。 私たちの用途ではそれを含めても割安に思えました。

これだけで DevOps ができるわけではない

DevOps - Wikipedia

∞ の形で表される DevOps のサイクルを実現するためには、市場に出したプロダクトがどう使われているかを観測して次のソフトウェア要求を導出するプロセスが必要ですが、 Azure DevOps にはそのための機能はありません。

サービスレベルとセキュリティ

企業でクラウドサービスを導入するには、ましてや開発の基盤に据えるサービスであるからには相応のサービスレベルとセキュリティが求められます。 それを確かめるためには Data security, Azure DevOps Services というページを読むことをおすすめします。 docs.microsoft.com

また、Azure 全般について国際標準の認証、法令順守がまとめられているページも参考になります。(例:ISO 27001、GDPR) docs.microsoft.com

ユーザー管理のセキュリティについては Azure DevOps だけでなく Azure Active Directory と合わせて知る必要があります。 ここはソフトウェア開発ツールだけを探している人々には気づきにくい盲点ではないかと思います。 必要なセキュリティ機能を使うためには Azure Active Directory の料金が必要となるかもしれず、 Azure DevOps の料金と合わせたら予算オーバーしてしまったということがないよう気を付ける必要があるでしょう。 azure.microsoft.com

サービスレベルについて。Twitter では知人がまれに「GitHubが落ちてるから今日は仕事できない」という旨のツイートをすることがあります。 Azure DevOps についてもそういったことはあります。 ここ1年で私がサービスダウンを観測した日数は2、復旧時間は4時間以内でした。 これくらいであれば商用サービスとして十分ではないでしょうか。

Azure DevOps が生きてるかは https://status.dev.azure.com/ で確認することができます。 いつもは安定稼働しているので緑色なのですが9月には真っ赤な日もありました。

英語

UI、公式ドキュメント、公式GitHubプロジェクト、公式サポートサイトは全て英語です。 ググればだいたい Qiita がヒットする、日本代理店のサポートを受けられるという環境に慣れており、 英語の技術情報に触れる機会に乏しい方にはつらいかもしれません。

オンプレ版からの移行はハード

これは他のトピックからみれば人を選ぶ狭いものですが、オンプレ版 (Azure DevOps Server または Team Foundation Server) からの移行はとてもハードです。 公式の移行ツールはあります。だから、「移行元と移行先情報を入力してボタン1つ押せば終わりっしょ」と思ったら大間違いです。 移行方法を解説した動画の再生時間は70分もあります。 Microsoft SQL Server, Azure Storage, Azure Active Directory の利用経験があればよし、なければ苦戦するはずです。

docs.microsoft.com

Boards は慣れるまでの鬼門

Repos は特にドキュメントを読まなくても、Git さえ使ったことがあれば試しているうちに慣れると思います。 Boards は別です。Work item を作るだけでも複数の方法があるので迷います。 特に最初にチームのルールを決める人はかなり独自の概念を理解する労力を必要とするでしょう。 例えば公式ドキュメントにある Choose a process というページは Boards を理解する上でトップクラスに重要であり、以前に解説を書きました。 masskaneko.hatenablog.com

docs.microsoft.com

API

Azure DevOps ではたくさんの API がサポートされており、ライブラリもあります。API のサンプルコードもあります。 私は PythonAPI ライブラリを使っています。 ただし、すべての API についてサンプルコードがあるわけではありません。 引数に何を入れればよいかわからない API に直面することもあります。 Stackoverflow を探せば API ライブラリを使うコードが出てくることがあります。 無ければライブラリのコードを読む必要があります。 これは Azure DevOps 特有の話ではないと思いますが、そういったプロセスに慣れていない方にとっては意外にしんどいものとなるでしょう。

docs.microsoft.com

github.com

github.com

stackoverflow.com

継続的なアップデート

3週間に1度というアップデート頻度は早く、自分でアップデートしなくてよい恩恵はとても大きいと感じています。 個別の OSS を組み合わせてセルフホストしなくてよかったと本当に思います。

以前に意外とこの機能がない、というものをまとめた記事を書きましたが、 この中にあるもので現在は実装されたものがいくつかあります。 masskaneko.hatenablog.com

とはいえ、自分達が欲しい機能からどんどん実装されるわけではありません。 Feature Timeline にはこれから実装予定の機能がまとめられています。ここにあればラッキー。 なければ Developer Community で訴えてゆくしかありません。 欲しい機能を検索し、あれば最低でも +1 を押し、できればなぜ欲しいかをコメントする積極性が必要だと思います。 本アドベントカレンダー4日目の記事(Azure DevOpsへ機能要望のTIPS)が参考になるでしょう。

docs.microsoft.com

https://developercommunity.visualstudio.com/spaces/21/index.htmldevelopercommunity.visualstudio.com

kkamegawa.hatenablog.jp

TFSUG に入って!

Azure DevOps (旧 Team Foundation Server を含む) のコミュニティとして TFSUG というものがあります。 私は同種のコミュニティとして Redmine Tokyo が思い浮かぶのですが、 比べると人数も勢いも TFSUG は小さいものです。だから使っている方々、興味ある方々、入って!そして私を助けて!(私も助けようとします) 一緒に楽しめる仲間が増えますように!以上で~す

Connpass や Slack のリンク、会則などもろもろは Azure DevOps のパブリックプロジェクトにあります。 https://dev.azure.com/tfsug/tfsuginfo

あの日々はどのくらいアジャイルだったのだろうか

10年ほど前に、うまくいったと思えるソフトウェア開発の経験があって、今もときどき思い返すことがあります。 そして、それは ある程度アジャイルだった のではないかと思っています。うまくいった例の原体験とも言えるものです。

https://twitter.com/masskaneko/status/3102383231991808

2010年11月13日 @masskaneko
いまのチームにはアジャイル開発について知ってる人は誰もいない。けど、週単位の活動と軌道修正はイテレーションそのものだし、実装できるところからどんどん進めていく。

ある程度アジャイルだった という言い方をすると、アジャイルなのか、そうじゃないのかと疑問を持つ方がいるかもしれません。 しかし、アジャイルか否かという考え方はナンセンスで、どのくらいアジャイル という見方をすることが適切と常々考えていました。 これについて調べたところ以下の優れた記事を見つけました。

flxy.jp

記事にはこう書かれています。

つまり形容詞であるアジャイルはゼロイチにはならず、アジャイルであるアジャイルではないという二元論のような考え方はそもそも存在しないということです。 あくまで度合いの話であって、よりアジャイルか、あまりアジャイルじゃないという見方をすることも大切です。

この記事では、なぜ私の原体験がある程度アジャイルだったと思うのか、どの程度なのか、原体験の記憶があるうちに記しておくことにします。 程度を語るには尺度が必要ですが、アジャイルの程度、アジャイルらしさについて定めている文献を知りません。そこで、12の原則 をよりどころにし、順にひも解いてゆくことにします。

顧客満足を最優先し、価値のあるソフトウェアを早く継続的に提供します。

プロダクトはカーエレクトロニクスデバイスで、ビジネス形態は BtoBtoC だったので、顧客には企業とユーザーの2種類がいました。 どちらの顧客についても顧客満足を最優先していたかは覚えがありません。 少なくとも、開発者である自分たちがユーザーになるデバイスだったので、自分たちから見て役立つものを作ることは心がけていました。

また、1週間のイテレーションで内部リリースし、2週間~1か月で toB にリリースしていたので、"早く継続的に" については部分的に当てはまると思います。

要求の変更はたとえ開発の後期であっても歓迎します。変化を味方につけることによって、お客様の競争力を引き上げます。

特に歓迎はしませんが、耐えられはしたかという感触です。 私を含めチームの何人かは、既存の要求、アーキテクチャ、コードの関係をよく理解していましたし、何のために何のコードが書かれたかというトレーサビリティの情報は全てではありませんが Trac Lightning に蓄積がありました。

また、ユニットテストレベルに限定ではありますが、テストが書かれたプロダクトコードの割合はファイル数について70%以上、テストが書かれたプロダクトコードのブランチカバレッジは90%以上、テスト設計はデシジョンテーブルで行ってテストコードの説明を Doxygen で記述していました。

ですから、要求の変更に対して、既に実現した要求のうち関連するものを見つけることは、その何人かの暗黙知に頼ればできましたし、ユニットテストが普及していたので耐えられました。 ただし、歓迎はしません。

動くソフトウェアを、2-3週間から2-3ヶ月というできるだけ短い時間間隔でリリースします。

1週間のイテレーションで内部リリースし、2週間~1か月で toB にリリースしていたので、当てはまると思います。

ビジネス側の人と開発者は、プロジェクトを通して日々一緒に働かなければなりません。

これはわかりません。ビジネス側の人と開発者は違うのでしょうか。 プロダクトは、作られ、ユーザーに使われて役に立ち、ユーザーが価値に対して金銭を払い、ビジネスが成立します。 あるいは、ユーザーが価値があると期待して金銭を払った後、プロダクトはユーザーに使われて役に立ちます。

これを考慮すると、プロダクトの提供組織には、作ることに責任を持つ人、役に立つことに責任を持つ人、儲かることに責任を持つ人がいると分けることができます。 そして、開発者は作る人です。ビジネス側の人とは儲かることに責任を持つ人でしょうか。だとすると、一緒には働いていませんでした。 儲かることに責任を持つ人と接することはまれでした。

意欲に満ちた人々を集めてプロジェクトを構成します。環境と支援を与え仕事が無事終わるまで彼らを信頼します。

これはわかりません。 ある程度アジャイルであったと思う日々に登場するメンバーは、その日々が始まるときに集められたわけではありません。 意欲について語ることはありませんでしたので、何らかの意欲があったのかもしれませんが、それを知る由はありませんでした。

メンバーの担う仕事が無事終わるような環境と支援が十分だったのかはわかりません。 一人一台実機を持っていて、いつでもテストできたのは実は良かったのかもしれませんね。 他の組み込みシステム開発の現場を聞くと、一人一台なんて無い場合を聞きますので。

そして信頼していたのかというと、どうでしょう。 疑っていた覚えはありません。 疑うのは欠陥やプロジェクトリスクであって、人を疑っていた覚えはないのです。

情報を伝えるもっとも効率的で効果的な方法はフェイス・トゥ・フェイスで話をすることです。

これはうなずけます。 オンラインのコミュニケーション機会はメール、チケット、そして今は懐かしき IP Messenger。 フェイス・トゥ・フェイスの機会は、公式には週に1回のマネジメント会議と不定期なレビューがあり、そのほか雑談を含め非公式なものが沢山ありました。

ソフトウェア開発者がテスト担当者にバグを再現するコツを聞くことはよくありました。 チケットに書かれた再現手順を行っても再現できないときは、毎回テスト担当者に直接聞いたものです。

ソフトウェア開発者は測定器の使い方や基板のことがわからなければ、すぐ近くにいるハードウェア開発者に質問することができました。 逆に、ソフトウェアの動作として気になっていることを聞かれて設計を説明することもありました。

難しいバグを手分けして調査したり、要求の実現方法が複数考えられるときに分担するとき、どう動いたかを IP Messenger で簡単に伝え、 それだけで分からなければ相手の席まで行って画面やログを見ることもありました。

フェイス・トゥ・フェイスで話をすることが効果的な状況とは例えばこれらだと思います。 オンラインで伝えられることを基にし、それだけで不足であれば、気兼ねなく直接伝える・質問することができていました。

動くソフトウェアこそが進捗の最も重要な尺度です。

これはまさしくそうでした。 一週間のイテレーションで新しい振る舞いを開発してテストできたかをマネジメント会議で確認していました。

設計書はイテレーションでも書きますが、それはそのイテレーションをこなすための記述に留めており、 数か月、数年先のための包括的な記述は後でまとめて書きました。 もう少し正確に言えば、イテレーション内で書く設計書の実態は9割以上UMLの図で、文章はほとんどありません。 また、イテレーションの中で行う手動でのテストケースは典型的なもののみ記し、ほとんど文書化しませんでした。 言い換えれば、イテレーション内の実機手動テストで文書化していたのはスモークテストのみなのです。

テスト結果、プロダクトコード、設計書(実態はUML) の順に進捗として重要でした。

アジャイル・プロセスは持続可能な開発を促進します。一定のペースを継続的に維持できるようにしなければなりません。

この原則にも沿っていたと思います。 イテレーションは1週間(5営業日)を守っていました。ときに7営業日、10営業日になるということはありませんでした。

ただ、ストーリーポイントやサイクルタイムという数値は使っていないので、 1イテレーションでどれだけの仕事量をこなせたのかはわかりません。 おそらくチームの誰も、ストーリーポイント、サイクルタイム、それどころかイテレーションという用語さえも知らなかったでしょう。

技術的卓越性と優れた設計に対する不断の注意が機敏さを高めます。

技術的卓越性については思い当たるところがありません。 優れた設計については、それを高い保守性と解釈すれば思い当たるところがあります。

レビューから察するに、保守性を高めることを心掛けていた開発者が何人かいました。 その方法ではテストを書きにくくなってしまう、密結合になってしまう、似た処理が重複してしまう、といった意見が出てくるのです。 いくつか先のイテレーションで実現予定の項目を考慮してインターフェースやデータ構造を決める意見もありました。

そういった意見を出さず、それはどちらでも良いと公言する、保守性に頓着の無さそうな開発者もいました。 そう大まかに分けたときにどちらが多かったのかはわかりません。

私はどのイテレーションで何を実現するか計画し、イテレーション内で設計書を書き、自身もコードを書く立場で、保守性に頓着を持っていました。 もしこのポジションが優れた設計に対して無頓着であったら、いくつか先のイテレーションで進捗が停滞してしまったのではないでしょうか。

シンプルさ(ムダなく作れる量を最大限にすること)が本質です。

要求については少しは沿っていたと思います。 要求同士の依存関係を考慮し、ベースとなるよりシンプルな要求から実現する計画を立て、イテレーティブに実現していきました。 ただ、OEMの要望、互換性維持のために開発者からは不要に思える要求を実現することもまれにありました。

コードについて、私が直接書く範囲ではいくらかシンプルになりましたが、コードベース全体として理想には遠かった覚えがあります。 静的解析ツールで無駄を見つけて消すことは全員でやりましたが、全員で取り組んだのはそれくらいだったでしょうか。

最良のアーキテクチャ・要求・設計は、自己組織的なチームから生み出されます。

これは12の原則のうち沿っているかの判断が最も難しいものです。 エラスティックリーダーシップやチームギークを斜め読みした程度の頭には荷が重いのですが、いくつか自己組織化の要素が思い当たります。

  • 開発者は全員実機を持っており、手動テストができる環境がありました。実機のテストはテスト担当者だけに任せということはありませんでした。
  • 多くのメンバーは自動車(開発対象のプロダクトが搭載される環境)を運転するため、自分がユーザーならこれはうれしい、許容できないという判断をすることができます。
  • 一部のメンバーは、他者が担当しているチケットに対して助言や関連情報を書き込んでいた覚えがあります。例えば、「●●APIを使えばできそうです」「何番と同じ原因ではないでしょうか?」など。
  • 多くの開発者は、バグの原因を調べる際に他の開発者の担当部分も調べ、バグチケットの担当者を変更する際に推定原因をコメントします。
  • マネージャー(元開発者)は、低頻度ではあるものの、コードや設計書を見て助言をすることがあります。

逆に、自己組織化とは遠いと考えられる要素もあります。

  • プロダクトの個々の振る舞いについて1ユーザーとしての是非を判断できるものの、プロダクト全体の未来を考えることはない
  • 新しい価値の考案はだいたい企画部門やOEM任せで、要求獲得は一部の開発者のみ関わる。大半のメンバーにとって要求・価値とは他人が定義するもの。その是非の判断はできても定義には関わらない。

ここを深堀りするには12の原則のようなよりどころ、フレームワークが必要です。 本文では以上の思い付きに留めておきます。

チームがもっと効率を高めることができるかを定期的に振り返り、それに基づいて自分たちのやり方を最適に調整します。

最後の原則です。 ハードウェアプロダクトとして市場に出した際は振り返りをしますが、スプリントレトロスペクティブに相当する頻度にはほど遠いものです。 イテレーション毎に開発チーム全員が参加するマネジメント会議の議題は計画と進捗であり、振り返りはしません。 「来週からこうしてみない?」という小さくて頻度の高い改善はあったのかもしれませんが、10年前の小さなことはさすがに覚えていません。 ツールと手法を採用したきっかけなら覚えています。プロダクトを市場に出した後の振り返りばかりではありません。

  • チケット管理ツール
    • 他のチームが使って良い評判を聞き、新製品開発のタイミングで採用
  • UMLモデリングツール
    • 誰も使えって言ってないのにいつの間にか普及してた (ただし使う図は一部)
  • ユニットテスティングフレームワーク
    • 市場に出した後の振り返りで手動なんてやってられないという結論に
  • 静的解析ツール
    • 最初は他のチームが診断してくれた。良かったので以後自主運用。
  • 大きなリファクタリング
    • 負債に耐えかねた私が静的解析ツールのメトリクスとバグチケットの相関を示して実施決定
  • イテレーティブプロセス
    • 顧客企業に2週間~1か月毎に出すには毎週作ってテストという結論に

おわりに

各原則にどれだけ沿っていたか、◎、〇、△、×で大まかにまとめました。

主観評価 主観評価 原則文面
まぁそうっすね 顧客満足を最優先し、価値のあるソフトウェアを早く継続的に提供します。
なくはない 要求の変更はたとえ開発の後期であっても歓迎します。変化を味方につけることによって、お客様の競争力を引き上げます。
せやな 動くソフトウェアを、2-3週間から2-3ヶ月というできるだけ短い時間間隔でリリースします。
× そうでもない ビジネス側の人と開発者は、プロジェクトを通して日々一緒に働かなければなりません。
× ちがうかなあ 意欲に満ちた人々を集めてプロジェクトを構成します。環境と支援を与え仕事が無事終わるまで彼らを信頼します。
そうねぇ 情報を伝えるもっとも効率的で効果的な方法はフェイス・トゥ・フェイスで話をすることです。
これや! 動くソフトウェアこそが進捗の最も重要な尺度です。
そうね アジャイル・プロセスは持続可能な開発を促進します。一定のペースを継続的に維持できるようにしなければなりません。
さぁね 技術的卓越性と優れた設計に対する不断の注意が機敏さを高めます。
ちょっとは? シンプルさ(ムダなく作れる量を最大限にすること)が本質です。
はて… 最良のアーキテクチャ・要求・設計は、自己組織的なチームから生み出されます。
× そうでもない チームがもっと効率を高めることができるかを定期的に振り返り、それに基づいて自分たちのやり方を最適に調整します。

あの日々はどのくらいアジャイルだったのだろうか。

誰もアジャイルと言ってなかったけれども、ある程度アジャイルだったのではないだろうか。

10年前の懐古はここまで。今は2020年。未来を見よう。

紹介 - How Microsoft is modernizing its internal engineering processes

先日の Microsoft Build にて Microsoft のエンジニアリングを知るセッションがあったのですが眠くて逃してしまいました。

Expert Q&A: Modernizing Microsoft’s Internal Engineering Practices

あーあ逃しちゃった。他に似たような講演があったりしないだろうかと思って探して出てきたのがこれ。

www.youtube.com

とてもいい内容だったのですが、本稿執筆現在で50回しか再生されていません。 そこで、私がかいつまんだ内容を紹介することにしました。

Core Service Engineering and Operations (CSEO)

  • Core Service Engineering and Operations (CSEO) は Microsoft 内部の IT 横断的な部門であり、法務、人事、財務、営業、調達などの縦割り部門や、エンドユーザー向けサービスの全てを支えている。3年前までは Microsoft I.T. と呼んでいた。
  • CSEO とその影響がどれだけ大きいかを示す数字として次のものがある
    • エンジニアとプログラムマネージャー (フルタイム) 5500人
    • Git リポジトリ数 3500
    • 1日あたりのコミット数 66000
    • 1日あたりのビルド数 2800
    • ビルドあたりの平均所要時間 16分
    • 1日あたりの市場リリース回数 640
    • Azure DevOps アカウント数 1 (訳注:single account, single project と言っているが single organization が正しいと思われる)

昔、現在、これから

  • 2017年までは…講演者の予想では、60-70% のエンジニアはアウトソースで、フルタイムエンジニアは 30%。それぞれの縦割りビジネス組織では約500ものオンプレ版 Team Foundation Server が使用され、互いの情報を見ることは不可能だった。複数の組織にまたがる問題のトラッキングは難しかった。それぞれの組織が似たようなツールを作ってしまうこともあった。それぞれの組織が開発したプロダクトに対して UI の統一性を持たせることも困難だった。
  • CSEO が生まれ、2020年現在は…約500の Team Foundation Server を1つの Azure DevOps に集約した。Microsoft に何のサービスがあるか、インシデントが何か、各サービスの稼働状況はどうなのかといった情報は集約された。ユーザーからどんなフィードバックがあり、それらのフィードバックを分析した結果が何で、ビジネスとエンジニアリングの計画にどう活かされたのか、わかるようになった。
  • このようなモダナイジングは道半ばであり、これからは…新たなフィーチャーの実験的なリリース、インシデントの自動検出と自動修正をリリース前に行うこと、エンドツーエンドのビジネスモニタリング、シフトレフトと開発者のコーディング集中、Azure DevOps から GitHub へのリポジトリ移行をしようとしている。

何をモダナイズするのか、4つに分けた。

  • サービスの信頼性が悪く、インシデントの解決に時間がかかる。時間がかかるのは開発者のレスポンスが悪いのではなく、ユーザーが怒って教えてくれるまで気づかないから。データもメトリクスもないから。だから、サービスがどう動いているのかをモニタリングして問題を見つける筋肉質な仕組みを作り、問題があればレビューとポストモーテムを行ってシェアするという live site first の文化を育むことを目標とした。
  • サービスのセキュリティー、プライバシー、アクセシビリティのポリシーが一貫していない。主な原因は技術的負債。だから、技術的負債の解消に労力の20-40%を充てること、ポリシーに準拠しているかをパイプラインで確かめることを目標とした。
  • 新ビジネスの勢いが続かない。これはビジネス部門同士がサイロ化しているため。だから、会社レベルでのコードの共有、継続的リリースの仕組みを作り、良いツールやプラクティスを会社全体に浸透させ、似たような仕組みを各々が作る必要がないようにし、エンジニア同士がイノベーティブな活動をできることを目標とした。
  • UX が練られていない。UI に統一性がない。これは Microsoft の典型的な問題。だから、統一的で練られた UX のための標準デザインコンポーネントを開発するチームを立ち上げた。これも CSEO 内にある。

約700あるサービス、アプリケーションのポートフォリオクラウド

  • 一夜にしてではなく何年もかけて、いくつかのフェーズを経てクラウド化していった
  • もはや使われない 30% のサービスを廃止
  • 15% は SaaS を使ったもの、または SaaS に置き換えたもの
  • 50% は PaaS, IaaS へ
  • 5% はオンプレミスのまま

フィードバック駆動開発

  • 講演の最初で述べたように、ユーザーのフィードバックを得て、組織的に共有し、次の開発計画を決め、実装後にパイプラインが流れたときもトレーサブルになるようにしている。
  • この仕組みを実現するのも CSEO の仕事で、例えば Office のスマイルマークからフィードバックできる仕組みを実装している。
  • CSEO がこの機能を開発するときは Office 開発チームと協力し、まず Microsoft 内部で使えるものか評価した。
  • 真の変革はフィードバックをする仕組みの機能的な実現だけではなく文化の変革である。開発チームが、PMが、ユーザーのフィードバックを無視せずに向き合い、それらを発端として開発を駆動するようになることが必要である。

モダナイジングを通じて学んだこと

  • モダナイジングを成功させるには、まずビジョンを立て、メトリックに基づいて進めること。それにより、何がキーとなる問題なのか、何から手をつけるべきなのかがわかる。
  • 変革は、人、プロセス、技術の全てを通して達成できるものであるということ
  • 技術的負債を解消するための時間を確保することの必要性。新たなフィーチャーを継続的に投入してゆくためには、労力の 20-40% を技術的負債の解消に投資する必要がある。
  • 変革は、事業主体から顧客までのE2Eを通して考える機会となること
  • この変革という旅をゴールとメトリックに基づいた一貫したものにすることの必要性

紹介者所感

アメリカの大手IT企業 (GAFAM と言われる企業) の組織構造を示す風刺画では、内部組織同士が銃を向け合っているものが Microsoft でした。これを解消し、全体最適を進め、その立役者が CSEO という事業横断組織だったということなのだと解釈しました。 f:id:masskaneko:20200610224911p:plain
Funny Organizational Structure of Apple, Facebook, Google, Microsoft, Oracle and Amazon! [PIC] - JUYOFO

もともと 700 もあった Team Foundation Server が 1つの Azure DevOps organization になり、ユーザーからのフィードバックも中央に集め全社的に共有できるような技術的仕組みと文化を醸成したというストーリーは、InnerSource を思い起こすものでした。また、DevOps における Monitoring→Planning→Development→Integration→Deployment→Monitoring→… を正攻法で達成していると思いました。

Windows, Office, Visual Studio, Azure など、従来はバラバラだったのであろう事業部門がビジョンを共有して文化の変革ができた主要因は何だったのでしょうね。従来の Microsoft I.T. から CSEO に変わったときに何が起きたのか、バルマーからナデラに変わったことがどこまで関係するのか、強烈なトップダウンと幾多のボトムアップが融合したのか、他の事業部門など関係ないと思っていた組織と人々を導くインセンティブを人事制度として設計したのか。

これらも併せて読むと見えてきそうです。

www.microsoft.com

www.amazon.co.jp

Azure Boards に対する期待と実際の違い

Azure Boards は優れたツールだと思いますが、私が期待していた振る舞いと実際が違うという場合があります。 それらがどういうものなのかを列挙していきます。

該当する要望は Developer Community に載っている場合があります。実装予定の場合もあります。 これらの情報の所在がわかるものはリンクも載せておきます。 developercommunity.visualstudio.com

内容は2020年5月17日時点の Azure DevOps Services に対するもので、Azure DevOps Server に対するものではありません。

UIは英語のみ

Localization support for Team Services - Developer Community

「あれ?実はできない?」と最初に気づいたものがこれ。 難しい言葉は見当たらないので別に英語のみでもよいのですが、慣れない人はいそうに思えます。

同様にドキュメントにも日本語はありません。こっちのほうが量が多くてつらそう。 Azure DevOps documentation | Microsoft Docs

GitHub - MicrosoftDocs/azure-devops-docs: This repo is the home of the official Azure DevOps documentation for Microsoft. GitHub Issues filed in this repository should be for problems with the documentation.

デフォルトでは Work item の ID が表示されない

Global work item column options - Developer Community

「●●の実装って終わったんだっけ?」 「えーと、123番じゃなくて145番の方の●●だよ」 のように会話で Work item の IDを挙げることは日常的だと思うのですが、 どういうわけかデフォルトでは ID が表示されません。 設定で表示させることはできます。

f:id:masskaneko:20200517222344p:plain

f:id:masskaneko:20200517222451p:plain

ただし、この設定はチームごとであり、organization 全体には効きません。 ID表示をデフォルトとし、organization 全体の設定を可能としてほしいところです。 Developer Community に同様の要望があるのですが、支持数が少なく Closed となっています。

Work item の期限が近付いたときに知らせる機能がない

Due date notification - Developer Community

Ability to set reminders on work items - Developer Community

Due Date の何日前になって Done じゃなかったら Assigned To の人にメールするというリマインダー機能がありません。 Planner にさえあるのに Azure Boards には無いのか!?と思うのですが無いものは無い。 デイリースクラムをやってれば必要ないんじゃない?ということなのでしょうか。

Work item の特定のステータスを遷移させることができるのは特定の権限を持つユーザーだけ、という機能がない

Allow specifying state transitions when using inheritance process - Developer Community

例えば、Closed にできるのはプロダクトオーナーだけにしたいという場合には欲しい機能ではないでしょうか。

これは 2020 Q2 実装予定であり、二段階に分けてリリースされるそうです。

Dan Hellem [MSFT]  May 05 at 01:48 PM
phase 1, state to state restrictions will be available for preview in our current sprint rollout. About 1-2 weeks.

Phase 2, restrict transitions by group membership, is scheduled for 2 sprints out
Dan Hellem [MSFT] 4 days ago
Phase 1 of this feature is rolling out to Azure DevOps service over the next 5-8 days. If you are interested in being part of the private preview, please email your org name to dahellem@microsoft.com.

複数の階層化された Work item をコピーする機能がない。

Work item template or clone including subtasks - Developer Community

ある親に対して決まった子の Work items があって、それをテンプレートとしたい場合には欲しい機能だと思います。

これは 2020 Q2 実装予定だそうです

Work item から Pull Request を作る際にブランチ名を自動で決める機能がない

Set A Branch Names In Azure DevOps from work item - Developer Community

GitLab と JIRA+Bitbucket ではお馴染みの機能なのですが無いんです。 チームで決めた命名規則に自動的に沿うためには便利な機能だと思うのですが要望数は少ないです。

Work item を Markdown で編集できない

Add Markdown Support in Discussions - Developer Community

Repos では Markdown ファイル (.md) を扱えるのですが、Work item の編集では違います。 これも 意外と できないことです。 要望数は 170 を超えていますが、まだ New なので検討されていないようです。

Iteration の期間を GUI で設定する際、指定した期間を繰り返して設定することができない。

Auto create iterations or sprints - Developer Community

f:id:masskaneko:20200517225922p:plain

これをイテレーションごとに入力するのは面倒なんですよね。 カレンダーアプリだと繰り返しの予定を入れる機能があります。似た機能が欲しいところです。

Boards では Tag の色をつけられるが、他の画面ではつかない

Add colored tags to sprint board/backlog - Developer Community

Boards では Tag に色をつけられます。しかし、Work items, Backlogs, Sprints ではその色がつきません。 要望数は50を超えていますが未検討のようです。

ガントチャートがない

Gantt chart option in VSTS - Developer Community

機能も、実装予定もありません。

長期の計画を立てる機能としては Delivery Plans という拡張機能があります。 Work item 同士の依存関係を表現するには Depencency Tracker という拡張機能あります。

どうしてもガントチャートが欲しければ Microsoft Project を併用するのがよさそうです。

Test Case を Disabled にすることができない

Work item type Test Case cannot be disabled. Disabling test work item types is not allowed. - Developer Community

使わない Work item type は Disabled にしてユーザーが迷わないようにしておきたいところですが、Test Case だけは Disabled にできません。 なぜなのでしょうね。

プロセステンプレートの編集にて Work item type をコピーできない、名前変更もできない

プロセステンプレートで用意されている Work item type の名前だけ変更したい、一部のフィールドだけ変更したい場合に コピーと名前変更ができると手間が少なくて済むのですが、できません。

Created Date が編集可能

f:id:masskaneko:20200517232057p:plain

Work item の State を変更した日付は自動的に記録されます。 どういうわけか Work item を作成した日だけは編集可能であり、他の状態になった日は編集不可能です。 記録を改ざんできるのでダメだと思います。 まぁ、改ざんといっても History には残るので照合はできますが、それも面倒ですよね。

おわりに

以上、私から見た意外とできないこと集でした。 これらができなくても十分採用に値すると思いますが、組織によってはクリティカルかもしれませんね。

また、Developer Community では Microsoft の方々がユーザーの要望に反応してくれますが、 彼らから見て要望の理由がわからなかったり、最後のコメントから90日過ぎると棄却されます。 なので、まずは欲しい機能があったら Vote する、無かったら新規に作る、要望の理由を詳細に書くということが貢献になると思います。

Azure Boards 入門時の Choose a process

Azure DevOps のプロジェクトマネジメント機能である Azure Boards では、要求、バグ、タスクなどのソフトウェアエンジニアリングで扱う項目を Work item という単位で扱うことができます。 Work item に相当する情報は、類似のツールで "チケット", "Issue" と呼ばれることがあります。 Azure Boards では、何という Work item を設けるかを定義し、どの画面で表示するのかを決めることができます。 この設定を工夫することによって Azure Boards を使う組織全体の活動効率向上が期待できます。

Azure Boards 入門時には、概要を理解した後に設定の工夫をすることになるでしょう。 その際に、私が思う最も理解しておくべきことが Choose a process というコンセプトです。 このコンセプトは Microsoft のドキュメントに書かれています。 これを理解できないと、同種のツールの経験があっても Azure Boards のことは何もわからないのではないかと思えるほどのコンセプトです。

docs.microsoft.com

何を理解すべきか順に説明します。

必ず4つの中から1つを選ぶことを理解する

Basic, Agile, Scrum, CMMI という4つのプロセステンプレートが用意されています。 プロセステンプレートによって用意されている Work item type が異なります。 Work item には State(状態) と Reason (状態遷移理由) があり、状態遷移もプロセステンプレートによって異なります。 テンプレートの内容をカスタマイズしたい場合は、カスタマイズの元をこれら4つから選んで継承し、新たなプロセスを作ります。 それぞれのプロセステンプレートを継承して my-basic, my-agile, my-scrum, my-cmmi を作ると次のような画面になります。

f:id:masskaneko:20200512230832p:plain

テンプレートを使わずにゼロから定義することはできません。
設定したい Work item type の名前やワークフローなどが既に頭にある方は恐らく面食らうことでしょう。私はそうでした。 カスタマイズするにしても必ず4つの中から選ばないといけないのです。 なので、実現したいプロセスに最も近いプロセステンプレートを選択することが有用になります。

Backlog level と Work item type と Work item 表示画面の関係を理解する

4つのプロセステンプレートの名前は Basic, Agile, Scrum, CMMI です。 選ぶ際に理解しておくべきことは、Backlog level と Work item type と Work item 表示画面の関係だと思います。

例えば Agile プロセステンプレートの場合、Work item type 同士の階層関係は以下のようになっています。

f:id:masskaneko:20200512231219p:plain
azure boards: agile process template

Boards 画面では、Feature を親として User Story を子とした表示か、または、User Story を親として Task を子とした表示かを選ぶことができます。Backlog level は Portfolio backlog または Requirement backlog です。

Backlogs 画面では 、Feature, User Story, Task の3階層をツリー形式で表示することができます。子を省略して Feature のみ、User Story のみの表示にすることもできます。Backlog level は Portfolio backlog または Requirement backlog です。

Sprints 画面では、User Story を親、Task を子とした表示ができます。Backlog level は Iteration backlog です。

このように、Work item の階層と Work item type と Work item 表示画面には関係があります。

Backlog level には、最上位の Portfolio backlog, 中位の Requirement backlog, 最下位の Iteration backlog の3階層があります。 Backlog level を3より増やすことはできません。各Work item 表示画面において扱える最大の階層数は3です。 親子関係の設定自体は何階層でも設定できますが、それがわかるようには表示されないのです。 例えば、Task の子に Task を設定することはできますが、Boards 画面でも Backlogs 画面でも Sprints 画面でも Task 同士の親子関係は表現されません。 なので、実現しようとしているプロセスにおける Work item type の階層数が3におさまるようにする必要があります。

3つの Backlog level に何の Work item type を当てはめるかの決定が必要であることを理解する

4つのプロセステンプレートにおける各 Backlog level に当てはめられている Work item type の名前は以下のようになっています。

  • Basic では、Epic -> Issue -> Task
  • Agile では、Feature -> User Story -> Task
  • Scrum では、Feature -> Product Backlog Item -> Task
  • CMMI では、Feature -> Requirement -> Task

Backlog level と Work item type の関係は設定することができます。以下は Agile を継承した my-agile での例です。

f:id:masskaneko:20200513002750p:plain

どれかがそのまま使えそうか、名前、フィールド、状態から考えてみましょう。 どれかが使えそうならさして悩むことはありません。

しかし、アジャイルラクティスになじみがない場合は Epic, Feature, User Story, Product Backlog Item のどれもわからない、Requirement (要求) ならまだわかるが Requirement と呼ぶことは無いという場合もよくあるのではないでしょうか。 そのような場合は、Azure Boards を使おうとしている組織が扱う最上位の項目を何と呼ぶか、その項目と親とし Task を子とする項目を何と呼ぶか、組織における Task とは典型的には何かに向き合うことになると思います。 これは組織に Backlog level と Work item type という概念を初めて導入する機会になり得るため、熟慮すべき点だと思います。

また、Agile, Scrum, CMMI では Bug を Task と同列に扱うか、User Stocy, Product Backlog Item, Requirement と同列に扱うかを選択できます。 ここも一緒に考慮すべき点だと思います。 尚、この設定ではプロセステンプレートを設定する Organization Settings ではなく Project Settings にあり、迷いやすいのではないかと思います。

f:id:masskaneko:20200514083147p:plain

Epic, Feature などの用意された Work item type とは名前が異なるだけで内容自体は従来から組織で扱っているという場合は、既存の Work item type をリネームかコピーすればよいと思うかもしれません。 しかし、残念ながら Work item type のリネームとコピーは不可能です。 フィールドは既存のものと同じで名前が異なる Work item type を作るには、新規に Work item type を作り、同じフィールドを1つずつ作るしかないのです。

おわりに

以上、Azure Boards 入門時に、コンセプトの中から特に押さえておくべきと私が思う Choose a process について解説しました。 私は入門時に4つのテンプレートから必ず選ぶ、Backlog level は3階層までという点はなかなか理解できず苦労しました。 Azure Boards はググっても日本語情報が少ない印象です。 Azure Board を使い始める際に日本語で概要をつかむには以下の情報が有用だと思います。

qiita.com

kkamegawa.hatenablog.jp

合わせて本文も Azure Board 理解の一助となることを祈ります。

ヤンゴン旅行記

仕事でミャンマーヤンゴンへ行きました。わずか2泊3日でしたが面白かったので仕事以外のことを記します。 まさか初めての海外出張先がミャンマーとは、何があるかわからないものです。

成田からヤンゴン国際空港へ片道約7時間。台湾が中間地点ってところでしょうか。ひまです。入国審査では一言も交わしませんでした。驚きしかありません。 空港には日本円からミャンマーの通貨であるチャットに両替できる店と、クレジットカードを入れてチャットを手に入れられるキャッシングのATMがありました。

ホテルとデパートの入り口では額にかざす非接触の機器で体温を測られました。 COVID-19 を警戒してなのでしょうか。 スタッフからは "96, fine." と言われて、何ちゅう体温やねんと思いきや、何秒かしてファーレンハイトであることに気づきました。 アメリカならまだしも、ミャンマーで使われているとは意外でした。

ヤンゴンの道路は車でいっぱいでクラクションが鳴りまくっていました。どのような時に鳴らしているのか最初は全くわかりませんでしたが、どうやら追い越しをするときには長く鳴らし、自分の存在を示したいときには短く何度か鳴らすようです。 そして、歩行者用の信号が全くありません。渡るには多少の勇気が必要です。6車線の真ん中を車線に沿って平然と歩いたり、渋滞中のドライバーに水や食べ物を売り歩く商人もいました。 初日はそんな光景に非常に驚きましたが2日目には慣れました。

ヤンゴンでの移動は Grab というタクシーアプリを使いました。 行きたい場所を指定すると、現在地に近いタクシーがやってきます。 支払いは事前に登録したクレジットカードで払う仕組みです。 料金は乗車前に決まり、渋滞して遅くなっても変わらないのがいいところです。 10回近く使ったところ、おおむね5分以内にやってくるのも素晴らしい。神アプリ。

ミャンマー公用語ビルマ語。英語で書くと Burmese です。1日目に昼食をとった店のメニューはビルマ語で書かれていました。全く読めませんが、漢字のメニューがあったことと Google 翻訳の画像認識機能に助けられました。

2日目の昼食。てきとーに入った店で海鮮炒め麺を注文。これが旨味があってうまい。日本人万人向けと思える味でした。辛くありませんし。 辛いといえば、この写真にはありませんが、付け合わせのサラダがこの旅行の中で一番辛いものでした。伏兵すぎる。

ミャンマーで初のクラフトビールブルワリー Burbrit Brewery に行きました。 東南アジアのビールというと、シンハー、タイガーのような軽いものを思い浮かべていたのですがそうではなく、 ヴァイツェン、レッドエール、ポーターといった欧州の味でした。 店員の好意で醸造設備を少し見ることができました。メニューにはないフレーバーを試しているそうです。

こちらは Burbrit Brewery 近くの風景。首輪をしていない犬が何匹かいます。人懐っこい振る舞いでしたが、触れ合うのはやめておきました。

わずか2泊3日での印象ですが、ミャンマーの料理はタイ、中国、インドが合わさったような印象でした。 米の麺、長粒種の米、インドのようなカレー、わりと脂っこい炒め物、バクテーのような薬膳らしいスープ、海鮮由来の旨味、酸味と辛味のある薬味が特徴に思えました。

シュエダゴン・パゴダにも行ってみました。ヤンゴン市内にある巨大な寺院です。 外国人専用の受け付けで入場料10000チャットを払い、裸足で入場します。 敷地は広大で、どこもかしこも金色。日本の仏教とは全く違うようです。 場内には観光客だけではなく、地元の参拝者も多くいらっしゃるように見えました。 見回っている間にお経が延々とスピーカーから聞こえてきて、何かを再生しているのかと思いきや、生でした。 長いときは3日3晩通して読むそうです。それも修行なんでしょうか。

仏像や鐘などの展示物の横にはQRコード掲示されていて、専用アプリで読むと解説ビデオを見ることができました。 フィンランドで戦車を展示している施設にもこんなのがあったっけなぁ。

こちらの仏教では水曜日を2つに分けた八曜日があり、自分の生まれた八曜日が重要とのこと。 曜日ごとに像があり、自分の八曜日の像に水をかけるのが参拝の作法だそうです。 像のどこにかけるか、何回かけるか、など聞いてみましたが、テキトーでいいとのことです。テキトー。

撮ってもらいました。夜になったら絶景だろうことは想像がついていたのですが、帰りの飛行機の都合上やむなく帰りました。

何も予定が無ければ瞑想したかったなあ。