pict3の日記

AWSネタを中心に

fluctでお手軽!EC2レスなAWS(API Gateway + Lambda)〜外部サービス(Questetra + Twilio)と連携する編【cloudpack 大阪 BLOG】

f:id:pict3:20150915210230p:plain

今回は、外部サービスと連携させて、もっともっとfluctを使ってみます。

連携させるのは以下のサービスです。

・Questetra 

・Twilio 

Questetraとは?

f:id:pict3:20150915214212p:plain

業務改善手法の一つに、BPMと言われるものがあります。

BPMは、UMLなどを策定しているOMGにて策定されています。

詳しくは本家サイトへ。

Questetraは、日本のQuestetra社によって開発されたBPMツールです。

BPMN(業務フロー図)を書くことで、webサービスや人的作業の流れを可視化するだけでなく、実際に処理をさばくことも出来てしまいます。

無料版もあるため、是非使ってみましょう!

 

Twilioとは?

f:id:pict3:20150915214223p:plain

Twilioは、インターネットと電話・SMSをつなぐAPIです。

コードから、電話をかけたり、SMSを送信したり出来てしまいます。

 

これらと、API Gateway & Lambdaを使って、自動モーニングコールシステムを組んでみます。

システムのイメージはこんなです。

 

f:id:pict3:20150915215908p:plain

Twilioの設定

こちらは、ネットに情報が多数落ちているので、細かい手順は割愛します。

アカウント作成後、ツールメニューに「電話をかける」ってのがあります。

必要事項を入力すると、ページの下部に書く言語向けのコードまで用意してくれます。

コピペで使いましょう。

ここでは、ちゃんと電話がかかることを確認しておいてください。

最初試したとき、ConditionalのUrlをブランクにしていたため、電話がかけられず少しハマりました。通話で話させたい内容をs3などに格納しておいてください。

 

API Gateway & Lambdaの構築

fluctで構築してしまいます。twilioを使うため、インストールしておきましょう。

$ fluct generate morningcall
$ cd actions/morningcall/
$ npm install twilio
$ cd ../.. $ vi actions/morningcall/package.json $ vi actions/morningcall/index.js

package.jsonでは、pathを"/morningcall"に変更しました。

index.jsは以下のようにしています。

// Twilio Credentials
var accountSid = '<accountSid>';
var authToken = '<authToken>';

var client = require('twilio')(accountSid, authToken);

exports.handler = function (event, context) {
    client.calls.create({
        to: "<かける側>",
        from: "<かけられる側>",
        url: "<http://hoge/voice.xml>",
        method: "GET",
        fallbackMethod: "GET",
        statusCallbackMethod: "GET",
        record: "false"
    }, function(err, call) {
        console.log(call.sid);
        context.succeed('Called!!');
});
};

 

ブラウザでアクセスしてみて、電話がかかってくることを確認してください。

 

Questetraの設定 

アカウントを作りましょう。今回は無料版を使わせてもらいました。

今回は数分で使用できるようになりました。便利です!

 

今回のフローは以下とします。

① 毎日8:00にプロセスを起動する

② 先程作成したAPI GatewayにHTTPリクエストを発行する

③ プロセスを終了する

適当な名前でプロセスモデルを作成し、BPMNを描きます。

BPMNは以下のようになりました。

f:id:pict3:20150917141136p:plain

BPMNについては、また別の機会に紹介したいと思いますが、

今回のは至極シンプルです。

BPMNをご存知ない方にもほとんど直感的に描けると思います。

 

左側のメニューは、「advanced」を選択してください。

開始イベントは、「タイマー開始イベント」を選んでください。

開始時刻は毎日8:00に設定します。

次に「メッセージ送信中間イベント(HTTP)」を配置します。

アクセスURLは、先程作ったAPI Gatewayのもの、HTTP Methodは「GET」を選択します。

最後に終了イベントで閉じます。

 

作成したプロセスモデルをリリースすることで、プロセスが稼働状態になります。

 

さて、このまま設定した8:00を迎えると。。。
電話がきました!!

 

わずかな時間で、モーニングコールをかけるシステムが出来てしまいました。

API Gateway + Lambdaに期待が高まります。

fluctでお手軽!EC2レスなAWS(API Gateway + Lambda)〜モジュール使う編【cloudpack 大阪 BLOG】

f:id:pict3:20150831125448p:plain

今回も、fluct入門編です。

サンプルを教材に、もう少し凝ったことをしてみます。

 

外部モジュールの読み込み

サンプルにjadeを利用したshow_rootアクションから、show_application_cssアクションを呼び出すものがあります。

いろいろ便利そうなので、実装してみたいと思います。

cloneでもいいかもですが、若干フォーマットも変わっているので手動で必要箇所を更新していきます。

それぞれactionを定義して、デプロイ!

# fluct generate show_root
# vi actions/show_root/index.js
# vi actions/show_root/package.json
# mkdir actions/show_root/views
# vi actions/show_root/views/index.jade
# fluct generate show_application_css
# vi actions/show_application_css/index.js
# vi actions/show_application_css/package.json
# vi actions/show_application_css/application.css
# fluct deploy

ブラウザでアクセスしてみると。。。

{errorMessage=Cannot find module 'jade', errorType=Error, stackTrace=["Function.Module._resolveFilename (module.js:338:15)","Function.Module._load (module.js:280:25)","Module.require (module.js:364:17)","require (module.js:380:17)","Object. (\/var\/task\/index.js:1:74)","Module._compile (module.js:456:26)","Object.Module._extensions..js (module.js:474:10)","Module.load (module.js:356:32)","Function.Module._load (module.js:312:12)","Module.require (module.js:364:17)"]}

失敗(゚´Д`゚)゚

jadeモジュールの読み込みに失敗しているようです。

var jade = require('jade');

その場合は、リソースのディレクトリに入って、npmでインストールしましょう。

# cd actions/show_root/
# npm install jade

node_modulesディレクトリ配下にjadeディレクトリが作られることで、lambda.zipに含まれるようになります。

ふたたび、デプロイ!

# cd actions/show_root/
# npm install jade

 

f:id:pict3:20150903195511p:plain

今度はうまく行った模様です!!

fluctにて外部モジュールを使用する場合は、呼び出し元アクションの配下にnode_modulesを置くことで、圧縮ファイルに追加されるようです。

 

おまけ情報

fluctには、デプロイせずともローカルでお試しする機能もあります。

$ fluct server
Server starting on http://127.0.0.1:3000
Loading event

コンソール出力も容易に見れるので、デバッグには便利!

AWS SDK for C++を使ってみる【cloudpack 大阪 BLOG】

f:id:pict3:20150904115238p:plain

AWSの公式ブログで、SDK for C++が紹介されていたので触ってみました。

 

環境

mac (OS X ver10.9.5)

 

準備

cmakeが未インストールであればインストールしておきます。

dmg形式で配布されているので簡単です。

ダウンロードサイトより、dmgを落として、インストールしましょう。

ただ、ここでインストールされるのはGUIツールのみです。

GUIツールを起動後、Toolsから、「How to Install For Command Line Use」とあるので、こちらを参考にCUIでも使えるようにしておきましょう。

f:id:pict3:20150904114310p:plain

 いろいろ方法があるようですが、ここでは環境変数に追加する方法を採りました。

 

次は、aws-sdk-cppのインストールです。

 GitHubにコードがあるのでダウンロードしてきます。コチラから。

ReadMeのとおり、以下の手順でインストールします。

# mkdir aws-sdk-cpp-bin
# cd aws-sdk-cpp-bin/
# cmake -DCMAKE_BUILD_TYPE=Release ../aws-sdk-cpp-master/
# make
# sudo make install

 

実装

ブログのサンプルコード(DynamoDB)の方を実装してみます。

※結果を先に言いますと、まだ動きません(;´д`)

ブログのコードを元に、ごにょごにょ#includeなどをすすめていきます。

結果はこんな感じに。

#include <aws/core/utils/Outcome.h>

#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeValue.h>
#include <aws/dynamodb/model/AttributeValueValue.h>
#include <aws/dynamodb/model/PutItemRequest.h>

#include <stdint.h>

using namespace Aws::DynamoDB::Model;


AttributeValue& AttributeValue::SetS(const Aws::String& s)
{
    m_value = Aws::MakeShared("AttributeValue", s);
    return *this;
}

int main(int argc, char** argv) 
{
Aws::DynamoDB::DynamoDBClient dynamoDbClient;

PutItemRequest putItemRequest;

putItemRequest.WithTableName("TableName");
AttributeValue hashKeyAttribute;
hashKeyAttribute.SetS("KeyName");
putItemRequest.AddItem("HashKey", hashKeyAttribute);
AttributeValue valueAttribute;
valueAttribute.SetS("SampleValue");
putItemRequest.AddItem("Value", valueAttribute);
auto putItemOutcome = dynamoDbClient.PutItem(putItemRequest);

if(putItemOutcome.IsSuccess())
{
std::cout << "OK!!\n";
//    std::cout << "PutItem Success Using IOPS " << putItemOutcome.GetResult().GetConsumedCapacity();
}
else
{
std::cout << "NG!!\n";
    std::cout << "PutItem failed with error " << putItemOutcome.GetError().GetMessage();
}

}

 

sdkのインストール時に、dylibが生成されているのでリンクします。 そのままだと、実行時にエラーがでるので、事前にlnしておきます。 その他、もろもろエラーをつぶしつつ、ビルドを通しました。

$ sudo ln -s /usr/local/lib/mac/Release/libaws-cpp-sdk-core.dylib /usr/lib/libaws-cpp-sdk-core.dylib
$ sudo ln -s /usr/local/lib/mac/Release/libaws-cpp-sdk-dynamodb.dylib /usr/lib/libaws-cpp-sdk-dynamodb.dylib
$ gcc -std=c++0x -lc++ -lm /usr/local/lib/mac/Release/libaws-cpp-sdk-core.dylib -lm /usr/local/lib/mac/Release/libaws-cpp-sdk-dynamodb.dylib -o test.o test.cpp

 

実行

。。。アウト(;´д`)

Credentialも設定していないので当たり前ですが。

 

$ ./test.o 
NG!!
PutItem failed with error Request is missing Authentication Token

Cognito辺りと連携が必要?

とりあえず、今日はここまで。

fluctでお手軽!EC2レスなAWS(API Gateway + Lambda)〜導入編【cloudpack 大阪 BLOG】

f:id:pict3:20150831125448p:plain

 

API Gatewayの登場によって、AWSの使いどころの幅がグッと広がったように思います。
とくにLambdaと組み合わせることで、EC2を使わないAWS環境もより実現しやすくなりました。

 

API GatewayLambdaの相性のたまものか、すでに両者を使うためのRailsのようなフレームワークが登場しています。フレームワークの名前はfluctと言い、r7kamuraさんにて開発されています。

今回は、fluctを使った簡単なwebサービスを作ってみます。

 

fluctのインストール

mac(10.10.5)にインストールしてみます。 fluctはNode.jsで動作します。インストールはnpmで行います。

また、fluctではaws-cliも内部で使うので、未設定ならこちらの設定も必要です。

$ brew install node
$ npm install fluct --global

インストールが終わったら、確認してみます。railsのようなコマンドが使えることが確認できます。

$ fluct --help

  Usage: fluct [options] [command]


  Commands:

    d|deploy             Deploy actions to AWS
    l|deployments        List recent deployments
    g|generate     Generate a new resource from  (e.g. "action")
    n|new          Generate a new application
    o|open               Open the production root URL in your browser
    r|routes             List all routes
    s|server [options]   Launch a web server

  Options:

    -h, --help  output usage information

 

fluctアプリケーションの構築

newコマンドでアプリケーションを作成します。

railsのように、ディレクトリが作られて、その中に環境のベースが作られます。

$ fluct new testapp
$ cd testapp/

次にリソースを作ります。ここでは、"hello"という名前のリソースを作ります。

'Hello, world!'と出力するスクリプトが自動生成されます。せっかくなのでちょっと変更してみましょう。

$ fluct generate hello
$ vi ./actions/hello/index.js
$ cat ./actions/hello/index.js
exports.handler = function (event, context) {
  context.succeed('Hello, no-ec2 world!');
};

つぎにリソースのpackage.jsonをいじります。今回はpathをリソース名に合わせておきます。

$ vi ./actions/hello/package.json
$ cat ./actions/hello/package.json
{
  "name": "hello",
  "private": true,
  "fluct": {
    "contentType": "text/html",
    "httpMethod": "GET",
    "path": "/hello",
    "statusCode": 200
  }
}

最後に、アプリケーション側のpackage.jsonを設定します。

IAMサービスにて、AWSLambdaBasicExecutionRoleのポリシーを付与したRoleを作っておきます。

AWSアカウントIDおよび上記のRole名を設定します。

$ vi ./package.json
$ cat ./package.json
{
  "name": "testapp",
  "private": true,
  "fluct": {
    "accountId": "123456789012",
    "restapiId": null,
    "roleName": "<Role名>"
  }
}

restapiIdはあとで自動的に割り振られるので、ここではnullでOKです。

初回デプロイ時に割り当てられて更新されます。

 

では、デプロイしてみましょう!

 

$ fluct deploy
Created zip: ./actions/hello/lambda.zip
Uploaded function: hello
Created restapi: hogefuga
Updated endpoint: GET /hello2
Deployed: https://hogefuga.execute-api.us-east-1.amazonaws.com/production

表示されたURLに、pathを付与してアクセスして確認します。 

f:id:pict3:20150831161617p:plain

生成されたAWSリソースも確認しておきましょう。

・Lambda

f:id:pict3:20150831163045p:plain

API Gateway

f:id:pict3:20150831163056p:plain

 

以上で、EC2を使わないWebアプリケーションがデプロイできました。

API Gateway + Lambdaのお勉強にも、構成を自動的に生成してくれるfluctは役に立ちそうです!

Amazon CloudFrontによるコンテンツ配信(originのs3にアクセス制限を付ける編)【cloudpack 大阪 BLOG】

f:id:pict3:20150828132346p:plain

 

前回はどこからでも参照可能なs3バケットをオリジンにしました。

そのため、s3から直接画像を取得することも可能でした。

今回は、CloudFrontからのみアクセスするように制限を掛けたいと思います。

イメージは以下です。

f:id:pict3:20150828173054p:plain

 

今回も、画像ファイルのみをCloudFrontより取得するようにします。

 

s3に画像をアップロード

バケットを作って、画像ファイルをアップロードします。

マネジメントコンソールにて、s3にバケットを作成して、画像をアップロードします。

今回は、バケットポリシーを設定しません。

なので、この時点では画像にアクセスできません。

 

CloudFrontの設定

ディストリビューションは前回使ったものを使います。

まずは、Originを作成します。

Origin Domain Nameは新たに作ったポリシーなしのバケットを選択します。

選択後、Restrict Bucket Accessの選択オプションボタンが現れます。

「Yes」を選びましょう。

未生成の場合は、Identifyを生成します。作成済みの場合は使い回しOKです。

Grant Read Permissions on Bucketは、「Yes, Update Bucket Policy」を選びます。

すると、自動的にs3のバケットに以下のようなポリシーが追加されます。

※すでに何らかのバケットポリシーを設定していた場合、追加されません。

{
"Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <Access ID>" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<backet名>/*" } ] }

これで、s3にCloudFrontからアクセス可能なポリシーが追加されました。

 

次に、追加したOriginに対応するBehaviorを追加します。

Patternは取り敢えず、「*」としておきます。

 

以上で、s3への直アクセスを禁止した、s3オブジェクトのCloudFront配信が可能となりました。

 

cloudpack.jp

Amazon CloudFrontによるコンテンツ配信(超入門編)【cloudpack 大阪 BLOG】

f:id:pict3:20150828132346p:plain

 

所属している会社が、業界最安値のCloudFrontサービスを開始しました。

cloudpack.jp

 

これを機に、改めてCloudFrontの使い方をおさらいしておきます。

 

はじめに

CloudFrontとは、コンテンツ配信向けのサービスです。

 HTTP、HTTPSおよびRTMPプロトコルをサポートしています。

 世界各地に散りばめられたエッジロケーションにアクセスするようコントロールされることで、低レンテンシーな配信が可能となっています。

f:id:pict3:20150828133315p:plain

 

 

今回は、webサーバー上の画像データを、CloudFrontから取得するように変えていきたいと思います。 

 

 以下のように、S3に配置した画像ファイルをCloudFront経由で表示させます。

検証は静的コンテンツなので、コンテンツもろともCloudFrontで配信したほうが早いのですが、敢えて画像ファイルだけとします。

f:id:pict3:20150828134047p:plain

 

s3に画像をアップロード

バケットを作って、画像ファイルをアップロードします。

マネジメントコンソールにて、s3にバケットを作成します。

作成したバケットのPropertiesからPermissionsを開き、バケットポリシーを設定します。

今回は取り敢えず、バケットポリシーにて全員に閲覧権限を付与します。

 Bucket Policy Editorが開いて、json形式でポリシーを記載します。

下部のSample Bucket Policiesを参考に(今回はそのまま)以下で設定します。

{
"Version":"2012-10-17", "Statement":[ { "Sid":"AddPerm", "Effect":"Allow", "Principal": "*", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::examplebucket/*"] } ] }

バケットに画像ファイルをアップロードしておきます。

 

 CloudFrontから配信

いよいよCloudFrontの設定です。

CloudFrontでは、ディストリビューション単位で管理します。

ディストリビューションを作成します。

今回は画像ファイルの取り扱いなので、Webで開始します。

Origin Domain Nameを設定します。先程作ったs3バケットが表示されるので選択します。

取り敢えず、今回は他のパラメータはそのままで。

 

以上で作業完了です。

CloudFrontを活用することで、簡単に低レンテンシーな環境を利用することができます。

 

次回以降は、もう少し掘り下げてCloudFrontを使っていきます。