AWSの話題を中心に、日々の業務やプログラミングの徒然を綴るエンジニアブログです。

HANDS LAB

HANDS LAB ENGINEERS BLOG

ハンズラボエンジニアブログ

AWS ElasticSearch Service の認証にIAM Roleを使う [Python編]

Pocket

AWS ElasticSearch Service の認証にIAM Roleを使う [PHP編] の続き、
Python編です。

Python でどうするのか、検索してみたところ、github の elasticsearch-py のライブラリレポジトリにて mathom がAWS の認証機能を追加するパッチつくったよー的な議論があって、最終的にマージされたようです。
なので、普通に elasticsearch-py でちょっと設定すれば使えるようです。

AWS ElasticSearch service · Issue #280 · elastic/elasticsearch-py

elasticsearch-py は、ElasticSearchのOfficial low-level clientとのことです。
今見ると、elasticsearch-py のドキュメントに、こんな感じで使えるよって書いてありました。

Python Elasticsearch Client — Elasticsearch 2.2.0 documentation

変更点も少なくて、ライブラリもそのまま使えていいですね。

Pocket

AWS ElasticSearch Service の認証にIAM Roleを使う [PHP編]

Pocket

こんにちは、井上です。

AWS ElasticSearch Serviceを使ってみました。
ElasticSearchはVPC外に置かれるとのことで、アクセス管理はどうするんだろうと思っていたら、AccessPolicyにて何かしら制限しないといけないようです。(VPC内に置いて欲しいなぁ…)

制限方法としては、

  • IPアドレスによる制限
  • アカウントIDによる制限
  • IAM Roleによる制限

などができるようです。

試しに、IAM Roleで制限をかけたEndpointにcurlでアクセスするとエラーがでることは確認できました。

ではどうやって認証を通るようにするかを探していてたどり着いたページ、
Amazon Elasticsearch ServiceのIAM Roleによるアクセス制御 | Developers.IO を見ると、

と、書かれていてメンドクサそうだな、と思ったのですが、下記にライブラリと共存させるやり方が書いてありました。

Signing an Amazon Elasticsearch Service Search Request — AWS SDK for PHP documentation

ElasticsearchのClientBuilderのHandler を定義することで、リクエスト署名を挿入してリクエストを送ることが出来るようです。

これを es_aws_test.php というファイル名で保存します。

inoue_test というインデックスが作られていることが確認できました。
この一連の手続きは結構長いので、この部分は Clientを生成する共通処理として作っておくとよさそうです。

あと、Node.js で Lambdaから ElasticSearch を更新するサンプルが awslabs に上がっていました。

amazon-elasticsearch-lambda-samples/s3_lambda_es.js at master · awslabs/amazon-elasticsearch-lambda-samples

実際に社内でも、Lambda からElasticSearchを更新する処理は稼働中とのことでした。早い!

Lambdaと同様に、ElasticSearch もVPC対応、期待しています。

[2016/01/28 追記]
アイキャッチ画像がクラスメソッドさん作成の画像との指摘を受け変更いたしました。ご迷惑をおかけしました。

Pocket

東急ハンズのiPad POSでRealmを使ってみた

Pocket

この記事は、Realm Advent Calendar 2015の22日目の記事です。

ハンズラボの黒岩です。

エンジニアブログに書くのが初めてなので軽く自己紹介させてください。
iOSアプリ開発・MDMを使った運用を主に担当しており、現在は東急ハンズの内製でiPad POSレジを開発しています。
(まだ、数店舗での導入しておらず、東急ハンズ・ハンズビー・ピカロ全店のレジを順次iPadに置き換える予定)

東急ハンズのPOSでは、多くの場面でRealmを使っています。

どの場面で利用しているか

  • 商品マスタ
  • 金券マスタ
  • 値引に関するマスタ
  • 取引情報
  • 支払情報
    などの保存に利用。

Realm採用に至った理由

  • パフォーマンスの良さ
  • アップデートが頻繁に行われており、将来性がある
  • 学習コストが少なく書き込み読み込みならすぐに理解が出来る
  • 自動マイグレーションでとても楽

毎朝90万件のデータをアップデート

商品、金券など、毎朝最新マスタのダウンロードします。
商品マスタだけで90万件分のデータがあり、JSONデータをダウンロード・マッピングした後、Realmに書き込みます。
ダウンロード・マッピング・書き込み処理合わせても15分ほどで終わり、Realmの書き込み速度の速さが素晴らしい。(近い将来、全件更新ではなく、差分更新にする予定)
現状、Realmが起因でのクラッシュ等の問題も見られず、順調に運用出来ています。

マスタ取り込み・Realmへの書き込み

お金を扱う処理は、 NSDecimalNumber で扱って計算を行いますが、
NSDecimalNumber のままRealmに保存できないため、下記のように数値をStringに変換して保存します。

1度に1万件ずつJSONデータを ObjectMapper でObjectにマッピングを行い、RealmObject に変換して書き込みます。

関連・オプショナル

取引に支払、複数の取引明細をもつなど、関連で簡潔に定義できる。
必要な場合のみセットするものはオプショナルで持つなどして対応できる。

マイグレーションが楽

Realm最新バージョンでは、例えフィールドがいくつ増えようとも増えても自動でマイグレーションが行われるため、
schemaVersionをインクリメントするだけの修正で済みます。

マッピングが辛かった

ObjectMapperのマッピングの抜け漏れがあって、Realmに保存されないフィールドが多々あった。
やはり手メンテ・目視でもメンテは辛い。

おわりに

軽く上辺だけ話になり、Realmの概要みたいになりましたが、
使い勝手がよくパフォーマンスの良いのでぜひ使ってみてください。

Pocket

AWSでしくじった話 (ElasticBeanstalk編)

Pocket

こんにちは、井上です。

最近好きな番組は「しくじり先生」です。
毎回、何かしらでしくじった諸先輩方が出演し、しくじった体験談と、それを元にした教訓をおしえてしてくれる番組なのですが、実体験に基づくだけあって教訓も説得力があり、非常にためになります。
辺見マリが洗脳されて5億円とられた話とか、生々しすぎて恐怖でした。

それにちなんで、今回はAWSの利用でしくじった話をしようと思います。

今回私がしくじったサービスは、ElasticBeanstalkです。

ElasticBeanstalkは簡単に説明すると、WEBアプリケーションのデプロイ、構成管理、オートスケールなどをまるっと面倒を見てくれる便利なサービスです。

2014年の4月くらいから利用検討を開始し、最初の頃は情報も少なく手探りの状態からスタートしました。
特に ebextensions で設定する構成管理の部分にクセがあり、どのようなタイミングでどのような処理が実行されるのかわからずに四苦八苦しました。

AWSのサポートに問い合わせたり、オークファンの得上さんに相談に乗ってもらったりしながら徐々に問題を解決していき、現在では複数のプロジェクトで活用するようになりました。
その試行錯誤の結果の秘伝のタレがこちらです。 ElasticBeanstalk .ebextensions 逆引き辞典

そんな運用もこなれてきた時に悲劇がおきました。
Applicationの消失です。

Applicationの消失

ElasticBeanstalkは、アプリケーションを配置する Application という単位の中に、開発環境、ステーング環境、本番環境といった様々な状態のものを動作させるための Environment という枠があります。

Environmentでは、アップロードされたいろいろなアプリケーションバージョンを選択し実行することができます。

こんなイメージです。

sikujiri_0

実際、消失したApplicationの中では、本番環境はもとより、ステージング環境、開発環境、○○向け開発用などいろいろなバージョンを動作させていました。また本番環境はBlue/Green Deploymentを実行するために本番待機系などもありました。
1つのEnvironmentには、ELB、EC2インスタンス、セキュリティグループ、AutoScalingGroupなどが含まれていましたが、それらもろとも消失しました。

なんで消えてしまったか

完全に私のオペレーションミスでした。
利用しなくなった古いApplication versionを掃除しようとしていて、誤ってApplication を削除してしまったのです。

以前、急にデプロイできなくなった問題が発生したことがあり、原因がApplication version数の上限に達したことによるものだったため、折を見て利用しなくなったApplication versionはポチポチと消してきれいな状態を保つようにしていました。その作業が裏目に出たのです。

sikujiri_1

sikujiri_2

押してしまったと同時に、全てのEnvironmentがグレーアウトしました。
一瞬何が起きたのか分かりませんでしたが、すぐに気づき血の気がサーっと引いていくのを感じました。

EC2インスタンスの一覧画面に行くと、今まさにターミネート処理中のインスタンスが並んでおり更に絶望しました。
またCSチームの方から「なんかエラーが起きてサービス見られない」という声が聞こえはじめました。

復旧作業

何が起きたのかを察した後は、冷静に冷静にと心のなかで唱えながら、復旧手順を考えました。

が、スクリプトを1つ実行すれば、Environmentが作成できるように自動化してあったことを思い出しました。
手動でApplicationを作成し、その中にEnvironmentを作成しデプロイするスクリプトを流しました。

スクリプト1発とはいえ、Environmentを作成するには、ELBの作成、AutoScalingGroupの作成、インスタンスの起動、アプリケーションのデプロイなど一連のリソース作成が流れるので10分くらいかかります。
それを待っている間の生き地獄感といったらありません。

何か失敗するのではとドキドキしながら待っていたのですが、無事立ち上がってCNAMEを書き換えるとアプリケーションが正常に動作しはじめました。

削除してしまってから、復旧まで約15分でした。

教訓

これらの事象から学べる点を上げてみたいと思います。

手作業はときどき失敗する

まず失敗点として、手作業で大事な作業を行っていたことです。手作業は必ずミスをする可能性があるので、繰り返し行う作業はスクリプト化するなど、間違えないようにしておく必要があると思いました。

一方で環境構築のための手順はコード化されていたため、復旧にかける時間が短くて済みました。
ElasticBeanstalkでAutoScaleを導入する前は、そもそもテレビで取り上げられると30分くらいつながらなくなっていたのでそれよりも短かったと言えます。

IAM権限は最低限

IAM権限の調整により、危険な作業は行えないようにしておくべきと思いました。

マネージメントコンソールを使う際は緊張感をもつ

ElasticBeanstalkの操作に慣れてきていたため、緊張感も足りなくなっていました。
AWSのマネージドコンソールは、結構危険な作業もサクッと行えてしまったりします。
頻繁に使う人ほど慣れてしまって緊張感がなくなるのではないでしょうか。

アプリケーションは状態を持たない

今回のアプリケーションは、データは、DynamoDBやS3など、マネージドシステムに配置しており、インスタンスに状態を持たないようになっていたためインスタンスを立ち上げ直せばすぐに復旧できるようになっていました。
このあたりは、ElasticBeanstalkを使っていて本当に良かったと思いました。

データについては、マネージメメントシステムとはいえ、別の方法にて保全しておき、スムーズに復旧できる手順を確立しておく必要があります。

復旧訓練の必要性

クラウドは便利な反面、怖いと実感しました。

クラウドの導入により、ハードウェア的な障害は避けられるようになりましたが、論理的な障害は防げません。
災害に備えて避難訓練を行うように、クラウドならではの障害にそなえ訓練しておく必要があるのではないでしょうか。
最悪のケースとして、AWSアカウントごと消した場合にどれくらいの時間で企業活動を復旧させることができるか?というのを考えてみるだけでも、やるべきことは見えてくるように思います。

AWSへ望むこと

  • Deployボタンの横にDeleteボタンが配置されているなど、UI上ちょっと工夫してほしいなぁと思う部分が見受けられます。
  • 危険な操作をするときには、クリックだけではなくキーボード入力をしないと実行できないようにしてほしいです。
    • Githubでは、レポジトリを削除する際には、レポジトリ名を入力しないと実行できなくなっています。あれはとても良いインターフェイスですね。

最後にお詫び

無事復旧できましたが、障害時にまさに利用しようとしていたお客様は、急につながらなくなって残念な思いをされたかと思います。この場を借りてお詫びいたします。

Pocket

Twilioで世界に通用する再配達自動応答システムを作る

Pocket

この記事は、Twilio Advent Calendar 2015 の21日めの記事です。
といいつつ、Twilioはほとんど触ったことなかったので、練習として佐川急便の再配達受付みたいなものをつくってみました。

デモ電話番号: 050-3159-5616 (かけると再配達受付っぽいものが動きます)

Twilioに作成した電話番号にかかってくると、Twilioがこちらの指定したURLにリクエストを送ってくれるようで、
こちらでは、それにレスポンスするAPIを用意すれば良いようです。

こんな感じですね。

twilio_uml

まずは、Twilioに設定する初期URLにあたるXMLを作ります。
これは、特に動的な部分はないので単なるXMLです。

File: index.xml

Say のタグに書いた内容を読み上げてくれるようです。language を指定すれば日本語も行ける。すごい。
あと、numDigits で桁数と、次のアクション(APIコール先)として twilio_2.php を指定しました。

7桁の番号が押された時に遷移する次のアクションの twilio_2.php はこんな感じです。
伝票番号の読み上げのところで、Playタグを使ってみました。
Playタグは、音声ファイルを再生してくれるタグのようです。
伝票番号の確認をし、良ければ1、修正する場合には 9 を押して貰うように促します。

File: twilio_2.php

入力された番号(1か9)によって条件分岐するのが、次のアクションの twilio_3.php です。
1 が入力されてたら、再配達希望日時を聞くフローへ、それ以外の場合には最初のフローへ戻すようにアクションを指定しました。

File: twilio_3.php

こんな感じで、ちょいちょいとXMLを返していくだけで、佐川の再配達受付システムができてしまいます。
初心者でしたが、3時間くらいで作ることができました。

ちゃんと作るには、DBとの連携とかいろいろやらなければならないですが、この時間でこれだけのものが作れるのはホント驚きです。

あ、タイトルで「世界に通用する」というのは、伝票番号の復唱のとき、3の倍数の時だけアホな感じで読み上げるからです。古いですね… すみません。

最後に

オフィスでアホな音声を発してくれた青柳さん、藤倉さんありがとうございました。

Pocket