新年明けましておめでとうございます。

f:id:AdwaysEngineerBlog:20171227100239j:plain

謹んで新年のお慶びを申し上げます。

昨年は大変お世話になりありがとうございました。
本年も昨年同様よろしくお願い申し上げます。
皆様のご健康とご多幸を心よりお祈り申し上げます。

平成30年元日

株式会社アドウェイズ
サービスデベロップメントグループ一同

AlexaでSlackにReminderを登録する

Adways Advent Calendar 2017 17日目の記事です。

http://blog.engineer.adways.net/entry/advent_calendar_2017


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

2度目の記事になりますが、またまたAlexaで遊んだ記事です。

今回は、Alexaを通して、SlackのReminderに予定を登録してみます。

設計

会話の流れはとりあえず以下のようにします。

ユ 「Alexa, スラックリマインダーで、明日の11時にMTGを設定して」
A 「明日の11時にMTGを設定しました。」  

まずはこの1パターンのみを考え、作ってみます。

設定

Alexaの設定をしていきます。

スキル情報

f:id:AdwaysEngineerBlog:20171225122116j:plain

対話モデル

f:id:AdwaysEngineerBlog:20171225122144p:plain

設定

f:id:AdwaysEngineerBlog:20171225122158j:plain

Lambda

プログラムはlambdaに作ります。

var https = require('https')

exports.handler = (event, context, callback) => {
    var slots = event.request.intent.slots; 
    var task = slots.Task.value;
    var date = slots.Date.value;
    var time = slots.Time.value;
    
    var resAlexa = {
        "version": "1.0",
        "response": {
            "outputSpeech": {
                "type": "PlainText",
                "text": date + time + 'に' +task+ 'を登録しました。'
            },
        }
    }
    
    var dn = new Date().getTime();
    var d  = (new Date(date + ' ' + time)).getTime();
    var unixTime = Math.ceil((d - dn) / 1000);
    https.get('https://slack.com/api/reminders.add?token='+process.env.TOKEN+'&text='+encodeURIComponent(task)+'&time='+unixTime+'&user='+process.env.USER+'&pretty=1', function(res){
        
        let body = '';
        res.setEncoding('utf8');

        res.on('data', (chunk) => {
            body += chunk;
        });

        res.on('end', (res) => {
            res = JSON.parse(body);
            console.log(res);
            callback(null, resAlexa);
            context.done(null, 'finish')
        });
    })
};

SlackのReminderのAPIの時間の扱い方が若干癖ありで微妙なのですが、一旦これで。

テスト

Alexaにはテストするためのシュミレーター画面があるので、それを使います。

f:id:AdwaysEngineerBlog:20171225122235p:plain

Slackの方をみてみましょう

f:id:AdwaysEngineerBlog:20171225122249p:plain

できているようですね。

まとめ

声経由でやって見ましたが、まだ日本語がうまく抽出できてないのか、僕の設定が間違っているのか、うまくTaskが取れない時もあったのですが、この流れで一応できました。
エラー処理などもやって、きちんと対話として成立させていきたいです。

ペアプロを導入しようと決意した話

Adways Advent Calendar 2017 16日目の記事です。

http://blog.engineer.adways.net/entry/advent_calendar_2017


社内サービスや社内システムを開発している組織のエンジニアリングマネージャーをさせていただいている山口です。

今回は、ペアプロを導入しようと決意した背景を共有させていただきます。

きっかけ


発端は、Joy, Inc.を読んだことです。
※本書の説明は省略させて頂きますが、非常に良い本ですのでオススメです!

この本を読んだ山口は、メンローイノベーションズのような組織を作りたいと思いました。

どうやって、作っていくのか。

ここでキーとなるのが、Joy, Inc. に出てくるペア作業です。

ペア作業はいままで見たなかでも最高のマネジメントツールだということだ。ペア作業により、従来あったたくさんの問題を解消できるようになる。ペア作業は学習システムを育む。また人間関係の構築、知識の塔の除去、新メンバーの立ち上げにも寄与し、生産性の問題を洗い出す役にも立つ。

よし、ペア作業やろう。

開発組織のペア作業といえば?ペアプロ。

ならば、ペアプロを導入だ!

どうせやるのであれば、抜本的に行こう!

よって、案件の開発は必ずペアプロで行うことにするぞ!

と決意したのです。

とはいえ


一般的にいいと言われているペアプロですが、パッションだけで導入するわけにもいかないので調査と検証を行いました。

まずは、ペアプロのメリットとデメリットを調べました。

ペアプロのメリット

調べてみると以下のようなメリットがあることがわかりました。

  • 属人化の軽減
  • レベル差の軽減、レベルの向上
    • レベルとは、技術レベル、PJや業務理解など
  • コミュニケーションの増加による、チーム感の向上
  • レビューコストの軽減
    • 常にレビューが行われている状態となるので、レビューを無くせる可能性も!
  • 新しいチャレンジのやりやすさ向上
  • メリハリのある開発

ペアプロのデメリット

中長期で見るとデメリットはない、もしくは無くせると思っています。 が、短期的にはありそうです。

働き方の変化が強制される

ソロでの開発では、その時の気分によってのんびり働いたり、キビキビ働いたりということが選べますが、
ペアでの開発では、一定の時間一定のペースで開発することが求められます。

また、弊社は出勤時間を個人の裁量で自由に選べる1という制度があるのですが、
ペアプロを導入すると、少なくともペアで出勤時間をある程度揃える必要があると考えています。

これらの問題は、乱暴な話かもしれませんが働き方に対する慣習に依るところが大きいと考えているので、
続けていくことでデメリットとして感じなくなるのではないかと思います。

生産性が低下する

これはよく言われていることでもありますし、直感的にも同意する方が多いのではないかと思います。

1つのタスクにかける人日だけを見たときには、中長期で見ても生産性は下がってしまうとは思います。

しかし、開発チーム全体として見たときの生産性を見ると、前述したメリットを享受することにより、
生産性は大きな問題にならないと考えています。

どうやって導入していくか


当たり前ですが、開発チームの外と内、それぞれに取り組みを理解して頂く必要があります。

開発チームの外に対して

正直な話、必勝の策はないと思っています。

メリットは実際にやってみても短期的には分かりづらいものとなるので、抵抗される可能性が高いです。

自分の場合は、各PJの責任者と開発部本部長が説得対象となります。

各PJの責任者

一部のPJの責任者には理解して頂くことが出来ました。

(残りはまだ取り組みを説明できていないです。)

PJの責任者も、開発チーム側に属人化の問題があることを問題だと考えており、
それが解消されるのであれば、やってもいいよ。という形でした。

ありがたいことです。

開発部の本部長

開発チームの生産性など自分と同じ責任を持つ立場だからこそ、納得していただくまで時間がかかるかなと思っていました。

しかし、既にペアプロのメリットなどを理解されていて、

「なぜ、今までやらなかったんでしょうね?」という発言が返ってくるぐらい歓迎されてしまいました。

いい上司を持ったなと思ったタイミングでした。

開発チームの中に対して

メンバー全員と個別にランチに行く時間を設けているので、殆どのメンバーにはそのタイミングで思いとメリット・デメリットを語りました。

みな、賛同してくれペアプロの取り組みも、自主的に進めてくれるなど積極的な行動をしてもらえました。

この行動はほんとに嬉しく、ペアプロを導入していきたいとより強く思うきっかけになりました。

少しだけ実践してみて


前述の通り、自主的にペアプロをやってみてくれたチームがありました。

そこから出てきたフィードバックとなります。

良かったこと

  • テストコードを書くノウハウが共有された
  • プロジェクトの既存機能の仕様などが共有された
  • コミュニケーションが活発に行われた
    • どのように実装すると品質があがるだろうか?
    • 納期と品質どこまでを追求するのか、妥協点をどこに置くか
    • 気軽に質疑応答が出来るようになった
    • 雑談が増え、新しいメンバーがより馴染んだ

課題

  • ペアプロの時間があまり取れなかった
    • 弊社の出勤時間を自由に選べる制度なども影響
  • 働き方に差があると、どちらかの働き方に寄ってしまう

まとめ

ペアプロの価値は、事前調査と実践で感じることが出来ました。

しかし、課題もありました。

今回の課題は、チームとしてどのような働き方をし、どのような結果を出すのか という点でチーム内の合意がないこと起因しそうです。

当たり前ではありますが、ペアプロを導入すればより良い組織になるというわけではなく、
組織の改善も同時に行い続ける必要があることがハッキリとわかったのです。

そして、自分の来年の目標が決まりました。

来年の目標

組織を改善しながらペアプロを導入するぞ!!!

参考記事

ペアプログラミングに関する調査報告

難易度は? 効果は? 実践して初めて分かった「ペアプログラミング」の実際


  1. 8時〜12時の間であればいつ出社してもOK。事前に出社時間を共有する必要もなし。

cloud9 + lambdaでslack bot作ってみる

Adways Advent Calendar 2017 15日目の記事です。

http://blog.engineer.adways.net/entry/advent_calendar_2017


こんにちは、swfzです。

先日のre:eventで発表されたAWS Cloud9

気になっていたのでこの機会に使ってみたいと思います

Cloud9とは

Cloud9はAmazonが去年買収した IDEです

下記AWSの一部引用です

AWS Cloud9 は、ブラウザのみでコードを記述、実行、デバッグできるクラウドベースの統合開発環境 (IDE) です。これには、コードエディタ、デバッガー、ターミナルが含まれています。

新しいプロジェクトを開始するためにファイルをインストールしたり、開発マシンを設定したりする必要はありません。

また、Cloud9 では、サーバーレスアプリケーションを開発するためのシームレスなエクスペリエンスが提供されており、リソースの定義、デバッグ、ローカルとリモートの間でのサーバーレスアプリケーションの実行の切り替えを簡単に行えます。

Cloud9 を使用すると、開発環境をすばやくチームと共有し、ペアプログラミングを行って互いの入力をリアルタイムで追跡できます。

面倒な環境構築が不要でlambdaの環境構築もサクサクできます、さらに共同編集機能でペアプロできます

といった感じでしょうか

試してみるために lambda + slack api で簡単なbotを作ってみたいと思います

cloud9の起動

f:id:AdwaysEngineerBlog:20171221152637p:plain

create environmentで環境を作ります

f:id:AdwaysEngineerBlog:20171221152652p:plain

名前を入れます

f:id:AdwaysEngineerBlog:20171221152705p:plain

動かす環境を選べます、既存のEC2や新規で立てるEC2などが選べるようです

今回は新規でEC2立ててやってみます

サクサク進んでいくと構築中の画面になります

f:id:AdwaysEngineerBlog:20171221152738p:plain

しばらく待つと

f:id:AdwaysEngineerBlog:20171221152753p:plain

環境ができたようです

ここからlambdaの設定を行っていきます

f:id:AdwaysEngineerBlog:20171221152810p:plain

アプリ名、function名を入力して

f:id:AdwaysEngineerBlog:20171221152821p:plain

blueprintsから選びます

サンプルなのでとりあえずhelloworldにしておきます

f:id:AdwaysEngineerBlog:20171221152836p:plain

lambdaのトリガーを指定します

今回はslackからのリクエストを受け付けるためのAPI GATEWAYをトリガーとします

さらにリソースのパスを指定します

f:id:AdwaysEngineerBlog:20171221152900p:plain

lambdaのスペックとロールを選択します

確認画面を通して少し待つと

lambdaの環境ができました

雰囲気はこんな感じです

f:id:AdwaysEngineerBlog:20171221152915p:plain

今回は新規でlambda関数を作りましたが既存環境のものをimportしたりgitからcloneしてごにょごにょすることもできるようです

slack側の設定

今回はEvents APIを使ってボットのいるチャンネルの発言に対して反応するだけの実装をします

ボットがリクエストを送れるようにするために下記手順でボットを登録します

  • Slack Appを作る

  • Event SubscriptionsでEvents APIを有効にします

    • Subscribe to Bot Eventsmessage.channelsを選択します
    • Request URLにイベント発生時のURLを入力します(API GatewayのURL)
  • 認証イベントを通す(後述)

    • イベント発生時のURLの認証
    • lambda側でpayloadのchallengeの値をそのまま返す処理を書いて認証を通します

f:id:AdwaysEngineerBlog:20171221152941p:plain

  • アクセストークンを取得、権限設定を行う
    • OAuth & Permissionsでボットが発言できる権限を与えます

lambdaの実装

npmモジュールもターミナルからnpm installするだけであとはよしなにデプロイしてくれます

今回はslackにポストするのでslack-api-clientをインストールしておきます

cd cloud9slackapp
npm init
npm install --save slack-api-client

f:id:AdwaysEngineerBlog:20171221153008p:plain

node_module以下にモジュールがインストールされました

あとは使うだけです

とりあえず動かせそうなサンプルを用意します

  • index.js
'use strict';

console.log('Loading function');

exports.handler = (event, contet, callback) => {

  const payload = JSON.parse(event.body);

  // 通知先認証用
  if(payload['type'] && payload.type == 'url_verification') {
     callback(null, {
      statusCode: 200,
      body: payload.challenge,
    });
  }
  // bot自身の発言に対しては何もしない
  else if(payload.event['subtype'] && payload.event['subtype'] == 'bot_message'){
    callback(null, {
      statusCode: 200,
      body: '',
    });
  }
  else {
    const slackToken = 'xxxx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxx';
    const slackApiClient = require('slack-api-client');
    const slack = new slackApiClient(slackToken); 

    slack.api.chat.postMessage({
      channel: 'swfz_test',
      username: 'swfz_bot',
      text: `Hello! ${payload.event.text}`,
    },(err, res) => {
      if(err){
        console.log(err);
      }
      else {
        callback(null, {
          statusCode: 200,
          body: '',
        });
      }
    });
  }
};

通知先URLの認証通すときは受け取ったchallengeの中身をそのまま返すことで認証を通すことができるのでその処理を入れています

テスト

slackから送られるpayloadを準備してテストしてみます

API Gateway(local)を選択すると対応する入力欄が出てきます

今回はPOSTでデータが送られるので Methodを POST

Bodyに実際に送られるであろうパラメータを入れていきます

最後にRunボタンを押して実行します

f:id:AdwaysEngineerBlog:20171221153040p:plain

デプロイ

テストで問題なければデプロイします

デプロイもボタンポチーしてしばらく待てば完了しています

f:id:AdwaysEngineerBlog:20171221153153p:plain

slackで確認

botをチャンネルに招待して何か発言してみます

f:id:AdwaysEngineerBlog:20171221153210p:plain

うまくいきましたね。

共同編集

ボット作成には関係ないですが共同編集を使ってみます

あらかじめ別ユーザーを作成しておきます(今回はtestというユーザー名)

f:id:AdwaysEngineerBlog:20171221153245p:plain

共有設定にするにはIDE右上のshareボタンをクリックします

f:id:AdwaysEngineerBlog:20171221153255p:plain

共同編集に招待するユーザー名を入力してInviteします

f:id:AdwaysEngineerBlog:20171221153303p:plain

招待されたユーザーで見てみるとShared with youの方に環境があるのでそこから編集作業に入ります

f:id:AdwaysEngineerBlog:20171221153316g:plain

共同編集!

varconstに変えたり、テンプレートリテラルに変えたりしてみました

同時にカーソルが動いて編集されているのがわかるかと思います

google docs使ってるみたいな感覚になりますね

f:id:AdwaysEngineerBlog:20171221181552g:plain

作業開始からの履歴も追うことができます

ペアプロ、モブプロ、研修とかで使ってみたら効果ありそうだと思いました

環境もサクッと立てられるのでlambdaに限らず色々用途はありそうです

まとめ

実際にサービス開発に使うには認証など色々クリアする課題はありそうですが

環境作るのも手軽にできるのでモックだったりサクッと作ってフィードバックをもらいたい時とかにも使えるんじゃないでしょうか

個人的にはvimモードもあるしターミナルもあるし使いやすかったです

気になったのはターミナル上でのショートカット操作とブラウザのショートカットが被るとブラウザのショートカットが優先されるのでC+wでタブを閉じてしまったりといったところが「あー!!」となりました

最後にEC2インスタンス起動分の料金は掛かるのでそこだけ注意ですね

AdwaysのAWSアカウントをConsolidatebilling(一括請求)でまとめた話

Adways Advent Calendar 2017 14日目の記事です。

http://blog.engineer.adways.net/entry/advent_calendar_2017


はじめに

こんにちは、インフラDiv.の矢吹です。

最近はAWS×Ansible関連の仕事を多くさせて貰っています。
来月スプラトゥーンの企業対抗戦があると聞いて、
そろそろ封印していたNintendo Switchを起動しないといけないと思っている今日この頃です。

今日のお話

今日はAWS OrganizationsのConsolidated Billing(一括請求)という機能を使って、
Adwaysで使われているAWSアカウントの請求をまとめてしまおうという話について書こうと思います。

メリット

当初考えているメリットとしていたものは以下の三つで

  • 請求処理を簡略化する(アカウント数分のクレカ管理→1枚の請求書)
    → AWSアカウントごとにクレジットカードを作成していたので一括になることで経理側の負担が激減

  • 使用量のトラッキングを簡略化する
    → Adwaysとしてどれくらいの利用があるのかを簡単に確認出来るようになり、AWS担当者の方との話をしやすい&ディスカウント検討できる

  • ボリューム割引を適用しやすくする(コストメリットの期待)
    → Adways全体のEC2,RDS等を把握して全体から見たRI(リザーブドインスタンス)の購入をすることが可能

他にも進めているうちに副次的効果(こっちの方が大変でした)として

  • AdwaysのAWSアカウントの棚卸し
     → 知らないアカウントもあり、料金発生していたのに使われていないものを削除できた

  • AWSアカウント作成のルール化
    → 総務、経理、インフラで話し合い決定!

やってみると意外とこうした方がいいよね的なことも見つかったし、
AWS利用しているサービス担当者の方と情報交換出来たりしたことは個人的に良かったなって思っています!

Orgnaizationsの設定の仕方

はい!ではさらっとOrgnaizationsの設定を説明します。

AWS Organizationsをサービスから選択してー f:id:AdwaysEngineerBlog:20171220163222p:plain

Add accountしてー f:id:AdwaysEngineerBlog:20171220163232p:plain

Invite accountで子アカウントを入れてInviteすればok f:id:AdwaysEngineerBlog:20171220163240p:plain

後は子アカウント側に承認依頼が来るので承認すればAWS Organizationsでの親子関係の出来上がりです! 設定自体はすごく簡単に出来ました。

ただ、ここまではすごい順調に検証出来てたんですけど、子カウント側にデメリットが。。

個々のアカウントで請求金額を見た時にブレンドレートされてしまう(リザーブドインスタンスの料金が全体で按分された見え方になってしまう)

ってことでそれぞれのAWS請求金額が実際の使用料金と違う(見え方の)ようになってしまう問題が発覚。 どうしようかなって時にAWSの担当者の方に以下のサービスを提案してもらいました!

NTT Docomoさん Cost Visualizer
https://dev.smt.docomo.ne.jp/?p=common_page&p_name=cost_visualizer

Cost Visualizerとは

Consolidate Billingによって親アカウントに統合されている請求情報を取得し可視化してくれるものです! 雰囲気こんな感じ↓ f:id:AdwaysEngineerBlog:20171220163303p:plain

実際にデモ画面も見せてもらいました。 請求額月次推移とか
f:id:AdwaysEngineerBlog:20171220163314p:plain

ユーザーやバケットやロールごとの表示や
f:id:AdwaysEngineerBlog:20171220163325p:plain

RI/On demand/SPOTの損益分岐点計算もやってくれます!
f:id:AdwaysEngineerBlog:20171220163338p:plain

すごい綺麗!AWS担当者の方にもデモを見せたところ好評な意見を多数頂きました! そして導入もcloudformationで簡単に入れれそう!ってことで採用されました!

まだデモしか触ってないので社内調整が終わり次第、導入時に色々触って見ようと思います!

おわりに

今回はAdways全体でのリザーブドインスタンス購入は一旦stayでチーム毎に購入する方向になりましたが、
今後はCost Visualizerを利用したAWS料金使用料金が正確に出せるようになったら全体最適化したAWS利用を 推進出来たらなと思っています!ではまたいずれ!