Cloud Storage Transfer Serviceをコンソールで設定してS3からGCSへファイル転送してみる

Console を使ったデータ転送の作成と管理を見ながらコンソールで転送設定をやってみる

f:id:sonomirai:20201206223050p:plain
設定画面1

f:id:sonomirai:20201206223119p:plain
設定画面2

f:id:sonomirai:20201206223220p:plain
設定画面3

f:id:sonomirai:20201206223409p:plain
設定画面4

f:id:sonomirai:20201206223510p:plain
確認画面1

f:id:sonomirai:20201206223534p:plain
確認画面2

f:id:sonomirai:20201206223559p:plain
実行結果

転送できた。 一回設定すると、その後定期転送スケジュールを変更できない&一回スケジュールを無効化した後、再度有効化できず、再作成するしかないように見えた。
またジョブ作成時の選択項目に「毎日次の時刻に実行」しかなかったので、コンソールからは毎時での実行設定はできないように見えた。

GCSへのファイル格納を契機にCloud FunctionsでDataflowをキックする

はじめに

一つの前の記事で、GCSからBigQueryにファイルを送るDataflowを作った。
前の記事の状態では、Dataflowは手動で起動する必要があり、自動化ができていない。
そこで本記事では、GCSへのファイル格納を契機にDataflowをキックするCloud Functionsを作成する。
GCSからBigQueryへファイルを送るところにCloud Functionsを使う(≒Dataflowを使わない)方式もあるが、この方式だと大きいサイズのファイルを送る場合にCloud Functionsの実行時間の上限に引っかかるリスクがある。
そこで今回はCloud FunctionsからDataflowをキックする。
Dataflowの起動を自動化する方法は、Cloud Functionsの他にApp Engine, Cloud Composer, Compute Engineなど様々な方法があるが、サンプルが多い&学んだことが他にも応用しやすいということで、Cloud Functionsを使う。
ランタイムにはPython 3.8を使う。

Cloud Functionsの設定

f:id:sonomirai:20201031163254p:plain
Cloud Functions設定画面
f:id:sonomirai:20201031163316p:plain
ファンクション設定

from googleapiclient.discovery import build

def execute_dataflow_template(event, context):
    project = <PROJECT_ID>
    job = "trialJob"
    template = "gs://dataflow-templates/latest/GCS_Text_to_BigQuery"
    parameters = {
        "javascriptTextTransformFunctionName": "transform",
        "JSONPath": "gs://dataflow-template-trial/schema.json",
        "javascriptTextTransformGcsPath": "gs://dataflow-template-trial/function.js",
        "inputFilePattern": "gs://dataflow-template-trial/FinancialSample.csv",
        "outputTable": project + ":dataflow_dataset.FinancialSample",
        "bigQueryLoadingTemporaryDirectory": "gs://dataflow-template-trial/tmp",
    }

    dataflow = build("dataflow", "v1b3")
    request = (
        dataflow.projects()
        .templates()
        .launch(
            projectId=project,
            gcsPath=template,
            body={
                "jobName": job,
                "parameters": parameters,
            },
        )
    )

    response = request.execute()

動作確認

  • BigQueryのテーブルのデータを空にするとともに、GCSのFinancialSample.csvを削除する。
    この状態でFinancialSample.csvのアップロードを契機に、 BigQueryにデータが転送されることを確認する。
% gsutil cp ./FinancialSample.csv gs://dataflow-template-trial
Copying file://./FinancialSample.csv [Content-Type=text/csv]...
- [1 files][ 71.4 KiB/ 71.4 KiB]                                                
Operation completed over 1 objects/71.4 KiB.                                     

Dataflowを見るとジョブが走っているのが見えて、BigQueryにもデータが入る。Cloud Functionsのログは以下の通り。

f:id:sonomirai:20201031163843p:plain
Cloud Functionsのログ

おわりに

わかったこと

  • Cloud Functionsのファンクションの引数は、デフォルトで設定されている数(今回だと2つ)にしておかないといけない。引数を使っていなくても
  • Cloud FunctionsのGCSトリガーは、バケットまでしか設定できないので、そのままだと特定のファイルが作成されたタイミングで処理をキックする設定はできなそう

わからないこと

  • 接続を「内部トラフィックのみを許可」に設定する際は、認証の設定をしないといけない気がするが、そこはやっていない
  • Goでのファンクションの書き方(Pythonのサンプルが多かったからそっちでやった)

参考URL

DataflowのCloud Storage Text to BigQueryテンプレート(バッチ)を触ってみる

2020/10/31追記 DataflowのUDF(function.js)を行削除と現在日付をカラム追加する内容に更新


はじめに

GCSからBigQueryにCSVを送ってテーブルを作成するに当たり、DataflowのCloud Storage Text to BigQueryテンプレート(バッチ)が使えそうだったので触ってみた。
結論から言うと、ちょっと触った限りではDataflowのCloud Storage Text to BigQueryテンプレート(バッチ)の良さがわからなかったが、やったことを記録しておく。
なお私はこの記事を書いている時点ではDataflowのドキュメントをほぼ読んでおらず、Dataflowのことを全然分かっていない。
とりあえず動かしてみたという程度で、DataflowやGoogle提供のテンプレートについて誤解があるかもしれないので、その点に留意してほしい。
使ったファイルはGitHubリポジトリにまとめてある。

流れ

  • インプットとなるデータの準備
  • BigQueryセットアップ
  • GCSセットアップ
  • Dataflow実行

インプットとなるデータの準備

今回はMicrosoftが公開している財務サンプルデータを利用する。様々な型のデータがそれなりの量用意されているので、サンプルとしていい感じなので。Power BI 用の Excel の財務サンプル ブックのダウンロードからFinancial Sample.xlsxをダウンロードしてCSVに変換する。この時、フォーマットによっては価格欄に「$」が入ったり、3桁区切りの「,」が入って後々扱いづらいので注意する。Macのnumbersで編集する場合は、セルを全選択した上で、画面右のフォーマットのセルでデータフォーマットを数字にして、3桁区切りのチェックボックスをオフにすると良い。また1行目のカラム名の行も使わないので削除する。ファイル名はFinancialSample.csvとする。

BigQueryセットアップ

データセット作成

適当にデータセットを作成する。ここでデータセットはdataflow_datasetとしている。
入力

bq --location=asia-northeast1 mk \
--dataset \
--default_table_expiration 0 \
--default_partition_expiration 93600 \
--description "" \
<PROJECT_ID>:dataflow_dataset

出力

Dataset '<PROJECT_ID>:dataflow_dataset' successfully created.

スキーマ作成

スキーマ準備は面倒。とにかく手間かけず進めたいので、BigQueryのスキーマ自動検出機能を使ってスキーマを作成する。コマンド打つ時点でテーブルはなくても大丈夫。
入力

bq --location=asia-northeast1 load --autodetect \
--source_format=CSV \
<PROJECT_ID>:dataflow_dataset.FinancialSample \
~/Downloads/FinancialSample.csv

出力

Upload complete.
Waiting on bqjob_r1520ec4b3b8ef942_000001755d6471f2_1 ... (1s) Current status: DONE 

なおここで欲しいのはスキーマだけなので、スキーマ作成後にTRUNCATE TABLE dataflow_dataset.FinancialSample;でデータは削除しておく。 Cloud Storage Text to BigQueryテンプレートを利用するためには、BigQueryのスキーマを後述の2箇所で利用する必要があるため、自動検出されたスキーマJSON形式で出力する。
入力

bq show --schema --format=prettyjson dataflow_dataset.FinancialSample

出力

[
  {
    "mode": "NULLABLE",
    "name": "Segment",
    "type": "STRING"
  },
  {
    "mode": "NULLABLE",
    "name": "Country",
    "type": "STRING"
  },
〜中略〜
  {
    "mode": "NULLABLE",
    "name": "string_field_16",
    "type": "STRING"
  }
]

こうして出力したスキーマは以下2箇所で利用する。スキーマをどこで必要になるのかわかりづらくて混乱したので、ここで記しておく。詳細は後述。

  • GCSにスキーマ情報を格納して、Cloud Storage Text to BigQueryテンプレート利用時に指定する

  • Cloud Storage Text to BigQueryテンプレート利用時のUDF内でJSONのキーとして利用する

とりあえずこれでBigQUeryセットアップは終わり。

GCSセットアップ

バケット作成

dataflow-template-sandboxという名前でバケットを作成する。

コマンド

gsutil mb -p <PROJECT_ID> -c STANDARD -l ASIA-NORTHEAST1 -b on gs://dataflow-template-template

出力

Creating gs://dataflow-template-sandbox/...

ファイル格納

作成したバケットには以下を格納する。

  • BigQueryに突っ込むデータ。ここではFinancialSample.csvとする。これは作成済み
  • BigQueryのスキーマ。ここではschema.jsonとして、この後作成する
  • UDF用のJavaScript。ここではfunction.jsとして、この後作成する
  • DataflowのCloud Storage Text to BigQueryテンプレート(バッチ)実行時に吐き出される中間ファイル。Dataflow実行時にフォルダを指定するだけでよい。(そのディレクトリがなくても作ってくれる。)

BigQueryのスキーマ作成

先ほどBigQueryから出力したJSON形式のスキーマをBigQuery SchemaというJSONオブジェクトにする。(なぜ出力したスキーマがそのまま使えないのか。。。管理しづらい。。。という気はするが。)

{
  'BigQuery Schema': [
    {
      "mode": "NULLABLE",
      "name": "Segment",
      "type": "STRING"
    },
    {
      "mode": "NULLABLE",
      "name": "Country",
      "type": "STRING"
    },
  〜中略〜
    {
      "mode": "NULLABLE",
      "name": "string_field_16",
      "type": "STRING"
    }
  ]
}

UDF用のJavaScript作成

UDFでは、BigQueryに突っ込むCSVを、スキーマ名をキーとしたJSONに変換して返却する必要があるらしい。BigQueryにはCSVをそのままインポートする機能があるのに、なぜ途中でJSONに変換する必要があるのか。。。別にUDF内でちょっとデータ加工する分にはCSVのままでもいい気がするが。。。よくわからない。
CSVだとDateは1/1/14のフォーマットになっていてBigQueryに格納できないので、UDFの中で2014-1-1のフォーマットに変換しつつ、CSVJSONに変換していく。
また試しに、ContryがGermanyだったら行を削除する処理、string_field_16カラムに現在日付を設定する処理も追加する。(2020/10/31追記)

function transform(line) {
  var values = line.split(',');
  var obj = new Object();
  obj.Segment = values[0];
  obj.Country = values[1];
  obj.Product = values[2];
  obj.Discount_Band = values[3];
  obj.Units_Sold = values[4];
  obj.Manufacturing_Price = values[5];
  obj.Sale_Price = values[6];
  obj.Gross_Sales = values[7];
  obj.Discounts = values[8];
  obj._Sales = values[9];
  obj.COGS = values[10];
  obj.Profit = values[11];
  var date = values[12].split('/');
  obj.Date = '20' + date[2] + '-' + date[1] + '-' + date[0];
  obj.Month_Number = values[13];
  obj.Month_Name = values[14];
  obj.Year = values[15];
  var dt = new Date();
  var insert_day = dt.getFullYear() + '-' + (dt.getMonth()+1) + '-' + dt.getDate();
  obj.string_field_16 = insert_day;
  var jsonString = JSON.stringify(obj);
  if (obj.Country == "Germany") {
    return null
  }
  return jsonString;
}

GCSに格納するファイルの準備ができたので、FinancialSample.csvとschema.jsonとfunction.jsを格納する

gsutil cp ./FinancialSample.csv gs://dataflow-template-trial
gsutil cp ./schema.json gs://dataflow-template-trial
gsutil cp ./function.js gs://dataflow-template-trial

Dataflow実行

準備ができたので、Dataflowを実行する。
入力

gcloud dataflow jobs run trialJob \
    --gcs-location gs://dataflow-templates/latest/GCS_Text_to_BigQuery \
    --parameters \
javascriptTextTransformFunctionName=transform,\
JSONPath=gs://dataflow-template-trial/schema.json,\
javascriptTextTransformGcsPath=gs://dataflow-template-trial/function.js,\
inputFilePattern=gs://dataflow-template-trial/FinancialSample.csv,\
outputTable=<PROJECT_ID>:dataflow_dataset.FinancialSample,\
bigQueryLoadingTemporaryDirectory=gs://dataflow-template-trial/tmp --region=asia-northeast1

出力

createTime: '2020-10-25T14:54:52.699960Z'
currentStateTime: '1970-01-01T00:00:00Z'
id: 2020-10-25_07_54_50-9162729669340431769
location: asia-northeast1
name: trialJob
projectId: <PROJECT_ID>
startTime: '2020-10-25T14:54:52.699960Z'
type: JOB_TYPE_BATCH

CLIの戻り値だと成功/失敗はわからない?コンソールで成功していること、BigQueryに確かにデータが格納されていることを確認する。(BigQueryに挿入される順番はCSV通りの順番ではないっぽい)

f:id:sonomirai:20201026002751p:plain
dataflowのjob成功画面
f:id:sonomirai:20201031014327p:plain
BigQueryのプレビュー画面

おわりに

わかったこと

  • DataflowのCloud Storage Text to BigQueryテンプレート(バッチ)の動かし方
  • Dataflowのデバッグの仕方
  • Dataflowはコンソールだとできない操作方法が多いっぽいということ
  • DataflowのCloud Storage Text to BigQueryテンプレート(バッチ)で指定するJavaScriptのUDFは、BigQueryのUDFとは役割が違いそうなこと
  • GCS上のtmpバケットは処理がコケると残って、成功すると削除される
  • そもそもDataflowのCloud Storage Text to BigQueryテンプレート(バッチ)はβ版

わからなかったこと

  • Dataflowのジョブの操作方法(停止や更新など)
  • Dataflowのジョブ(バッチ)は、バッチということだけど時刻の設定箇所がわからなかった。そういう類のものではない?
  • GCSのデータが更新されたらどのタイミングでBigQueryのデータが更新されるのか?そもそも更新されるのか?更新時は追記されるのか?上書きされるのか?
  • Dataflow全般(DataflowのCloud Storage Text to BigQueryテンプレート(バッチ)を動かしたくらいではDataflowのことはわからないことがわかった笑)

参考サイト

クネビンフレームワークとステークホルダの期待値コントロール

9/14更新 9/11にScrum Masters Night!でこのブログをネタにディスカッションさせていただいたので、その内容を踏まえて全体的に改訂


はじめに

ソフトウェア開発が扱うのはクネビンフレームワークの煩雑系(Complicated)と複雑系(Complex)で、アジャイル複雑系に向くという話をよく聞くが、個人的には煩雑系もアジャイルでやればいいのでは?と思っていた。
しかし最近、ステークホルダの期待値コントロールという観点で考えると複雑系アジャイルを導入するより、煩雑系にアジャイルを導入する方が骨が折れるということに気づいたので、記事に残しておく。*1

スクラムの成果のステークホルダへの見え方

クネビンフレームワークの煩雑系と複雑系を雑に言い換えると、煩雑系は(どうやるかはさておき)やればできる領域、複雑系はやってみないとわからない領域と言い換えられると思っている。
アジャイルだと開始時点で「いつまでに、何を」は約束できず、やりながら徐々に見積の精度を高めていくので、例えば半年とか一年とか、ステークホルダが気にするタイミングでのアウトプットとしては、「(優先順位が高い順に実装した)いくつかの動く機能と今よりも精度のいい見積」ということになる。
スクラムを導入する際には、あるタイムボックスで見たときのスクラムの成果が「(優先順位が高い順に実装した)いくつかの動く機能と今よりも精度のいい見積」になることをステークホルダに説明し、納得してもらう必要がある。ではこの情報が、複雑系のステークホルダと煩雑系のステークホルダの目にどのように映るかを考えてみる。

複雑系のステークホルダの場合

スクラムを一定期間実践すると得られる成果(優先順位が高い順に実装した)いくつかの動く機能と今よりも精度のいい見積複雑系のステークホルダの目にどう映るかというと、これは価値ある情報として映るものと思われる。なぜならやってみないとわからない領域について、継続するにせよ撤退するにせよ、半年後には何らかのジャッジができるようになるからだ。なので複雑系の場合、ステークホルダへの説明は割とすんなりいくものと思われる。

煩雑系のステークホルダの場合

次に煩雑系の場合を考える。複雑系のステークホルダには価値があった(優先順位が高い順に実装した)いくつかの動く機能と今よりも精度のいい見積が、煩雑系のステークホルダにとって同じように価値を持つかというと、そうではないと思う。
なぜなら煩雑系のステークホルダは、煩雑系のプロダクトはやればできることはわかっているので、あとはいつ完成するかだけが知りたいと思っているからだ。
(優先順位が高い順に実装した)いくつかの動く機能と今よりも精度のいい見積は、ともすれば未完成の機能と、開発初期には出てこなかったのに今更出てきたスケジュールに見えてしまい、いつ完成するのかを気にしているステークホルダからすると、期待外れと思えてしまうのだ。

煩雑系にスクラムを導入するためにはどうすればよいか

上記で説明した通り、一定期間後の成果物という観点だけでステークホルダと話をすると、スクラムを導入するメリットがステークホルダには伝わらないので、スクラムを導入する側としては、スクラムの導入により、従来型の開発プロセスと何が変わるかをステークホルダに説明し、納得してもらう必要がある。例えばスクラム導入によるステークホルダのメリットには以下がある。

  • 開発後期でも追加要望を出すことができる
  • 紙の進捗資料ではなく動くモノとして進捗を確認できる

おわりに

本記事では、複雑系アジャイルを導入するより、煩雑系にアジャイルを導入する方が骨が折れる理由として、煩雑系のステークホルダにとっては、スクラムの成果である「(優先順位が高い順に実装した)いくつかの動く機能と今よりも精度のいい見積」の価値が感じづらいこと、そのような場合にスクラムを導入するためには、ステークホルダにどんな説明をする必要があるかを述べた。

*1:実際のところあるプロダクトが煩雑系か複雑系かなんてわからないので、スクラムチームおよびステークホルダが対象とするプロダクトをどのように捉えているかが重要となる。この記事は、スクラムチームおよびステークホルダの間で、対象とするプロダクトが煩雑系と複雑系のどちらに該当するかは、共通認識が持てていることを前提として記載している。

TDDワイワイ会その32参加レポート

はじめに

3/1にTDD+モブプログラミングでワイワイする会 その32に参加してきた。 スクラムマスターとして案件に参画することが多いが、XPの開発プラクティスの実践経験に乏しく困ることがあったので、手を動かして実感を掴みたいと思ったのが参加の動機。 この記事では「イベントの流れ」、「モブプロについての学び」、「TDDについての学び」の3項目で、イベントをふりかえる。

イベントの流れ

  • 最初にイベント全体の説明があった。
    f:id:sonomirai:20200303205349j:plain
    当日の様子(@miholovesqのTwitterから拝借)
  • この日の参加者は12名だったので、4人チームを3つ作った。得意な言語でチーム分けするのかと思っていたが、そういうわけではなかった。
  • チームごとに別れてから改めて自己紹介をして、今回使う言語と誰のノートPCを使うかを決めた。
  • 次に使用する言語の選択。メンバの得意な言語はRubyJavaだったが、みんなが知らない言語の方がモブプロ の力を体感できるということで、使用する言語にはあえてPythonを選んだ。(テストフレームワークはpytest)
  • 最後にコーディングの題材をcyber-dojoから選んだ。
    • 前半戦はFizzBuzzをやった。実際に私のチームがやった軌跡はここから見れる。(いつまで見れるのだろう。ずっと見れるのかな?)
    • 後半戦はHally Potterという題材をやった。Hally Potterはあまり関係なくて、シリーズ物の書籍を複数冊購入した際の最適な割引率を算出する問題。チームの軌跡はここ。難しかった。とりあえず実装は始めたものの途中で行き詰まって、ホワイトボードで実装イメージについてディスカッションして、コーディングを再開したあたりでタイムアップになってしまった。
  • 最後にイベント全体をふりかえって、片付けをして、イベントは終了となった。

モブプロ についての学び

  • 楽しい
    • スキル面で不安があって、実際足を引っ張ってしまう場面もあったが、モブプロだとフォローしてもらいつつ進めることができるので、いたたまれない想いはしなかった。それよりも「楽しい」の気持ちの方がずっと大きい。
    • TDDワイワイ会は「テストが落ちると思って落ちた時」「テストが通ると思って通った時」はワーと拍手をすることになっていて、これも大いに場作りに貢献していた。
    • 逆に「テストが通ると思って落ちた時」はみんないっせいにガタッ!となってエラー原因の特定に努めた。この一体感。これはこれで楽しかった。
  • ドライバーはYouTuberのように声を出しながら手を動かすのが大事
  • 可能なら椅子は人数分+1つ用意するとよい
    • 人数分だと毎回ほかのメンバとの入れ替わりが発生してしまうため)
  • 可能ならノートPCは人数分+1つ用意するとよい
    • 他の人のPC触るのはけっこう心理的なハードルが高いことに気づいた。あと時間が経つとロックがかかってしまう。。。いちいち解除してもらうのもリズムを崩してしまう。
  • リモートでモブプロするときはVS CodeのLiveShare機能がけっこういい感じというのをメンバに教えていただいたので、今度使ってみたい
  • TDDワイワイ会のページにも貼ってあるMob Programming Startup Manualがモブプロの資料としてとても参考になった。

TDDについての学び

  • 事前にt_wadaさんのFizzBuzzを題材にしたTDDのライブコーディングの動画を見て「歩幅の調節」を知識として知ってはいたが、実感がなかったので、そこを体感できたのはとても良かった。今回は初対面のメンバでモブプロしたので丁寧にやったが、業務にTDDを取り入れて慣れてしまえば、基本は明白な実装を前提として実装を進めて良いのかなと思った。

  • すぐに実装イメージが合わないような難しい題材を扱う際、ホワイトボードを使った設計とTDDでの設計を、どうバランス取りながら進めるかというのは、難しい問題だと感じた。ここは経験を積んでバランス感覚を養うしかない気はするので、またTDDワイワイ会に参加して、"筋トレ"させてほしいと思った。

さいごに

イベント運営が大変な社会の状況の中、対策を講じた上でイベントを開催してくださった運営の皆様に感謝します。またぜひ参加したいと思います。

スクラム初心者お悩み相談参加レポート

はじめに

1/28(火)にアジャイルチームを支える会主催の「スクラム初心者お悩み相談」に参加した。(募集サイト
悩み相談は、参加者の持ち寄ったスクラムの悩み事について、標準5分〜最大20分で対話するという形式だった。
参加者は8名だった。冒頭のアンケートでスクラム実践前の悩みを抱える3名、スクラム実践中の中身を抱える5名でグループに分かれた。そこへ各2名の相談員の方に参加いただき、計5名のグループと7名のグループで対話をした。
私はスクラム実践前の悩みを抱えるグループに参加した。対話の時間はおよそ1時間で、この間に5個くらいのトピックについて対話をした。
いずれの悩みも共感せざるを得ない悩みで、相談員の方のコメントもとても参考になった。
ここではその中から、私が一番聴きたかった、QAチームとの連携に関する悩み相談と相談結果を共有する。

f:id:sonomirai:20200129091914j:plain:w400
私が相談したQAチームとの連携についての悩み

悩み

上記のポストイットを説明する際に、口頭で説明した内容を補足すると、悩みは以下の通り。

相談結果

参加者の方、相談員の方と対話させていただき、自分の中では悩みは解消した。(とりあえず次の一歩を踏み出せそうという感触を持てた。)

対話した内容と、それを受けて考えたことをまとめると以下の通り。

  • 従来のQAチームが何をしているのかを理解することは次の一歩を踏み出すために大事なので、資料を展開してもらうなり、対話をする必要がある。
    • QAチームがウォーターフォール案件を見るときにどんな営みをしていたかは、スクラム案件には関係ない気がしており、資料の展開をしてもらう必要はないかと思っていたけど、ウォーターフォール案件のQAで何を担保しようとしていたかを理解することは非常に重要だと、対話を通じて考え直した。
  • QAチームのメンバ(例えばモチベーションの高い若手など)を自分たちの案件にステークホルダの位置付けでアサインしてもらい、一緒に品質保証に向けた取り組みを進めるのは効果的。(その後スクラム案件が拡大することを見越すと、試験項目の内容を見てもらったり、完了の定義を一緒に検討するのも良さそう。)
  • QAチームと話す際は、ウォーターフォール案件かスクラム案件かという観点で話す必要はない。「お客様に価値を早く提供するためには、どう連携できるか?」という観点で話をした方が良い。
    • 悩みのところに「スクラムの話をしていても品質の話は出てこない」と書いたけど、それは当たり前で、品質保証というもののはウォーターフォールスクラムかという案件特性とは関係なく守らねばならないものだからだ。なのでQAチームにスクラムの話をしてもあまり意味はない。それより、QAチームがクオリティゲートを設けていることで価値の提供速度が下がってしまうという課題を取り上げて、その課題をどう解決することができるかを話し合ったほうが建設的な議論ができるということだった。めちゃめちゃ納得した。
  • 早い段階で成果物を見せてもらうというのは、QAチームにとっても嫌な話ではない。最後の最後に品質の低い成果物を持ってこられて打つ手なし、となるよりは、早い段階で品質の低い成果物を見て早めにその旨をフィードバックをする営みをしたほうがお互いによい。こういった営みをする時、実はQAチーム側としては対応稼働は従来から増えない。それに対してスクラムチーム側は、QAチーム用の環境を構築してメンテする必要があるので、対応稼働は増えるので、そこはスクラムチームが頑張る。
    • このあたりも実践しないとわからない知見だと思う。教えていただけて大変有難かった。

悩み以外の対話内容

上記の悩みに関連して、調査する中で気になったことを2点伺ってみた。

スクラム案件が増えた際にQAチームがボトルネックになる懸念ついて

  • QAチームがスクラムチームに寄り添う(≒各スクラム案件に担当者をアサインしてサポートする)事例は素晴らしいと思うが、スクラム案件が増えると、QAチーム側がボトルネックになるというリスクはある?
    • スクラムチームが成熟して毎回安定した品質の成果物を提供することができるようになった結果、QAチームが「品質保証のために入り込む必要はない、スクラムチームの判断でリリースして問題ない」となった国内事例がある。
      • その事例を踏まえると、QAチームはスクラムチームの立ち上がりの際に寄り添ってサポートして、スクラムチームの十分な成熟を見届けて、QAチームのところから卒業させるような世界観がありうる?
        • これは結構な理想論で、従来型のQAチームがそこまで変われるかは難しいところ。QAチームの営みが従来の品質保証から発展して、QAトレーナーとしてスクラムチームの指導ができるところまで行かないと、この世界観は実現されない。

海外事例について

  • アジャイル関連の書籍を見ると、基本的にはスクラムチームがリリースの判断をすべきとある。「スクラムチームでリリースの判断ができる」というのは、海外だと元々QAを専門としていたメンバが開発チームの一員となっていて、品質保証に人一倍の責任を持っているから成り立っているのではないか?と仮説を立てたのだが、海外事例などご存知か?
    • その側面もあるかもしれないが、大切なのはその場合でもリリース判断しているのは、QAの専門家ではなく、スクラムチームだということ。
      • 質問の背景として、日本の開発現場だと、チームにQAの専門家がいるのではなく、QAの組織が別にあり、そこがリリース判断に関与するので、日本の開発現場って、海外に比べて品質保証の意識が薄いのでは?という仮説を持っている。(この仮説が全くもって違うかもしれない。) そうした時に、品質保証について意識の薄いスクラムチームが「アジャイルだとクオリティゲートは設けず、チームでリリース判断するんですよー。それが普通ですよー。」みたいな形で上位層を言いくるめてリリースして、結果として故障が出て、上位層が「アジャイル駄目じゃん」みたいになってしまわないかという懸念があったので聞いてみた。 「アジャイルになってQAチームの役割は変われど、QAチーム自体はなくならないと思う。」とおっしゃっていた相談員の方もおり、自分もそんな気がした。

おわりに

品質保証という難しい悩みについて、相談会でここまで色々な学びを得られるとは思っていなかったので、本当に有難かった。悩み相談にのってくださった相談員、参加者の皆様、ありがとうございました。

アジャイルマインド・インストレーション体験セミナー参加レポート

有償ワークショップのダイジェスト版を無料で体験できる太っ腹なセミナーが開催されるということで、1月24日にグラーツ社主催のアジャイルマインド・インストレーション体験セミナーに参加してきた。(募集サイト
このセミナーは13:30-16:30の半日のセミナーで、前半講演、後半ワークショップという構成だった。
参加者は15名くらいで、3〜4人のグループを4つ作ってワークショップに臨んだ。
参加者の属性は、SM経験者が半分くらい、PO, Dev経験者が数名、スクラム未経験者が2名くらい。
講演とワークショップの内容は以下の通り。

講演「アジャイルコーチと辿る価値と原則」(30分)

  • アジャイルソフトウェア開発宣言の4つの価値と12の原則、スクラムガイドの理論・価値基準・チームの紹介と、スクラムにおけるマネージャの役割の説明がメイン。
  • スクラムにおける"確約"を『スポーツ選手が「必ず勝ちます!」と試合前に宣言するようなイメージ』と説明していて、すごくいい説明だと思った。パクろう。
  • マネージャの説明はエッセンシャルスクラムとLeSSからの引用が多かった。マネージャとチーム間の権限委譲については、エッセンシャルスクラムに掲載の以下の表を参照しながら話すとスムーズとのこと。
    f:id:sonomirai:20200124210253p:plain
    Appeloによる7段階の権限レベルとその実例 (エッセンシャル スクラムより)
  • 組織にアジャイルを広める際には書籍「Fearless Change アジャイルに効く アイデアを組織に広めるための48のパターン」がとても参考になるとのことだった。読もう。
  • あと、昨年 技術書展で頒布された「アジャイルコーチからのアドバイス」についての言及もあった。読もう。500円だし。

ワークショップ「スクラム・ペルソナ・ロールプレイ」(120分)

  • 受講者がセミナ申し込み時のアンケートに記載した「アジャイルスクラムの困りごと」から各グループ1つテーマをピックアップし、そのテーマについてPO/SM/Devの視点で「問題への向き合い方」「対処」「予防」をディスカッションするというワークショップ。

  • 「ペルソナ」とある通り、架空のスクラムチームのペルソナを用意して、そのチームが受講者の挙げた「アジャイルスクラムの困りごと」に遭遇した場合にどう対処すべきかをディスカッションする。

  • ワークショップに当たって決まっていることはスクラムチームのペルソナのみで、スクラムチームが作るプロダクトのカテゴリやスクラムチームのロケーションといった細かい点については言及がなく、グループで仮定を置いてよいということで、以下の2点から丁度よく抽象化されているという印象を持った。

    • ロールプレイの設定と受講者の記載した「アジャイルスクラムの困りごと」がかち合ってディスカッションが進まないということもなさそう。
    • もしチームビルディングの一環でスクラムチームがこのロールプレイをやろうとした場合、ペルソナを設けていないとついつい自分たちのスクラムチームと重ねて個人攻撃をしてしまいそうだが、ペルソナを設けてあることで、自分たちのスクラムチームとは切り離してディスカッションをすることができそう。
  • 各グループの取り組む「困りごと」が、他のグループと被らないように決めたら、まず自分たちが取り上げた「困りごと」について30分ディスカッションし、PO/SM/Devの視点で「問題への向き合い方」「対処」「予防」をポストイットに書き出して、模造紙に貼る。模造紙は以下のような構造になる。

    PO SM Dev
    どう向き合うか
    どう対処するか
    どう予防するか
  • 次に隣のグループに移って、隣のチームが取り上げた「困りごと」について、20分ディスカッションする。(2回目以降は、前のグループが貼ったポストイットが残っているので、まずはそれを参照して、共感したらシールを貼った。)これを4チーム分繰り返した。

  • 今回選出された4つのディスカッションテーマと最終的な模像時の状態は以下の通り。

    f:id:sonomirai:20200124210433j:plain
    テーマ:個別最適の考え方が強く、全体最適の考え方を持ってチームが行動できていない
    f:id:sonomirai:20200124210625j:plain
    テーマ:品質とスピードをトレードオフの関係で捉えてしまう
    f:id:sonomirai:20200124210700j:plain
    テーマ:SMがアジャイルスクラムもよくわかっていない
    f:id:sonomirai:20200124210744j:plain
    テーマ:ビジネスサイドは日本、開発チームは海外子会社という環境で、効果的にスクラムを浸透させる方法が知りたい

  • なお「どう向き合うか」には、基本的にアジャイルの価値や原則、スクラムの理論や価値基準から選んだワードを記載する。(その他でもOK。)以下はワード選びのために配布いただいた資料。
    f:id:sonomirai:20200124210826j:plain
    アジャイルスクラムの価値・原則が載っている資料

感想

  • スクラムセミナーというと、ともすれば自己組織化の話やフレームワーク(ロール・イベント・成果物)の話が中心で、アジャイルの価値や原則、スクラムの理論や価値基準の説明はさらっと流してしまうこともあると思うが、このセミナーはアジャイルの価値や原則、スクラムの理論や価値基準について、受講生にしっかり考えさせるプログラムになっていて、とても勉強になった。
  • また普段はスクラムチームにおける自身のロールを前提として価値や原則を考えがちだが、このロールプレイは一回そこをクリアして、PO/SM/Devそれぞれの視点から、価値や原則に基づき、具体的なアクションを追求できるという点も勉強になった。
  • ぜひ組織に持って帰ってほしいということだったので、折を見て自社でもロールプレイをやってみたいと思う。(KPTの結果、なかなかTryに取り上げられない重めのProblemがあった場合には、このロールプレイのテーマに取り上げると、アジャイルスクラムの価値や原則と照らし合わせて、フラットなディスカッションができて良さそう、という印象を持った。)