この記事は富士通クラウドテクノロジーズ Advent Calendar 2017の12日目の投稿です。
11日目は@yaaamaaaguuuの今年一年間の知見に関する記事でした。私の過去10年間の知見よりも多くて正直焦りました。
#はじめに
私はニフクラのサービス開発エンジニアとして携わっていますが、様々な内外的要因とタイミングとあれやこれやあり今年の7月からマネージャーというポジションで仕事しています。
マネージャーであるからには、言いづらいけど言わないといけないこともはっきりとチームメンバーに伝える必要があります。しかし新米へっぽこマネージャーはひとくせもふたくせもある優秀なエンジニアのチームメンバを相手にいつも四苦八苦してしまいます。
今回は私のようなヘタレでもチームメンバーに伝えたい事を伝えらるようなお話です。
#手段
エンジニアチームの話なのでコミュニケーションにもエンジニアリングを極力用いるのがいいでしょう。今回はニフクラのサーバーレスサービスのスクリプトとオープンソースで豊富なプラグインが魅力的なAPIGateWay基盤であるKONGを活用して言いたいことを言ってみようと思います。やっとタイトル通りの記事っぽくなってきましたね。
#環境
- Docker version 17.11.0-ce
- KONG 0.11.2
- Postgresql 9.4
- ニフクラスクリプト
導入
まずはKONG
とそのデータストアであるPostgresql9.4
をマニュアルを基にDockerで構築します。
Postgresql構築〜起動
$ docker run -d --name kong-database \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.4
スキーマなどをマイグレーション
$ docker run --rm \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations up
KONG構築〜起動
$ docker run -d --name kong \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:latest
docker ps -a
をして確認してみましょう。kong
とkong-database
がUPしてればOKです。
スクリプト作成
今回はクイックスタートにあるスクリプトをそのまま使ってみようと思います。
上記ページに従ってスクリプトを作成します。
KONGにnifcloud-script pluginを配備して再イメージ化
KONGはデフォルトでaws-lambdaという公式プラグインがありますが、残念ながらニフクラスクリプト用のプラグインはありません。
なので新規にプラグインを作成してインストールさせる必要があります。
プラグインの作成にあたっては公式のPlugin development - Introductionを読みながら作成します。
今回は他のlua-nginx-moduleを参考にこちらを作りました。
配備後はcommitしておきます。
$ git clone https://github.com/Ken-Moriizumi/kong-nifcloud-script-sample.git nifcloud-script
$ docker cp nifcloud-script kong:/usr/local/share/lua/5.1/kong/plugins/
$ docker commit kong kong:nifcloud
KONGへプラグインをインストール
上とほぼ同じですがKONG_LOG_LEVEL
とKONG_CUSTOM_PLUGINS
という環境変数が追加になっています。
また、立ち上げるのは先程commitしたイメージから立ち上げます。
$ docker run -d --name kong \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_LOG_LEVEL=debug" \
-e "KONG_CUSTOM_PLUGINS=nifcloud-script" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:nifcloud
立ち上がったらdocker logs kong
を実行してnifcloud-script
プラグインがロードされていることを確認します。
環境構築はこれで完了です。
実行
API作成
KONGのマニュアルに従って新規APIを作成します。upstream_url
は通常転送先のURLを設定するのですが、今回はaws-lambda
同様プラグイン内で強制的にニフクラスクリプトに転送するのでなんでも構いません。
curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'name=nifcloud-api' \
--data 'hosts=nifcloud' \
--data 'upstream_url=http://nifcloud.com'
nifcloud-script プラグイン有効化
次に上記で作成したAPIに対してnifcloud-scriptプラグインを有効化します。
この時アクセスキーとシークレットキーを指定します。
curl -X POST http://localhost:8001/apis/nifcloud-api/plugins \
--data "name=nifcloud-script" \
--data-urlencode "config.access_key=<nifcloud-access-key>" \
--data-urlencode "config.secret_key=<nifcloud-secret-key>" \
--data "config.region=jp-east-1" \
--data "config.function_name=dummy"
クライアント作成〜実行
これでKONGを使用したニフクラスクリプトのAPIGateWayができました。
curlを使ってAPIGateWay経由でニフクラスクリプトを叩いてみます。
$ curl -i -X POST --url http://${KONG_HOSTNAME}:8000/${EXEC_SCRIPT_NAME} --header 'Host: nifcloud'
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Connection: keep-alive
ETag: W/"27a-Wjd06nqimAWgaLmPnQYR1T3HGno"
Content-Length: 634
Access-Control-Allow-Origin: *
Date: Thu, 07 Dec 2017 07:25:36 GMT
Connection: keep-alive
Server: kong/0.11.2
<?xml version="1.0"?><ExecuteScriptResponse><requestId>5f08a68c-ea04-41e6-9374-615059356498</requestId><ExecuteScriptResult><Result><console><log/><err/></console><ResponseStatus>200</ResponseStatus><ScriptIdentifier>test1.js</ScriptIdentifier><RequestQuery><![CDATA[{"name":"merryChristmasAndHappyNewYear!!"}]]></RequestQuery><RequestBody><![CDATA[{}]]></RequestBody><ResponseHeader><![CDATA[{"Content-Type":"text/plain"}]]></ResponseHeader><RequestHeader><![CDATA[{}]]></RequestHeader><ResponseData><![CDATA[merryChristmasAndHappyNewYear!!]]></ResponseData><Status>200</Status></Result></ExecuteScriptResult></ExecuteScriptResponse>c
KONG_HOSTNAME
はAPIGateWayを構築したドメインもしくはIPアドレス、
EXEC_SCRIPT_NAME
は上で保存したニフクラのスクリプト名を設定します。
無事200応答が帰ってきましたが、これではさすがのエンジニアもちょっと何言ってるのかわかりません。
なので簡単なクライアントを作りました。
#!/bin/ruby
require "httpclient"
require "rexml/document"
client = HTTPClient.new
body = ""
header = {
"Host" => "nifcloud"
}
res = client.post(
"http://#{ENV['KONG_HOSTNAME']}:8000/#{ENV['EXEC_SCRIPT_NAME']}",
body,
header
)
doc = REXML::Document.new res.body
puts doc.elements['ExecuteScriptResponse/ExecuteScriptResult/Result/ResponseData'].text
# bundle exec ruby api-gateway-client.rb
merryChristmasAndHappyNewYear!!
これでシンプルかつ明確にみんなへクリスマスと新年の挨拶をすることができました。
挨拶はマネジメントというよりそもそもコミュニケーションの基本ですし、lowerCamelにすることでちょっと親密なprivate感も醸せます。TPOに応じて使い分けましょう。
難点といえば自作プラグインの作りが少々雑なため他のメッセージを送信できないことくらいでしょうか。
おわりに
今回は必要であったためプラグインを作成しましたが、KONGはデフォルトで豊富なプラグインが同梱されているため、ライトな用途であればほぼそのまま現場に導入可能な印象を受けました。
ただJavaを一切使っていないのに出力をlowerCamelにしてしまったことは反省しています。
是非みなさんもKONGを使ったコミュニケーションでAPIマネジメントだけでなくチームのマネジメントをしてみましょう。
あしたは@tunakyonnの「Unity WebGLをmBaaSで使ってみた」です。お楽しみに!