運用縛りのテーマ「オペレーションじょうず」を開催しました
5月23日(土)ですが、テーマを運用縛りにした「オペレーションじょうず」を主催しました。
毎回開催のテーマに関してはあまり悩まない(だいたいニーズがあるものは読める)
のですが、今回はちょっとどうなるのかと自問自答しながらの運営でした。
ただ、自分が去年の4月にcloupackに入り、6月から構築/運用で24/365のチームに
配属されてから運用に入った時にイメージと現実が隔離している事に愕然として
DevOpsだよね〜なんて軽口叩いていた開発から運用への自分の勘違いをテーマに
TOPバッターはもちろん波田野さん。
資料には記載できてない話があるのですが、そこがオペレーションじょうずの
裏テーマだったんですが自重らしくUP資料からは割愛されていますw
こういうケースもあるので、是非皆様現地にお越し下さいw
「東急ハンズの運用削減事例と方針」をハンズラボ株式会社の田部井さん
「CG映像制作におけるAWSの活用(スポットインスタンスによるCGレンダリング)」
を株式会社石田大成社の戸崎さん。
創業の100年の老舗がAWSでレンダリングでさらにスポットインスタンス。
資料の公開が待たれますが、サミットでもお話するようで、資料はそれ以降ですね
吉田姓の為に登壇するcloudpack吉田ヒロカズさんw
サーバーワークスの柳瀬さんは「AWSのAPIを使うときに気をつけていること」
JAWSUG大阪の森さんの登壇後に波田野さんが森さんの内容についてトークする瞬間。
とりはNRIネットコム株式会社の佐藤さん。
でも記載されているので、資料とまとめを見て頂ければと思います。
【cloudpack 大阪 BLOG】MSPのシステム化について Hubotでの状態管理(mysql)とGoogleカレンダーとslack連携 その1
一年間寝かし(放置してしまった汗)ておいた
をようやく実施できるようになりました汗。
クラウドユーザーグループ7つ+αによる合同勉強会。
去年の2月のXEggはJAWS-UGとJAZUGのみで、他のコミュニティの方にも
ご協力いただきましたが、今回はクラウドユーザーグループメインでの実施が
可能になりました。
1年でたくさんのクラウドユーザーグループが産まれたのはうれしいですね。
今回はHUBOTとmysqlとgoogle カレンダーとgoogle apps script(以降GAS)とslackの連携となります。
今回実施したかった事は、計画的作業の見える化です。
cloudpackでは計画的な時刻指定の作業は、
backlogやgoogle カレンダーに記載して対応していましたが、
担当者の作業忘れや作業を取りかかっているかどうかが他の人(cloudpack依頼者)から
見えないなど、結果的には出来ていたのですが、もやっとした部分があったので
日次処理のつぶやきのように、slackへのカレンダーの通知(作業着手URL付き)と、
作業着手を受け付けたのを表示するつぶやきと、作業着手できない場合は、
定期的に出来ていない事を通知する機能を実装する事にしました。
今回はgoogleカレンダーの連携にGASを利用しました。
hubotからgoogleカレンダーのAPIを呼ぶのも出来るようですが、
自身の理解力が無いのか、情報が古いのかわかりませんが、
少しやってうまくいかなかったので、GASを使って
googleカレンダーの連携を行います。
GASでの方法は、単純で、定期的にgoogleカレンダーにアクセスして
つぶやきたい時間の範囲のカレンダーのデータを取得し、hubotに投げるだけです。
※以降の処理はhubotでさせる。
GASでカレンダーに連携するのは下記のURLを参考にさせて頂きました。
Googleカレンダーにアクセスする(1/5):初心者のためのGoogle Apps Scriptプログラミング入門
※GASですが、非常に便利ですが、色々と罠(仕様)や不具合が潜んでいます。
※簡単お手軽で、サンプルを張ってちょっと修正して動いちゃうのですごく良いのですが
※そこだけを見ていると痛い目に遭いますので注意(今回の範囲ではなかったので記載しません)
//カレンダー連携
function googlecalender() {var calendarId = "抽出したいカレンダーのID";
var cal = CalendarApp.getCalendarById(calendarId);
var urlstr = "連携先のhubotのurl";
// 現在時刻を生成
var date = new Date();
var d1 = new Date();
d1.setMinutes(d1.getMinutes());
var d2 = new Date;
d2.setMinutes(d2.getMinutes() + 15);
var evts = cal.getEvents(d1,d2);
var body = "";
if (evts.length > 0){
for (var i in evts){
var evt = evts[i];
if(!evt.isAllDayEvent()){ //終日では無い場合
var creators = evt.getCreators();
var responsible = "@" + creators[0].slice(0,creators[0].indexOf("@")) + " (イベント作成者)";
var guests = evt.getGuestsStatus();
if (guests.length >= 1){//招待者(担当)が登録されていたら招待者を担当者として上書き
responsible = guests[0].getEmail()
responsible = "@" + responsible.slice(0,responsible.indexOf("@")) + " (招待者)"
}
var Id = evt.getId()
var Title = evt.getTitle()
var Description = evt.getDescription()
var StartTime = Utilities.formatDate( evt.getStartTime(), 'JST', 'yyyy年M月d日HH時間mm分')
var EndTime = Utilities.formatDate( evt.getEndTime(), 'JST', 'yyyy年M月d日HH時間mm分')
var StartTimeInt = evt.getStartTime();
StartTimeInt.setMinutes(StartTimeInt.getMinutes() - 3);//処理時間の誤差を許容する為に
StartTimeInt = Utilities.formatDate( StartTimeInt, 'JST', 'yyyyMMddHHmm')
var EndTimeInt = Utilities.formatDate( evt.getEndTime(), 'JST', 'yyyyMMddHHmm')
var query =
{
"Id" : Id,
"Title" : Title,
"Description" : Description,
"StartTime" : StartTime,
"EndTime" : EndTime,
"StartTimeInt" : StartTimeInt,
"responsible" : responsible,
"EndTimeInt" : EndTimeInt
};
var options =
{
"method" : "post",
"payload" : query
};
UrlFetchApp.fetch(urlstr, options);
}
}
}
}
な感じで、GASは実装させて頂きました。
実装の詳細ですが
var calendarId = "抽出したいカレンダーのID";
var cal = CalendarApp.getCalendarById(calendarId);
で、抽出したいカレンダーにアクセスします。
var date = new Date();
var d1 = new Date();
d1.setMinutes(d1.getMinutes());
var d2 = new Date;
d2.setMinutes(d2.getMinutes() + 15);
取得したい期間を作成し
var evts = cal.getEvents(d1,d2);
その期間のカレンダーデータを取得します。
evts.length
カレンダーのイベントがあるのかを確認し
for (var i in evts){
データがあればでループさせ、
var evt = evts[i];
一つ一つのカレンダー情報にアクセスします。
evt.isAllDayEvent()
カレンダーが終日かを確認し、終日でなければ
var creators = evt.getCreators();
〜
var EndTimeInt = Utilities.formatDate( evt.getEndTime(), 'JST', 'yyyyMMddHHmm')
hubotに投げる情報を作ります。
そして
var query =
{
"Id" : Id,
"Title" : Title,
"Description" : Description,
"StartTime" : StartTime,
"EndTime" : EndTime,
"StartTimeInt" : StartTimeInt,
"responsible" : responsible,
"EndTimeInt" : EndTimeInt
};
var options =
{
"method" : "post",
"payload" : query
};
UrlFetchApp.fetch(urlstr, options);
でHubotのURLにカレンダー情報を投げます。
今回は③と④の情報を記載しました。
GASの"UrlFetchApp.fetch"での連携は非常に便利ですが
getとpostのみget/post/put/deleteの対応でpatchメソッド非対応なので使う方はちょっと検討する必要があります。
Google Apps Script Documentation - UrlFech Services - Class UrlFechApp
【cloudpack 大阪 BLOG】MSPのシステム化について(不定期連載) Hubotに定期的につぶやかせる&作業の管理をさせる
なんて記事が出ていて、時代の先を行っているな俺とかわけのわからん優越感に
浸っていますw
今回は<Hubotに日次作業を定期的につぶやかせる&作業の管理をさせる>です
①と②のやり取りの部分は前回で基本は出来るようになります•••
そしてよくHubotの最初に実装されている機能で、Slackにpingと入力したらpongと
返したりするのを少し楽しみますが・・・これからどう活用するの?で
PCの電源をそっとOFFにして、Heroku上には実装を待ち続ける、野良Hubotが
5万といるのではないかと推測されます・・・汗
とりあえず日次業務をつぶやかせるには、Hubotの機能だけでは無理なので
状態を管理する機能と、時間になったらHubotをつぶかす機能が必要になります。
今回状態を管理させるのは、Redisを使用し、
時間によるトリガーはnode.jsのモジュールである、cronモジュールを使います。
redisのインストールと設定は
sudo yum --enablerepo=epel install npm redis
sudo /etc/init.d/redis start
sudo chkconfig redis on
で、行いcronのインストールは
npm install cron
で、行いました。
これで下準備はOKでつぶやかせるには○の所に時間を入れて
cron = require('cron').CronJob
client = require("redis").createClient()module.exports = (robot) ->
new cron('0 0 ○ * * *', () ->
robot.messageRoom つぶやかしたいルーム名, "MSPの皆様おはようございます。本日の日次処理担当の方、○時になりましたので日次処理の対応よろしくお願いします"
, null, true, 'Asia/Tokyo').start()
で出来て、redisへの値のセットは
client.set "○", 1
な感じで(○はキー名として時間で”1”はセットしたい値です)簡単に値のセットが可能です・・・が、hubotに対する指示(ここでは作業を着手した)を、毎回キーボードで
入力してって言ったら、間違いなく使ってくれない・・・と言う事で、
HubotがURLを表示して、クリックされたらHubotが受け付けてつぶやく事をやめるような、お手軽なUIの実装を行います。
Hubotはnode.jsなので
request = require 'request'
module.exports = (robot) ->
robot.router.get "/hubot/daily", (req, res) ->
な形で、WEBサーバーとしてURLを受け付ける事も可能ですが、
SlackでURLを表示してしまうと、もれなくSlackのプレビュー機能で、
そのURLがコールされるというかなり残念な状況になってしまい、
表示=URLを叩かれた状態で処理が勝手に完了して、
全く無意味な状態になるので、コード上でユーザーエージェントを確認し
if req.headers['user-agent'] == 'Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)'
return
slackからのプレビュー表示なら、処理を抜けるような実装をしてあげる必要があります。
で後は
client.get "○",(err, val) ->
if err
return
# エラーが無ければデータを取得
if val == 1
client.set "○", 0
robot.messageRoom "ルーム名","*○時の日時処理の受付完了しました*"
な感じで、redisから値を取得して状態を見て、問題なければつぶやくような実装をすれば
な感じでつぶやいてくれるようになります。
なお今回の機能を実装するにあたり下記のページを参考にさせて頂きました
私のブログは実装側を目的としているのではなく、
課題に対するアプローチがメインなので、ざっくりとした形で抜粋させてもらっていますので、実装は色んなBLOGを参考にして頂ければと思います。
今回の実装の仕方は、Hubotが初めてでもあったのと、見たサンプルを元に
実装していったために、作りが固定で汎用性が無いものになっていますが
とりあえず24/365を目標にずっと稼働しているので、今のところは目的を果たしていますし、担当者が作業を忘れていても、Slackを見ている他の人が気がつくようになっています。
クリックしないと、10分おき(時間が遅くなると5分おき)につぶやくので、
Slack上でのやり取りを中断してしまう?って話もありましたが、
気がつけばすぐにクリックと、作業漏れや作業着手の遅れが可視化されたので、
とりあえずはよしかなと思っていますが、よりMSPや他のメンバーにわかりやすくできる案が頭の中では出来たので、いつのタイミングかで実装/投入したいと思います。
次回はこの機能の実装を汎用化させた、
googleカレンダーとgoogle app scriptとhubotとslackの連携を書きます。
【cloudpack 大阪 BLOG】MSPのシステム化について(不定期連載) まずはHubotのインストールとslack連携まで
ようやく本編?です。
今回は最も基本的なグリーンの部分を解説?します。
このBLOGはざっくりとした流れの説明なので、実際に実装する場合は他のBLOGを
参照してくださいw。
cloudpackでは
や
でも記載されていますが、Slackを使っています。
なので、Slackがコミュニケーションの中心となりますので、MSPの
業務でもSlackがメインとなります。
Slackが便利な所は(他のチャットツールでもありますが)、botやwebhookの
他システムとの連携が秀逸なところです。
で、どこの勉強会でもSlack=bot=hubotな流れがずっとあるので、
MSPの業務にHubotを比企のほうで導入してみようと思いました。
ただ、どんな小さな内容を導入するのでも
①24時間/365日稼働する必要がある
②開発ではないので業務の合間の時間のみで実装やデバッグと導入
③顔をなかなか合わせない(スケジュールのローテーションの都合)メンバーにも使ってもらえるように配慮した仕組み
する必要があり、
①に関しては、バグを出さずに重い実装もしない
②に関しては、自分でがんばる&手軽に出来る実装方法を選ぶ
③に関しては、自然と使ってもらえる機能を用意して、必ず使う方向に持って行く
が必要な要件で、
とりあえず手始めとして
日次業務で時間になったらHubotがSlack上につぶやいて完了した事を報告しないと
Slack上に一定間隔で忘れていないか?をしつこくつぶやき続けるHubotのサービスを
作りました。
Hubotのインストールの仕方は残念ながら自身がやりだしたのがVer1の方で
今展開しても意味がないのでVer2のほうでのインストールの仕方
などを参考にしてください。
Hubotをインストールすると結構な頻度でHEROKUが現れますが
今回はAWSのEC2(CentOS)上にインストールをしました。
Hubotをインストールするだけでは駄目なので
# cd 作ったプロジェクトのディレクトリ # npm install hubot-slack --save
で、slackのアダプターをインストールしてあげる必要があります。
上記だけでは駄目でSlackの画面左上にある、Slackのグループ名の
をクリックし
をクリックし
タグの
のAddをクリックし
botの名前をつけて
表示されているAPI Tokenを保持し
Customize Icon/First & Last Name/What this bot does
な項目はわかりやすいのをセットし
Save IntegrationするとSlack側のHubotの設定は完了です。
※SlackはHubotからの通信が長期間ないと
勝手にDisableしてくれるNice(涙)な仕様なので、
繋がらない場合は、そこの設定も見ておいてください
あとはHubot側のEC2の環境変数に
export HUBOT_SLACK_TOKEN=控えておいたトークン
export HUBOT_SLACK_TEAM=チーム名
export HUBOT_SLACK_BOTNAME=botの名前
をセットして、
./bin/hubot --adapter slack
で起動させてエラーが出なければ、最初は#generalで反応するようになります。
※Ver2は試していませんが、各チャンネルでhubotを招くと反応するようになるようです。
※Ver1の時は
export HUBOT_SLACK_CHANNELMODE=whitelist
export HUBOT_SLACK_CHANNELS=チャンネル名
のような感じで記載する必要がありました。
ここでとりあえずHubotのインストールは終わりですが、
これまでの設定とAWSのEC2のセキュリティグループのポートがOPENしていたら
ハマる事は無いと思われます。
しっかりと設定を確認し、時間切れでのDisableになっていない事も確認してください。
なお、hubot(node.js)は、例外が発生するとサービスが継続できなくなりますので
sudo npm install forever -g
で、foreverをインストールし
forever start -c coffee node_modules/.bin/hubot -a slack
で起動させHubotを永続させてください。
なお、停止は
forever list
でプロセスIDを確認し(1つだけだと基本0です)
forever stop プロセスID(基本は0)
で、停止させてください。
プログラムを更新する時も再起動の必要があるのでご注意を
とりあえず今回はここまで
「それぞれの JAWS DAYS 2015 第一回・おぼえていますか」
勉強会で内輪ネタに走るのは非常に嫌いです・・・
内輪ネタも内輪な付き合いもコミュニティを閉鎖的にしてしまい、
自身が望む、たくさんの方がふらっと参加できるJAWS-UGのコンセプトに
真っ向から反対するから。
そんな自分が、今回のLTに望んだのは理由があります。
このLTはAWS界隈の中でもガン○ム好きはいても、さらに狭い守備範囲のマ○ロスの
しかも初代の劇場版で、30年近く前の作品をモチーフにして、画像たくさん張りすぎて
LTの本番に落ちるは、そのままUPしたら著作権で訴えられる(今日日はたくさんUPされすぎて結果的に処理が追いついていない・・・?)ので、UPできないと言う、
誰得?なLTで、去年のAWS SAMITのJAWSUGのLT大会の時のガ○ダムLT(
この前出したらPV4000以上でフォロワーも400人近くになった結構感触の良かったLT)
40まで開発のリーダーだった男がインフラの運用のリーダー(見習い)になってみて
と、最後までどちらのLTを作るのか?を悩んでいたやつですが、内輪すぎるので
去年お蔵入りさせていました。
今回踏ん切りがついたのは、去年の7月とは状況が大きく変わっていたから
あえて強行してみました。
スライドシェアで公開はしませんが、一部をこのブログで公開します。
2011年10月某日
自社の売り上げにしか興味の無いアウトソーシング系開発リーダー二人の会話・・・
リーダーM「はい、JAWS-UG東京にはエンジニアと非エンジニア、
そして競合会社同士が共存していると判明しました」
リーダーL 「ばかな」
「競合会社同士は戦う為に作られたはずではないのか?」
第0回開催
リーダーM 「分かりました•••
我々のエンジニア魂が呼び覚まされているのです」
リーダーL「何?」
「我々にもエンジニア魂が蘇るのか」
第0回、懇親会まで無事終了・・・
第一回会場が調達できずに始まらず・・・
と言うようなきちんと?劇場版○クロスをJAWS-UG第0回から第1回に合わせて
個人的にはかなりがんばった内容だったのですが(劇場版○クロスは記録映画との
位置づけなのでテレビ版(現実のJAWS-UG第0回と第一回)と違うってもの再現したかった・・・)、LTの途中で画像が重すぎて落ちてしまいました・・・汗
状況が変わったのは、去年の年末にリーダーMで登場している
第1回は益子さんが自社に掛け合い、自社のTOPまでなんとか説得して
開催にかこつけれましたし、以降も精力的にJAW-UGの盛り上げに力を注ぎ
JAWS-UG大阪のお母さん的な存在で、二人で盛り上げてきて今ではたくさんの
強力なメンバーが参加してくれるようになり、
去年のJAWS DAYS2014ではロードトリップで4列シートの夜行バスで
バスを指揮しながら、途中で何度もはきそうな状態でも
がんばってJAWS DAYS・翌日の総会をほとんど寝ずに乗り切りました。
比企は霊感とか無いですが、DAYSの10日前ぐらいに急遽サムライに選ばれた時に
誰かLTをするって話になり、比企に話が来た時に、ふとこのネタを思い出し、
短い期間でしたが、何度も何度もこの1回のみのLTの為に時間をかけました。
きっと俺も一緒にDAYS連れて行きやがれって言ったのかもしれません。
そんなこんなでこのLTを実施しました。
益子さんが生きていれば
本来はサムライは益子さんが選ばれるべきだったのかもしれません。
DAYSの会場ではたくさんのJAWS-UGのメンバー達が活躍し
運営を皆でがんばっていました。
益子さんはきっとこの光景を見たら満足していたと思います。
また総会での話もあったのですが、JAWS-UG東京や大阪は
一回で開催される人数が200人以上とかになってきて、
参加人数では運営メンバーのモチベーションにならないという意見もありました。
JAWS-UG関西のDoorkeeperの数だけで、1000名近いコミュニティ参加数と、
大阪で開催したJAWS-UG FESTAでも同じく1000名近いコミュニティ参加数で
イベントレジストやATNDなどを追加するとのべ人数(ユニークではない)ですが、
2500名近い方(イノベーションエッグを含めると3000名近い!)が
JAWS-UG関西のイベントに参加して頂きましたが、
これって大阪のIT業界の人の何%?ってぐらいで、益子さんや比企が考えていた
関西のIT業界のクラウドシフトの為には全然足りていません。
サムライにもなったので露出を増やそうかななんて事も少し考えたりもしましたが
このLTを実施する事により初心を思い出し、選んだ道を歩んでいこうと思います。
益子さんの最後のコミュニティ関連のFBのコメントは
「コミュニティって楽しいよね」
でした。
そういってくれる人が一人でも多く増え、新しい絆や関係が
生まれてきたら良いなと思いつつ、比企のJAWS DAYS 2015のブログは終わりです。