ファイアウォール、Slackからでも対応できる?!

はじめまして、中川です。 3年目ということもあって、丁度自分の立ち位置が分からない時期にさしかかり、日々迷走しております。

早速ですが、皆様の企業では、どのFWを使用して社内ネットワークを守っていますでしょうか?
また、どのようなクラウドサービスを利用しておりますでしょうか?

弊社では、Paloalto社のPAシリーズを使用しております。
また、利用しているクラウドサービスの1つにAWS EC2があります。
AWS EC2への通信許可設定はFW上で行っていますが、
「AWSって次々とIPアドレスレンジ増やしていくから大変っっ(◎_◎;)」でした・・

そこで、“panxapi”という便利なAPIを利用したscriptを活用した事で【大変】が解消されたので、
今回は"panxapi"とは何か、弊社での活用方法を簡単に説明させて頂きます。

■"panxapi"とは・・・・

簡単に言うと、"FWにログインしなくても、コマンド上から設定編集したり、情報収集出来るPaloalto限定の便利ツール"です。

■どのような【大変】を抱えていたのか・・・

  1. 弊社ではAWS EC2への通信許可設定をFW上で行っておりますが、皆さんもご存知のように
    AWSは次々と新しいIPアドレスレンジが追加されたり、新リージョンが出来たり、時にはIPアドレスレンジの変更・削除もあります。
    その度にFW上にIPアドレスレンジ追加して、アドレスグループに追加してました。
    ↑この次々とあるのが、FW上で通信許可設定を行ってる身からしたら結構手間・・・(地味に時間がかかる)

  2. 例えば休日等にエンジニアが新しくサーバを立てて、そのサーバがまだFWに追加設定していない新しいIPアドレスレンジの中からIPを取ってしまったら・・
    折角休日にサーバ立てても作業出来ません・・通信許可設定してよ~。と言われてもこちらが出先だったら?勿論対応出来ません。

何とか解消出来ればな~・・・・

そこでリスペクトしていた元上司からこんな提案がありました。


【slackならスマホにも入れてるから、slackからFWへ追加設定出来る様にしよう!!!!】


(と同時に既にscriptもほぼ作り上げていました( ̄д ̄)!!)

まずslackから対応出来るようにする為のscriptを作成する前に運用ルールを考えました。

■ルール

slackから対応出来る様、"bot_palo"というslack botを用意し、
そこから追加分のIPアドレスレンジの確認や追加設定を行う。
ただし、slackから追加設定出来るのは、あくまでも【既存リージョンへのIPアドレスレンジ追加のみ】
新リージョン、IPアドレスレンジの変更・削除は今まで通り手動で行う。

では、次にこのルールを踏まえて作られたscriptの追加設定までの流れを説明します。

■説明

  1. Amazon公式サイトに掲載されているAWS EC2の使用IPアドレスレンジとFWに設定されているIPアドレスレンジ情報をpanxapiを使い、情報を引っ張ってきて比較
  2. 比較し、出た差分情報(追加が必要なIPアドレスレンジ)を中川にメール通知(既存リージョンへのIPアドレスレンジ追加なのか新リージョンなのか、変更・削除なのかまで出す)
  3. slack上で"bot_palo ck"と打つと今回の対象分(既存リージョンへの追加IPアドレスレンジ)を確認できる
  4. “bot_palo set"と打つと、FWへ設定が入る(panxapiを使って追加処理を動かす

実行例

bot_palo ck

f:id:AdwaysEngineerBlog:20170901125049p:plain

bot_palo set

f:id:AdwaysEngineerBlog:20170901130002p:plain`

これにより出先からでも対応出来る様になり、またいちいちFWにログインして、IPアドレスレンジを登録して、アドレスグループに入れて・・・とやらなくても
ささっとslack上から設定する事が出来るので手間も省け、この作業に費やす工数を減らすことが出来ました!!!!!!!

今回は細かいscriptの内容まで書くことはできませんでしたが、
今後もpanxapiを利用して出来る事があれば、チャレンジしていきたいと思っております。

Mackerel Plugin Hackathon #1 Tokyo に 参加した話

こんにちは、久保田です。

先週の土曜日(8/19)に「Mackerel Plugin Hackathon #1 Tokyo」に参加して参りました。

mackerelio.connpass.com

人生初ハッカソンだったのですが、楽しく過ごせたので、どんな感じだったのか、つらつらと書いていきたいと思います。

説明/アイディアソン

まず、13時に今回の会場であるVoyageさんのオフィスに集合し、はてなのsongmuさんから今回のテーマであるMackerelのpluginについてのお話がありました。

プラグインには

  • メトリックプラグイン
  • チェックプラグイン
  • メタデータプラグイン

があり、それぞれデモを交えて説明していただきました。
とてもわかりやすかったです。
今までメトリックプラグインしか作ったことがなかったので、色々できることが増えそうでわくわくでした。

そしてその後、近くの人とグループになり、アイディアを出し合いました。
みなさんいろいろなアイディアがあるようで、かぶらないものを探すのに必死でした。笑

実装

14時からは各自実装でした。
17時までと3時間しかないため、まだ何を作るか迷っていた僕は結構焦っていました。

はてなのスタッフの方々が質問にも答えてくださるので、大変心強かったです。

みなさん各々実装していたので、とても集中して作ることができました。

最初はgoで作ろうと思ってたのですが、時間もなく、僕はメタデータプラグインを作っていたので、最終的にはRubyで実装しました。

成果発表

あっという間に3時間が過ぎ、成果の発表になりました。
みなさん時間内でしっかり成果を出していて、驚きました。

僕が一番驚いたのは、jsonを与えるとスキーマいらずで良い感じにmackerel-agentが求める必要な形に成形してくれるプラグインでした。
ぜひ今度コードを読んでみたいなと思いました。

そんな僕は「ホストに入っているプログラミング言語のバージョン」をメタデータとして登録するプラグインを作成しました。

これがあれば、脆弱性があるバージョンの言語を入れていたりサポートが終わった言語を使っているホストを特定できるな、と考え作りました。

github.com

まとめ

その後懇親会があったようですが、僕は私用があり先に帰らせていただきました。
みなさんそれぞれの多種多様なアイディアがあり、エンジニアとしてとても刺激になりました。
また、初めてのハッカソンでしたが、短い時間で1つ作りあげることができ、とてもいい時間でした。

機会があれば参加したいなと思います。

素晴らしい機会を提供していただいたはてなの皆様、ありがとうございました。

イベント駆動型slack botの実装

こんにちは、久保田です。インフラdivです。

インフラdivでは商用サービスのインフラ管理の他に、色々なオペレーション業務があります。
最近は、空いた時間でそんなオペレーション業務を自動化させて行っています。

その中でも、比較的小さな改善によく使うのが、botです。
弊社のシステム部門はslackを使っているので、botを作ってしまえば結構色々なことが便利になったり解決できたりします。

slackのbotといえば、色々な作り方がありますね。

一番簡単なのは、incomming webhookを使う方法だと思います。
エンドポイントにメッセージを投げるだけなので、非常にお手軽ですね。色々な言語でライブラリもあります。

しかしこれではメッセージを投げるだけの一方通行ですね。
できればchatの中のキーワードやユーザーのイベントをキャッチして何かをしたいですね。
そっちの方ができることの幅が広そうです。

このようなbotは大きく分けてRTM API(Real Time Messaging API)Events APIを使う2つの方法で作ることができます。
そしてRTM APIはTokenが必要なのですが、Tokenの取得に関して、レガシーなやり方とslack appを作成する2つの方法があります。
今回は、この合計3つの実装方法を確認していきます。

RTM API(レガシー)

まずはRTMのレガシーなやり方で実装します。
レガシーと言いますが、僕としてはこれが一番わかりやすく楽です。

流れは、
1. Custom Integrations で Bot を作成する。
2. 作成したBotのtokenを使い、websocketでslackとつなぎイベントを取得する。
3. websocketを使って、メッセージを送信する。 となります。

1. Custom Integrations で Bot を作成する。

https://{your slack domain}/apps/manage/custom-integrations こちらから作ることができます。
色々とBotの設定をしていき、発行されたTokenを後で使います。

f:id:AdwaysEngineerBlog:20170817205432j:plain

2. 作成したBotのtokenを使い、websocketでslackとつなぎイベントを取得する。

実装部分ですね。こちらはwebsocketを使って繋ぐ必要があります。
実装例は後ほど書いておきます。

3. websocketを使って、メッセージを送信する。

こちらはjsonで送ってあげれば大丈夫です。
こちらも後ほど書いておきます。

RTM API(slack app)

こちらはslack appを作成し、そのslack app上でbotを作りtokenを発行する方法です。
こちらの方が現在は推奨されているようです。

流れは、
1. slack appを作成する
2. bot userを作成する
3. tokenを発行する
4. RTM API(レガシー)の2,3と一緒

1. slack appを作成する

まずはslack appをこちらから作ります。

https://api.slack.com/slack-apps

2. bot userを作成する

次にslack app上にbot userを作ります。

f:id:AdwaysEngineerBlog:20170817205528p:plain

3. tokenを発行する

Install AppからAuthorizeしてtokenを発行します。

f:id:AdwaysEngineerBlog:20170817205455p:plain

4 実装

今回はRubyで実装しました。
レガシーでも、slack app経由でもtokenの取り方が違うだけなので、一緒です。
websocketでつないでおくのですが、処理が抽象化できそうだったので、gemにしました。

github.com

このライブラリを使うと、以下の処理だけでbotが作成できます。

require 'slack-rtm-bot-helper'

# channelはnilならば送信してきたchannelにメッセージを返す。
Slack::Rtm::Bot::Helper.run(token='xoxo-hgoehogheoajgjafhodhgao', channel=nil) do |data|
  # messageを作るロジック
end

Slack::Rtm::Bot::Helper.runを実行して、ブロックを渡してあげます。
slackのRTM経由でjsonが送られてくるので、それを処理し、文字列を返すとメッセージを返します。

RTMの実装はこれだけです。

https://github.com/slack-ruby/slack-ruby-client でも同じようなことができます。

Events API

さて、次はEvents APIを使う方法です。
これはRTMとは違い、websocketでつなぎません。
RTMはwebsocketの扱いが面倒くさいので、僕はこのAPIを使うのがベストなのでは、と思います。
このAPIでは、slack app上にエンドポイントを作成し、そこにイベントが送られてきます。

なので実装の流れは、

  1. slack appを作成する。
  2. エンドポイントを実装する
  3. Event Subscriptionから、エンドポイントとsubscribeするeventを登録する。
  4. webhookURLなどを使ってメッセージを送信する

という流れになります。
4は普通なので今回は割愛します。

1. slack appを作成する。

これはRTMの時と同じです。

2. エンドポイントを実装する

Eventが発火された時、受け取るためのエンドポイントが必要になります。
httpsでpostを受け取れるようにしておきます。

そして、登録時にverficationを突破する必要があるので、送られてくるchallengeパラメータを返すようにしておく必要があります。
https://api.slack.com/events/url_verification

僕はAPI Gatewayとlambdaでサクッと作りました。 とりあえず登録だけしたいので、lambdaは

exports.handler = (event, context, callback) => {
    callback(null, event["challenge"]);
};

こんな感じです。

APIGateway経由で動くようにしておきましょう。

3. Event Subscriptionから、エンドポイントとsubscribeするeventを登録する。

さて管理画面に戻り、設定をします。

f:id:AdwaysEngineerBlog:20170817205612p:plain

まずは右上のoffになっているところをonにし、 先ほど作ったエンドポイントを登録します。
そしてverfiyが通ればOKです。

そして下の方でsubscribeするイベントを登録します。
今回はmessage.channelsを使います。

https://api.slack.com/events/message.channels

f:id:AdwaysEngineerBlog:20170817205630p:plain

これで対象のチャンネルで何か喋ると

f:id:AdwaysEngineerBlog:20170817205645p:plain

ログに出てきます。

f:id:AdwaysEngineerBlog:20170817205842j:plain

良さそうですね。

他にも色々なイベントを扱えるので、色々試してみてください。

今回は以上です。

ansibleでディスクを拡張してみる

こんにちは。インフラの奥村です。

最近、業務でインフラ運用業務の改善活動をさせて頂いています。
僕が行った改善活動の一つ
「ディスク拡張のコマンド化」について書いていこうと思います。

以前までは

  1. Web GUIで仮想マシンのディスクを追加し
  2. 対象のマシンにSSH等でアクセスし
  3. コマンドを打ち込む。

という作業を行なっていました。この作業を短縮するべくansibleを書きました。

環境

  • 対象: vSphere仮想マシン

必要な工程

  1. 仮想マシンのディスク拡張(デバイス追加)
  2. パーティションの拡張
  3. LVM領域の拡張
  4. ファイルシステムの拡張

以上4工程をansible化しました。shellの利用が多くなっているのは妥協してしまっています。

必要無さそうな条件分岐等がありますが、これはディスク拡張のパターンとして

  • デバイスを追加するパターン
  • ディスクの容量を拡張するパターン

があるためです。 今回はデバイスを追加するパターンにフォーカスを当てて書きますので、余分な部分はカットしています。

ファイル群

  • ディレクトリ構造
.(DISK_CHANGE_ROOT)
├── ansible
│   ├── disk_change.yml
│   └── roles
│        └── disk
│             ├── defaults
│             │   └── main.yml
│             ├── tasks
│             │    └── disk_add.yml
│             └── templates
│                  └── disk_add_cmdline.j2
├── govc_commands
│   └── disk_add
└── scripts
     └── exec_disk_add.py

playbook

  • disk_change.yml
---
 - hosts: default
   become: True
   vars:
     execute_disk_add: True
   roles:
     - disk
  • main.yml
- name: generate govc command  #テンプレートからgovcのコマンドを生成する
  become: False
  template:
    src: disk_add_cmdline.j2
    dest: "{{ playbook_dir }}/../govc_commands/disk_add"
    mode: 0755
  delegate_to: 127.0.0.1
  when: ip is defined

- name: include task for disk_add
  include: disk_add.yml
  when: execute_disk_add == True
  • disk_add.yaml
---
- name: execute disk_add  #govcコマンドを実行する
  become: False
  local_action: shell ./disk_add
  args:
    chdir: "{{ playbook_dir }}/../govc_commands/"
  run_once: True

- name: print disk info #現在のデバイスの状態をファイルとして書き出しておく
  parted:
    device: /dev/{{ device_name }}
    state: info
    unit: KiB
  register: result

- name: save disk info to file
  copy:
    content: "{{ result }}"
    dest: /home/okumura/export.txt

- name: create partition
  parted:
    device: /dev/{{ device_name }}
    number: 1
    flags: ["lvm"]
    state: present
    part_end: 100%
  ignore_errors: True

- name: exec parted command because ansible module failer  #partedモジュールでうまくいかなかったのでpartedコマンドで対応
  shell: parted -s -m -a optimal /dev/{{ device_name }} set 1 lvm
  ignore_errors: True

- name: set already_pv flag  #追加するデバイスがすでにPhysical Volumeにないか確認する
  shell: pvdisplay | grep {{ device_name }}1
  register: already_pv
  ignore_errors: True

- block:
  - name: pvcreate
    shell: pvcreate /dev/{{ device_name }}1

  - name: resize volume group
    shell: vgextend VolumeGroup /dev/{{ device_name }}1

  - name: resize logical volume
    shell: lvextend -l +100%FREE /dev/VolumeGroup/LogicalVolume

  - name: resize filysystem
    filesystem:
      fstype: ext4
      dev: /dev/VolumeGroup/LogicalVolume
      resizefs: yes
    when:
      - ansible_distribution == "CentOS"
      - ansible_distribution_major_version == "6"

  - name: resize filysystem
    filesystem:
      fstype: xfs
      dev: /dev/VolumeGroup/LogicalVolume
      resizefs: yes
    when:
      - ansible_distribution == "CentOS"
      - ansible_distribution_major_version == "7"
  when: already_pv.rc == 1

テンプレートファイル

  • disk_add_cmdline.j2
{% for host in ip %}  #呼び出すときのIPの数でループ
govc vm.disk.create -vm.ip={{ host }} -size {{ disk_size }}G -name={{ device_name }} -ds=datastore
{% endfor %}

こんな感じです。

流れを説明すると

  1. disk_add_cmdline.j2というテンプレートファイルをもとにして、localhost宛にgovcのスクリプトを作成する。
  2. パーティションを切る
  3. すでにデバイスがないか判断する
  4. 無い場合はphysical volumeを作成し、Volume Groupの拡張、Logical Volumeの拡張を行なう
  5. ディストリビューションを判断し、デフォルトのファイルシステムで拡張

という流れです。

192.168.0.1のホストのディスクサイズを20GB拡張したいときに呼び出すansibleは

ansible-playbook -i inventory/hosts --extra-vars '{"ip": [192.168.0.1], "disk_size": 20, "device_name": sdb}' ansible/disk_add.yml

!?

長すぎるじゃないですか!シングルクウォートとダブルクォートが混在しているコマンドを誰が好んで実行するんですか! ってなりますよね。私もなりました。

ということで、今回はこのコマンドを呼び出すためのスクリプトも作ってみました。 内容としては 受け取った引数を元にansibleのコマンドを作り出し、それを実行するというまぁ、うん、なスクリプトです。

  • exec_disk_add.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import subprocess
import os
import argparse

def create_inventory(iplist,env_path):
    f = open("" + env_path + "/inventory/pre_hosts","w")
    inventory_text = "[default]\n"
    for ip in iplist:
        inventory_text = inventory_text + ip + "\n"
    f.write(inventory_text)
    f.close()

def create_cmd_args_for_add(iplist,size,device):
    cmd = '{"ip": [' + ",".join(iplist) + '], "disk_size": ' + size+ ', "device_name": ' + device + '}'
    return cmd

def create_cmd(cmd_args,env_path):
    cmd = "ansible-playbook -i " + env_path + "/inventory/pre_hosts --extra-vars '" + cmd_args + "' " + env_path + "/ansible/disk_add.yml"
    return cmd

def main():
    parser = argparse.ArgumentParser(description='this script extends the disk.')
    parser.add_argument("-i","--ip",      help = "target ips. This option is required",       required=True, nargs="*")
    parser.add_argument("-s","--size",    help = "target disk size. This option is required", required=True)
    parser.add_argument("-d","--device",  help = "choice device. This option is required",    required=True)
    parser.add_argument("-p","--printif", help = "print command",                             action="store_true", default=False,)

    cmd_arg = parser.parse_args()

    create_inventory(cmd_arg.ip,os.environ.get('DISK_CHANGE_ROOT'))

    cmd = create_cmd(create_cmd_args_for_add(cmd_arg.ip,cmd_arg.size,cmd_arg.device),os.environ.get('DISK_CHANGE_ROOT'))

    print(decided_cmd) if cmd_arg.printif == True else subprocess.call(decided_cmd, shell=True)

if __name__ == "__main__":
    main()

上のディレクトリ構造の「.」の部分を「DISK_CHANGE_ROOT として環境変数に登録すれば

./exec_disk_add.py -i 192.168.0.1 -s 20 -d sdb

これで呼び出せるようになりました。

まとめ

最近「Yak Shaving(ヤクの毛を刈る)」という言葉を知りました。

「ある問題を解決しようとしたら、別の問題に直面し、その問題を解決しようとしたら、また別の問題に直面し・・・」

というようになることだそうです。(気になる方は調べてください)
改善活動をしていると、こういう状況に出くわすことが多いと思います。

ですが、改善活動の場合は、出てきた問題を一つ一つ潰していくのが理想だと私は思います。

最後までご覧頂き、ありがとうございます。

スクラムにおける4つのイベント

はじめまして!入社2年目のエンジニアまっちゃんです!
もともとチームとしてスクラム開発を行っていたものの、うまく回せていないという課題がありました。
スクラム改善として、新しくチームにジョインしてくださったスクラムマスターのT先輩から「スクラムの事再度調べてこい」とチーム全員に課題を出されたので、スクラムのイベントについてチームメンバーと認識合わせしたものをまとめてみました。

まとめるにあたって、下記のものを読みました。

SCRUM BOOT CAMP THE BOOK

SCRUM BOOT CAMP THE BOOK

Scrum Guide 2016

※用語が分からない方はwikipedia参照
スクラム (ソフトウェア開発) - Wikipedia

スプリントプランニング

計画会です。
スプリントで開発チームが何を行うのかを決めます。

登場人物
  • プロダクトオーナー
    • プロダクトバックログの内容について説明
  • 開発チーム
    • プロダクトバックログの内容を確認  
    • タスクを洗い出す
  • スクラムマスター
    • ファシリテート
    • サポート
手順
  • 第1部
    • プロダクトオーナーがプロダクトバックログの上から順番にどこまで実現して欲しいかを開発チー ムに伝える
    • 何を実現すればいいのか確認。プロダクトオーナーから開発チームにそれぞれの項目について説明
    • 項目が達成できそうかをプロダクトオーナーと開発チームで相談
  • 第2部
    • 開発チーム全員で必要なタスクを洗い出す
    • タスクの見積もりを行う
時間
  • 2週間スプリント…4時間
  • 4週間スプリント…8時間
成果物
  • ポイントが見積もられたプロダクトバックログ
  • タスクが洗い出されたスプリントバックログ

デイリースクラム(デイリースタンドアップ)

よく朝会と呼ばれているものです。
これを行うだけでスクラムやっている感がでます。

手順
  • 開発チームが毎日、同じ時間・場所で開催する
  • 開発チームのメンバーが以下のことを説明
    • 開発チームがスプリントゴールを達成するために、私が昨日やったことは何か?
    • 開発チームがスプリントゴールを達成するために、私が今日やることは何か?
    • 私や開発チームがスプリントゴールを達成するときの障害物を目撃したか?
  • 開発チームまたは一部のチームメンバーは、デイリースクラムの終了直後に集まり、スプリント残作業について詳細な議論・適応・再計画を行う事もある
登場人物
  • 開発チーム
    • デイリースクラムを開催する責任を持つ
  • スクラムマスター
    • 開発チームにデイリースクラムに開催してもらうようにする
    • デイリースクラムを15分間で終わらせるよう開発チームに伝える
    • デイリースクラムには開発チームのメンバーしか参加できないというルールを厳守する
時間
  • 15分
成果物
  • スプリントゴールとスプリントバックログの作業の進捗を検査

スプリントレビュー

実際に成果物を見せて、意見をもらう貴重な場です。

手順
  • 参加者(スクラムチームと重要な関係者)はプロダクトオーナーが招待
  • プロダクトオーナーは、プロダクトバックログアイテムの「完成」したものと「完成」していないものについて説明
  • 開発チームは、スプリントでうまくいったこと・直面した問題点・それをどのように解決したかを議論
  • 開発チームは、「完成」したものをデモして、インクリメント(成果物)に対する質問に答える
  • プロダクトオーナーは、現在のプロダクトバックログを審議する。(必要であれば)現在の進捗から完了日を予測
  • グループ全体で次に何をするかを議論し、次のスプリントプランニングに価値のあるインプットを提供できるようにする
  • プロダクトの市場や今後の利用状況についてレビューした場合、次に行う最も価値の高いことが変更されることもある
  • プロダクトの次のリリースに対するスケジュール・予算・性能・市場をレビュー
  • 完了の定義について考える。プロダクトオーナーが求めてるもの。スクラムチーム内での合意を得る
    • デモ手順の通りに動作する
    • publicメソッドのテストコードがある
    • 調査した内容はWikiにまとめてある
    • 最新の仕様がWikiにまとめてある
    • リポジトリからいつでも最新のでも可能でテスト済みのソフトウェアが取得できる
登場人物
  • プロダクトオーナー
    • 関係者を招待
    • プロダクトバックログについて説明
    • プロダクトバックログの審議
  • ステークホルダ
    • 「完成」したものへの質問
    • プロダクトの市場や今後の利用状況についてレビュー
  • 開発チーム
    • スプリント内の良いところと悪いところ、悪いところをどのように解決したか議論
    • 「完成」したものを動かし、質問に答える
  • スクラムマスター
    • ファシリテート
    • サポート
時間
  • 2週間スプリント…2時間
  • 4週間スプリント…4時間
成果物
  • 次のスプリントで使用するプロダクトバックログアイテムが含まれた 改訂版のプロダクトバックログ
  • 新たな機会に見合うように、プロダクトバックログを全体的に調整

スプリントレトロスペクティブ(スプリント振り返り)

今回のスプリントをもとに、次のスプリントがより良くなるか考えます。

手順
  • 人・関係・プロセス・ツールの観点から今回のスプリントを検査
  • うまくいった項目や今後の改善が必要な項目を特定・整理
  • スクラムチームの作業の改善実施計画を作成
登場人物
  • スクラムマスター
    • イベントが確実に開催されるようにする
    • 参加者に目的を理解してもらう
    • スクラムチームにタイムボックスを守るように伝える
    • スクラムプロセスを説明するためにチームメンバーとしてイベントに参加
  • 開発チーム
時間
  • 2週間スプリント…1.5時間
  • 4週間スプリント…3時間
成果物
  • 改善実施計画

まとめ

T先輩からの課題は大変ながらも無事にこなす事ができました!
が、本番はここからだと思います。
現在はそれぞれのイベントに対して、チームに合った実施方法をスクラムチーム全員で考え、議論していきたいです!