システム開発の現場でアジャイルを導入した(チーム改革を行なった)際に失敗したこと
私がPMをしていた自社サービスの開発現場ではウォーターフォールで進めていたのですが、進め方に限界があり、アジャイルを導入してみることになりました。
その際に多くの失敗をしたので、失敗談をここにまとめます。
アジャイルといいつつ、アジャイルの考えを一部取り入れようというチーム改革がメインの内容になります。
チーム改革を起こそうとしている方々に少しでも参考になればと思います。
施策内容と背景
チーム改革を行うに至った主な背景と施策は下記の通りです。
サービス全体の進め方や開発チームの改善、経験の浅いチームメンバーの育成のために改善フローをチームに取り入れた
コミュニケーションの時間が少ない、サービス全体の進め方や開発チームの改善、経験の浅いチームメンバーの育成が進まないなど、これらの課題を認識しておきながら、なかなか実行にうつせない体制でした。
これを解決するためにアジャイルの定期的な振り返りと改善の思想をチームに取り入れました。
具体的的には、振り返り、課題の特定、試作検討、試作の効果測定方法検討、実行のライフサイクルをチームメンバーで回しました。
graph TD; 振り返り-->課題の特定 課題の特定-->試作検討; 試作検討-->試作の効果測定方法検討 試作の効果測定方法検討-->実行 実行-->振り返り
システム上の大量のバグや課題がおざなりになっていたため、アジャイルチームを作った
大規模開発が多かったのと、スピード感を意識したスケジュールだったため、バグや課題が大量に残っている状態でした。
これを解決するために大規模開発するチームと定期的に細かい改修をするアジャイルチームに分割しました。
- 大規模機能開発チーム:大規模な機能を開発するチーム、大きなマイルストーンを作成し、そこに向かって開発を進める
- アジャイル開発チーム:細かい機能や、バグ改修をするチーム、1ヶ月1スプリントで進める
タスクを管理しきれていない状態だったため、タスク管理ツールを使って、そこにタスクを集約するようにした
タスク管理をスプレッドシートで管理していたのですが、そのスプレッドシートは一箇所ではなく、複数箇所に分割されていたり、稀にメモ帳ベースでの管理をしている状態でした。 流石に限界だったので、ガントチャートやボード管理が可能なタスク管理ツールを導入しました。
失敗したこと
上記や他にも細かい施策のおかげで、タスクやチーム全体の見える化、チームメンバーのソフトスキルが向上、コミュニケーション時間の改善など、多くの課題を改善することはできました。
しかし、どうしても施策として浸透しなかったものなど、当初想定していたものとは違う結果になったものがありました。
改善フローの思想が浸透しなかった
始めた当初は、お互いに感謝を言い合う時間ができたり、課題を共有し合う時間ができたり、具体的な施策や実行計画を立てることができたりとかなりいい調子で進みました。 途中振り返り会全体をメンバー中心に変更し、PMの発言回数を減らす体制に切り替えた際も、メンバーの性格の助けもあり、生産性の高い時間を作ることができました。 しかし、課題に対して、どうしても施策内容を検討しきれなかったり、具体的な効果測定をすることができなかったりと当初想定していたような仮説検証のライフサイクルをうまく回すことができませんでした。 その結果課題は残り続け、ただ感謝や反省だけする会になってしまいました。
アジャイル開発チームが自然消滅した
アジャイル開発チームは、開発以外の業務を兼任しているメンバーで構成されていることもあり、状況に応じて活動停止する運用にしていました。
チーム分割後、大規模機能開発が止まらず、アジャイル開発チームは他の業務に追われ、全く機能しませんでした。(動いたのは最初の2ヶ月程度)
そのままチームが停止したまま進み、結局スプリントというワードがプロジェクト内で聴くことがなくなり、アジャイル開発チームが自然消滅しました。
主な原因は、時間とスキルのリソース不足これに尽きます。
当初到底していたリソースをアジャイルに回すことができなかったこと、経験の浅いメンバーの技術スキルが上がらなかったこと、これらが大きな原因です。
特にメンバーのスキル不足に関しては、チームメンバー間の意識の違いが振り返り会の中で露呈したこともあり、なかなかみんなで頑張ろうというところまで意識改革に繋がらなかったこと、業務中のスキルアップの機会創出の限界、が課題として残りました。
まとめ
PMとしてのスキル不足、体制を作ることの難しさ、自分含めメンバー間の意識の違い、育成の難しさを痛感したチーム改革でした。
そして、今後チーム改革を起こす際は、下記の意識が必要とな学びました。
- コスト観点のリソースから試作を回すことができるか? (実行に移せる施策内容か)
- スキル観点のリソースから試作を回すことができるか?(メンバーがキャッチアップできるか、キャッチアップできるだけのスキルがあるか、その体制を作ることができるか)
- メンバー育成できるだけのスキルを自分が持っているか?(持っていなければ他のプロジェクトからリソースをひっぱてこれるか、育成するリソースを自分が割けれるか)
- 施策の内容は伝えきれているか(繰り返し伝えているか)
同じような課題を抱え、チーム改革を起こそうと考えている方々の参考になれれば幸いです。
Cloud Run + Cloud Build + Docker + Nextjsで環境変数を使う時の注意点
Cloud Run + Docker + Nextjsで環境変数を使う時の注意点をまとめます。
Cloud Runで設定できる環境変数は、コンテナ起動時に呼ばれるもの
ここで設定する環境変数は、コンテナ起動時に呼ばれるものなので、Nextjsでサーバーサイドのプログラムをビルドした時にはCloud Runで設定したものは使われません。
Nextjsでビルドした後のprocess.envの値の出力のされかた
nextjsで使うprocess.env
はサーバーサイドのプログラムの場合、ビルド時にenvの値がビルド後のプログラムに出力されます。
このようにenvファイルとnextjsを記述した場合、
HOGE=hoge
console.log(process.env.HOGE)
ビルドを実行すると下記のように出力されます。
console.log('hoge')
.envファイルは、dockerignoreで排除する
.dockerignoreでenvファイルを除外しないと、環境変数がenvファイルを参照してしまう場合があります。
envファイルをそのまま使いたい場合は良いのですが、そうでない場合は除外しましょう。
Go言語:ルーティング(gorilla)の優先順位について
Go言語のルーティング(gorilla)処理では、記載順序が重要です。
/hoge/{id※任意のID}
,/hoge/list
の二つのAPIを開発したい場合を例に説明します。
/hoge/{id※任意のID}
,/hoge/list
の順に実装した場合
下記のように実装して、/hoge/list
でリクエストを投げると、「{id}」が任意の文字という意味になるため、/hoge/{id}
が呼ばれます。
r.HandleFunc("/hoge/{id}", func(w http.ResponseWriter, r *http.Request) {}).Methods("GET")
r.HandleFunc("/hoge/list", func(w http.ResponseWriter, r *http.Request) {}).Methods("GET")
/hoge/list
,/hoge/{id※任意のID}
の順に実装した場合
/hoge/list
と/hoge/{id※任意のID}
を別のAPIとしたい場合は、下記のように実装しましょう。
これで/hoge/list
が先に呼ばれるようになります。
r.HandleFunc("/hoge/list", func(w http.ResponseWriter, r *http.Request) {}).Methods("GET")
r.HandleFunc("/hoge/{1}", func(w http.ResponseWriter, r *http.Request) {}).Methods("GET")
まとめ
ルーティングはプログラムの上から順番に決定していきます。
他のプログラミング言語でも同じようなことがあったので、ルーティング処理を書く際は注意が必要です。
Amazon:初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド
Go言語:ローカルでos.Getenv()を使う際のenvファイルの置き場所
ローカルでos.Getenv()を使う際、envファイルの置き場所で悩んだので、ここにメモを残します。
結論
mainファイルと同じ階層に置きましょう。 os.Getenv()で.envに記載した値が呼ばれるようになります。
cmd
∟main.go
∟.env
Amazon:初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド
Hugo:Markdownでコードブロックを使う時は、ちゃんと言語指定をしよう
Hugo:Markdownでコードブロックを使う時は、ちゃんと言語指定をしましょう。 言語指定しないとスタイルが適応されません。
スタイルを適応していない場合のデザイン
cd ..
スタイルを適応した場合のデザイン
cd ..
言語指定の方法
```python→コードブロックの「```」の横に言語を指定する
Hugoコマンド備忘録
ビルドの実行コマンド
hugo
ローカルサーバー立ち上げの実行コマンド
hugo server
下書き中の記事を公開したい場合は、–buildDrafts
をつけて実行する
hugo server –buildDrafts
Hugoで日本時間を扱う
HugoはデフォルトだとUTCを使っているため、投稿時間をUTC時間で記載する必要がある
date = 2023-03-15T11:00:00-07:00
この投稿時間をJSTにするためには、hugo.tomlに timeZone = "Asia/Tokyo"
を記載する必要がある。
Squarespaceにドメイン設定する時につまづいたこと
Squarespaceにホスト「www」のAレコードを設定しようとした時に、「このレコードを保存できませんでした」と表示された
原因は、デフォルトで設定されている「Squarespaceの規定値」を削除していなかったことでした。
削除したら無事にAレコードを設定することができました。
※余談:Squarespaceの規定値は、プリセットを追加からいつでも戻せます。
プロダクトライフサイクルで現在の市場と戦略を考える
プロダクトライフサイクル
プロダクトライフサイクルとは、1950年にアメリカの経済学者ジョエル・ディーンが提唱した市場分析フレームワーク
プロダクトが市場に出る〜利益がでる〜衰退していくまでの流れを以下の4つの段階に分類し、分類ごとに適切な戦略を検討する
- 導入機
- 成長期
- 成熟期
- 衰退期