Category: AWS Lambda*


AWS のサイトですか? AWS Lambda を使用したドメインの識別

以下のゲスト投稿で、私の同僚である Tim Bray は IsItOnAWS.com を構築した方法について説明しています。このサイトは、AWS の IP アドレスレンジのリストと Tim が記述した AWS Lambda 関数を使用して、お気に入りのウェブサイトが AWS で実行されているかどうかを調べることを目的としています。

Jeff;


AWS のサイトですか?
クリスマスの時期に遊び半分でプログラミングをしていたら、おもしろい Lambda 関数ができました。きっと気に入ってもらえると思います。指定したドメイン名 (または IP アドレス) (IPv6 でも可能) が、公表されている AWS IP アドレスレンジ に含まれているかどうかを調べてくれます。IsItOnAWS.com で実際に試してみることができます。構築の過程では、1 つの Lambda 関数で別の Lambda 関数を作成しています。JSON 形式の IPv4 および IPv6 CIDR で提供されているレンジのリストはここです。説明書はここで、Jeff Barr のブログ もあります。以下は、JSON 形式の IP レンジの例です。

{
  "syncToken": "1486776130",
  "createDate": "2017-02-11-01-22-10",
  "prefixes": [
    {
      "ip_prefix": "13.32.0.0/15",
      "region": "GLOBAL",
      "service": "AMAZON"
    },
    ...
  "ipv6_prefixes": [
    {
      "ipv6_prefix": "2400:6500:0:7000::/56",
      "region": "ap-southeast-1",
      "service": "AMAZON"
    },

これを見た瞬間、「IsItOnAWS.com ができるのではないか」と思いました。可能だと分かったので、これを構築しました。以下のようなサイトにしたいと思いました。

  1. サーバーレス (クールな人たちはみんなそうしているので)
  2. シンプル (数字の範囲の中で数値を調べるというシンプルな課題なので)
  3. 高速。当然ですよね。

 

データベースか否か
構築はとても明快に思えました。IP レンジを表にまとめ、アドレスを調べるということです。テーブルはどこに配置すればいいでしょうか。Amazon DynamoDB にしようかと思いましたが、実質的に数値のレンジから検索するのは明快ではありませんでした。明快な所で SQL データベースも考えましたが、上記の 2 番目に当てはまりません。Redis やそれに似た方法を考えましたが、インスタンスのプロビジョンが必要で、上記の 1 番目に当てはまりません。数日間この問題を考え続けて行き詰ってしまいました。その時、1 つの疑問が浮かびました。レンジのリストはどれほど大きいのだろう。エントリの数は 1000 未満であることが分かりました。そうであれば、そもそもデータベースは必要ないのではないでしょうか。JSON を配列して、バイナリサーチすることにします。そうすると、配列はどこにすればいいでしょうか。Amazon S3 なら簡単でしょう。でも、上記の 3 番目を見てください。S3 は高速ですが、すべてのリクエストのループにそれが必要でしょうか。それで、配列リテラルとしてレンジを含む小さなファイルを生成し、それを IsItOnAWS Lambda 関数自体の中に含めることにしました。この方法だと、IP アドレスが変更されるたびに関数を再構築してアップロードする必要があります。アドレスを気にするのであれば、Amazon Simple Notification Service (SNS) トピックへの受信登録をし、変更されるたびに通知が届くようにできます (最近の私の経験によると、週に 1、2 回の頻度です)。そして、サブスクリプションを Lambda 関数に結び付けておきます。これで、だれもが必要とする道具をそろえることができたと感じました。Lambda 関数は 2 つあります。1 つめは、 newranges.js で、変更通知を取得し、IP レンジのデータから JavaScript を生成して、2 つめの Lambda 関数である isitonaws.js へアップロードします。これには JavaScript が含まれています。注意深い読者の方は、これはすべて Node ランタイムに関係するとお分かりでしょう。典型的な async または waterfall である新しいレンジ関数は、当初思っていたよりはやや複雑です。

Postmodern IP アドレス
最初のタスクは IP レンジの取得で、直接的な HTTP GET です。その後、JSON をより検索しやすい形にします。当然ですが、IPv4 と IPv6 の両方のレンジがあります。作業を容易にするため、単純な文字列や数字のマッチングで検索できる 1 つの配列にまとめようと思いました。IPv6 アドレスは JavaScript の数値で扱うには大きすぎるので、文字列にする必要があります。IPv4 のスペースが IPv6 の ("::ffff:0:0/96") に組み込まれている方法はやや驚きでした。BMP マッピングが低ビットの Unicode に組み込まれているようなものだと思っていました。このような方法になっているのはなぜかと漠然と考えはしましたが、調査はしていません。すべての CIDR をクラッシュして整然とした検索可能な配列にするコードは煩雑になりましたが、目的は達成できます。

Lambda の中に Lambda を構築する
次に、実際に IsItOnAWS リクエストを扱う Lambda を構築します。zip ファイルである必要があり、NPM に作成に必要なツールがあります。後は、圧縮されたバイトを S3 に詰め込んでアップロードすれば、新しい Lambda 関数を作成できます。鋭い方はお気づきでしょうが、いったん zip を作成すれば、直接 Lambda にアップロードできます。フローを精錬するために後で生成された「レンジ」データ構造をダウンロードして確認したかったので、S3 を中間のステップとして使用しました。実際の IsItOnAWS ランタイムは、名前でアドレスを探すために DNS を「たたく」ことと、レンジ配列に使用したのと同じ形式にするために多少工夫すること以外は、かなりシンプルです。HTML テンプレートの作成などはせず、zip の中のファイルを読み込み、表示されない <div> があれば、それを結果に置き換えただけです。ただ、バイナリサーチの手法をコードにする必要はありました。10 年に 1 度あるかないかの作業でしたが、楽しくできました。ピースをまとめるすべてのコードを実行できるようになったら、Amazon API Gateway を使用して世界につなげてみたくなりました。以前これを実行したときは複雑な作業でしたが、今回は「プロキシリソースを通じて Lambda プロキシと統合された API を作成する」を参照していたので、比較的単純で予想外の事態はほとんど生じないと思えました。ただ、その説明は主に API の構築 (例:JSON in/out など) についてで、実際の使用例にはあまり触れられていません。実際に HTML を人に送信してブラウザに読み込ませる方法などは書かれていませんでしたが、その方法を考えるのは難しくありませんでした。以下はその方法です (Node より)。

context.succeed({
  "statusCode": 200,
  "headers": { "Content-type": "text/html" },
  "body": "<html>Your HTML Here</html>"
});

一度すべてを API Gateway に接続できたら、最後のステップは isitonaws.com をそこに向かわせることです。そのため、このコードを記述したのは 12 月から 1 月にかけてでしたが、ブログにまとめるのは今になっています。当時は、Amazon Certificate Manager (ACM) 証明書は API Gateway で使用できませんでした。そして、時は 2017 年になり、証明書を承認して接続するのに古い学校の式典のようなことをする暇はありません。ACM により、証明書のプロセスはまったく思考を要しないものになっています。ACM と Let’s Encrypt が世に出たおかげで、今や非 HTTPS サイトを作成する理由は何もなくなりました。両方ともすばらしいツールですが、私のように API Gateway や CloudFront など AWS のサービスを使用している方であれば、ACM のほうがなじみやすいでしょう。自動更新もされる点は、きっと気に入るはずです。それで今や、ドメイン名を HTTPS と CloudFront 経由で API Gateway API に接続するのはとても簡単にできます。「API Gateway API のホスト名としてカスタムドメイン名を使用する」を参照してください。初めて試して、私の場合はうまくいきましたが、注意点があります (2017 年 3 月時点の話ですが)。最後のステップで ACM 証明書を API に接続する時、数分間、接続のために待機しなければなりませんが、これは普通のことです。幸い、私はあまり気にしていなかったため、あせって更新やキャンセルその他の操作はしませんでしたが、もしそうしていたら問題が生じていたかもしれません。ところで、API Gateway を使用する副次的な効果として、CloudFront を通してすべて実行されます。そのため、データベースを使わないので、高速な処理を期待できます。実際、ここバンクーバーでの話ですが、処理は高速に行われています。速度を計測する必要がないほど高速です。「IP レンジの変更」 SNS トピックに E メールで受信登録もしているので、変更があれば随時 E メールが送信されます。私はその通知を見てうれしくなります。自分の Lambda が新しい Lambda を記述して、すべてが自動で、手を煩わされずに、スムーズかつ高速に行われていると分かるからです。

Tim Bray、シニアプリンシパルエンジニア

Amazon ECS におけるコンテナ インスタンス ドレイニングの自動化方法

同僚のMadhuri Periが素晴らしい記事を書いてくれました。AutoScalingグループのクラスタをスケールダウンする際にインスタンスからタスクを事前に削除するために、コンテナ インスタンス ドレイニングを利用する方法です。

—–

Amazon ECSクラスタでは、クラスタからインスタンスを削除する必要があるタイミングというのがいくつかあります。例えば、システムを更新するとき、Dockerデーモンを更新するとき、あるいはクラスタのサイズをスケールダウンするときなどです。コンテナ インスタンス ドレイニング機能によって、クラスタ上のタスクに影響を与えることなく、コンテナインスタンスを削除することができます。この機能により、コンテナインスタンスがDRAINING状態である間はそのインスタンスに対して新しいタスクの配置がスケジュールされないようになり、利用可能なリソースがあればサービスがタスクをクラスタ上の他のコンテナインスタンスに移動してくれ、インスタンスを削除する前にタスクの移動が成功したことを待機できるようになります。

コンテナインスタンスの状態は、手動でDRAININGに変更することが可能です。しかしこの記事では、これらのプロセスを自動化するためにAutoScalingグループAWS Lambdaを利用してコンテナ インスタンス ドレイニングを行う方法を説明します。

Amazon ECS オーバービュー

Amazon ECSはコンテナ管理サービスです。クラスタやEC2インスタンスの論理グループ上でDockerコンテナの実行、停止、そして管理を容易にしてくれます。ECSを使ってタスクを実行するとき、タスクはクラスタに配置されます。Amazon ECSは指定されたレジストリからコンテナイメージをダウンロードし、そしてそのイメージをクラスタ内のコンテナインスタンス上で実行します。

コンテナ インスタンス ドレイニングの状態を扱う

AutoScalingグループはライフサイクルフックをサポートしています。ライフサイクルフックは、インスタンスの起動や削除の前に独自の処理を完了するために呼び出されます。今回の例では、ライフサイクルフックは、2つの処理を実行するLambdaファンクションを呼び出します。

  1. ECSコンテナインスタンスの状態をDRAININGに変更します。
  2. コンテナインスタンス上にタスクが1つも残っていないことを確認します。もしドレイニング中のタスクがまだ存在する場合は、Lambdaファンクションを再度呼び出すためにSNSにメッセージを送信します。

コンテナインスタンス上で実行中のタスクがなくなるか、あるいはライフサイクルフックのハートビートタイムアウト(サンプルのCloudFormationテンプレートではTTL15分に設定)に達するか、どちらかの状態になるまでLambdaによってステップ2が繰り返されます。その後、制御はオートスケーリングのライフサイクルフックに戻され、そのインスタンスは削除されます。このプロセスを次の図に示します。

Architecture

試してみましょう!

この記事で説明した一連のリソースをセットアップするためにCloudFormationテンプレートを使用します。このCloudFormationテンプレートを使用するには、あなたのアカウントのS3バケットにLambdaデプロイメントパッケージをアップロードする必要があります。このテンプレートは次のリソースを作成します。

  • VPCと関連するネットワーク要素(サブネット、セキュリティグループ、ルートテーブルなど。)
  • ECSクラスタ、ECSサービス、そしてサンプルのECSタスク定義
  • 削除のライフサイクルフックと2つのEC2インスタンスが設定されたAutoScalingグループ
  • Lambdaファンクション
  • SNSトピック
  • Lambdaを実行するために必要なIAMロール

CloudFormationスタックを作成し、インスタンスの終了イベントをトリガーすることによってどのようにこのスタックが機能するのか見ていきます。

Amazon EC2のコンソールにおいて、AutoScalingグループを選択し、CloudFormationによって作成されたAutoScalingグループの名前(CloudFormationテンプレートのリソースのセクションから)を選択します。

操作編集を選択し、インスタンスの希望の数を “1” に減らすようにサービスを更新します。これによって、2つのインスタンスのどちらか一方で終了プロセスが開始されます。

AutoScalingグループのインスタンスタブを選択します。1つのインスタンスのライフサイクルの状態が “Terminating:Wait” という値を示すはずです。

asg-draining
この状態になると、ライフサイクルフックが発火してSNSにメッセージが送信されます。そして、SNSメッセージトリガーに反応してLambdaファンクションが実行されます。

Lambdaファンクションによって、ECSコンテナインスタンスの状態がDRAININGに変更されます。その後、ECSサービススケジューラによってこのインスタンス上のタスクは停止され、利用可能なインスタンス上でタスクが起動されます。

ECSのコンソールに移動すれば、コンテナインスタンスの状態がDRAININGになっていることを確認できます。

ecs-draining
タスクが全て完了すると、AutoScalingグループのアクティビティ履歴でEC2インスタンスの削除を確認できます。

events-draining

どのように動作しているか

少しLambdaファンクションの内部的な動作を見てみましょう。ファンクションはまず最初に、受け取ったイベントのLifecycleTransitionの値が autoscaling:EC2_INSTANCE_TERMINATING にマッチするかをチェックします。

# もし受け取ったイベントがインスタンス終了中ならば・・・
if 'LifecycleTransition' in message.keys():
    logger.debug("message autoscaling %s",message['LifecycleTransition'])
    if message['LifecycleTransition'].find('autoscaling:EC2_INSTANCE_TERMINATING') > -1:

マッチする場合は “checkContainerInstanceTaskStatus” という関数が呼び出されます。この関数は、受け取ったEC2インスタンスIDのコンテナインスタンスIDを取得しコンテナインスタンスの状態を ‘DRAINING’ に変更します。

# ライフサイクルフックの名前を取得
lifecycleHookName = message['LifecycleHookName']
print("Setting lifecycle hook name {} ".format(lifecycleHookName))

# インスタンス上で実行中のタスクがあるかをチェック
tasksRunning = checkContainerInstanceTaskStatus(Ec2InstanceId)

続いてインスタンス上で実行中のタスクがあるかがチェックされます。実行中のタスクが存在する場合、このLabmdaファンクションを再度トリガーするためにSNSトピックにメッセージが発行され、このLambdaファンクションのプロセスは終了となります。

# タスクの詳細を得るためにタスクARNを使用
descTaskResp = ecsClient.describe_tasks(cluster=clusterName, tasks=listTaskResp['taskArns'])
for key in descTaskResp['tasks']:
    print("Task status {}".format(key['lastStatus']))
    print("Container instance ARN {}".format(key['containerInstanceArn']))
    print("Task ARN {}".format(key['taskArn']))

# 実行中のタスクがあるかチェック
if len(descTaskResp['tasks']) > 0:
    print("Tasks are still running..")
    return 1
else:
    print("NO tasks are on this instance {}..".format(Ec2InstanceId))
    return 0

Lambdaファンクションは、コンテナインスタンス上に実行中のタスクがない時には、ライフサイクルフックを終了しこのEC2インスタンスの削除に進みます。

# ライフサイクルフックの完了
try:
    response = asgClient.complete_lifecycle_action(
    LifecycleHookName=lifecycleHookName,
    AutoScalingGroupName=asgGroupName,
    LifecycleActionResult='CONTINUE',
    InstanceId=Ec2InstanceId)
    print("Response = {}".format(response))
    print("Completedlifecycle hook action")
except Exception, e:
    print(str(e))

 

まとめ

コンテナ インスタンス ドレイニングによって、クラスタのスケールダウンや新しいAMIのロールアウトのような運用業務がシンプルになります。例えばこの記事で説明された構成に加えて、CloudFormationやCodePipelineを利用して、新しいインスタンスの起動や終了を一括実行するローリングデプロイメントの環境を構築することもできます。

コンテナ インスタンス ドレイニングについてもっと知りたい場合は、Amazon ECS 開発者ガイドを参照してください。

ご質問やご提案があれば、ぜひ以下にコメントしてください。

(翻訳はSA畑が担当しました。原文はこちら)

 

AWS Lambda – 2016 年を振り返って

2016 年は AWS Lambda、Amazon API Gateway、そして、サーバーレスコンピューティングテクノロジーにとって、控えめに言ってもすばらしい年となりました。もしかすると、AWS Lambda および Amazon API Gateway でのサーバーレスコンピューティングについて耳にしたことがない方がいらっしゃるかもしれませんので、これらのすばらしいサービスについてご紹介したいと思います。AWS Lambda を使用すると、サーバーをプロビジョニングまたは管理しなくてもコードを実行できます。このイベント駆動型のサーバーレスコンピューティングサービスにより、開発者は、ほぼすべての種類のアプリケーションまたはバックエンドで機能を簡単にクラウドへ移行できます。Amazon API Gateway は非常にスケーラブルで、信頼性が高く、堅牢な API を大規模にすばやく構築するのに役立ち、作成した API の維持およびモニタリングの機能も提供します。2016 年のサーバーレスの勢いの締めくくりとして、AWS チームは re:Invent でサーバーレスソリューションの構築をさらに簡単にする強力なサービス機能を発表しました。その機能には次のものがあります。

Jeff が Step Functions などの分散アプリケーションやマイクロサービスを構築するための前述の新しいサービス機能についてほとんど紹介したので、一般的なサーバーレスユースケースの例であるリアルタイムのストリーム処理を使って、まだ説明されていない最後の 4 つの新しい機能について紹介しましょう。ストリーム処理のユースケースについてのこの説明では、データのストリームを処理する Lambda 関数から送られることのあるエラー通知のために、デッドレターキューを実装します。ストリームの処理には Node.js で記述された既存の Lambda 関数を用い、C# 言語を使って書き換えます。その後、API Gateway と AWS Marketplace の統合を利用して Lambda が支援する API の収益化の例を構築します。これは楽しみです。それでは、始めましょう。サンフランシスコとオースティンでの AWS 開発者デーの期間中、私はリアルタイムのストリーム処理で AWS Lambda を活用する例を、Twitter ストリーミング API を使ったストリーミングソリューションを見せるデモを作成して紹介しました。この例の方法に沿って、デッドレターキュー (DLQ)、C# サポート、API Gateway 収益化の特徴、API Gateway Developer Portal のオープンソースのテンプレートを紹介していきます。デモでは、「awscloud」または「serverless」 (またはその両方) のキーワードを含むコンソールまたはウェブアプリケーションのストリームのツイートを Twitter ストリーミング API から集めました。それらのツイートはリアルタイムで Amazon Kinesis Streams に送信され、Lambda が新しいレコードを検出し、NoSQL データベースである Amazon DynamoDB にツイートを書き込むことでストリーミングのバッチを処理します。これで、リアルタイムのストリーミング処理のデモのワークフローを理解できたので、Kinesis からのバッチレコードを処理する Lambda 関数についてより詳しく見てみましょう。まず、以下のとおり、Lambda 関数 DevDayStreamProcessor には、バッチサイズが 100 で DevDay2016Stream という名前の Kinesis ストリームであるイベントソース、またはトリガーがあります。Lambda 関数は新しいレコードのために定期的にストリームをポーリングし、レコードのバッチ、このケースではストリームで検出されたツイートを自動的に読み取って処理します。

次に、Node.js 4.3. で記述された Lambda 関数のコードを調べます。以下に示す Lambda 関数のセクションは、Kinesis ストリームからのツイートレコードのバッチをループし、各レコードを解析し、一連の JSON データに必要なツイート情報を書き込みます。一連の JSON のツイート項目は Lambda ハンドラーの外部にある ddbItemsWrite 関数に渡されます。

'use strict';
console.log('Loading function');

var timestamp;
var twitterID;
var tweetData;
var ddbParams;
var itemNum = 0;
var dataItemsBatch = [];
var dbBatch = [];
var AWS = require('aws-sdk');
var ddbTable = 'TwitterStream';
var dynamoDBClient = new AWS.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {
    var counter = 0; 
    
    event.Records.forEach((record) => {
        // Kinesis data is base64 encoded so decode here
        console.log("Base 64 record: " + JSON.stringify(record, null, 2));
        const payload = new Buffer(record.kinesis.data, 'base64').toString('ascii');
        console.log('Decoded payload:', payload);
        
        var data = payload.replace(/[\u0000-\u0019]+/g," "); 
        try
        {  tweetData = JSON.parse(data);   }
        catch(err)
        {  callback(err, err.stack);   }
        
        timestamp = "" + new Date().getTime();
        twitterID = tweetData.id.toString();
        itemNum = itemNum+1;
               
         var ddbItem = {
                PutRequest: { 
                    Item: { 
                        TwitterID: twitterID,
                        TwitterUser: tweetData.username.toString(),
                        TwitterUserPic: tweetData.pic,
                        TwitterTime: new Date(tweetData.time.replace(/( \+)/, ' UTC$1')).toLocaleString(), 
                        Tweet: tweetData.text,
                        TweetTopic: tweetData.topic,
                        Tags: (tweetData.hashtags) ? tweetData.hashtags : " ",
                        Location: (tweetData.loc) ? tweetData.loc : " ",
                        Country: (tweetData.country) ? tweetData.country : " ",
                        TimeStamp: timestamp,
                        RecordNum: itemNum
                    }
                }
            };
            
            dataItemsBatch.push(ddbItem);
            counter++;
});
    
    var twitterItems = {}; 
    twitterItems[ddbTable] = dataItemsBatch; 
    ddbItemsWrite(twitterItems, 0, context, callback); 

};

以下に示す ddbItemsWrite 関数は、Kinesis ストリームから処理された一連の JSON のツイートレコードを取り出し、バッチオペレーションを使用してレコードの複数の項目を同時に DynamoDB テーブルに書き込みます。この関数は、個々のテーブルのスロットリングによる書き込みリクエストの失敗を避けるため、エクスポネンシャルバックオフアルゴリズムを実装することにより、未処理の項目を再試行する DynamoDB のベストプラクティスを活用します。

 function ddbItemsWrite(items, retries, ddbContext, ddbCallback) 
    { 
        dynamoDBClient.batchWrite({ RequestItems: items }, function(err, data) 
            { 
                if (err) 
                { 
                    console.log('DDB call failed: ' + err, err.stack); 
                    ddbCallback(err, err.stack); 
                } 
                else 
                { 
                    if(Object.keys(data.UnprocessedItems).length) 
                    { 
                        console.log('Unprocessed items remain, retrying.'); 
                        var delay = Math.min(Math.pow(2, retries) * 100, ddbContext.getRemainingTimeInMillis() - 200); 
                        setTimeout(function() {ddbItemsWrite(data.UnprocessedItems, retries + 1, ddbContext, ddbCallback)}, delay); 
                    } 
                    else 
                    { 
                         ddbCallback(null, "Success");
                         console.log("Completed Successfully");
                    } 
                } 
            } 
        );
    }

現在、この Lambda 関数は期待通りに動作しており、Twitter ストリーミング API から Kinesis に取得されたツイートを問題なく処理します。しかし、この関数には、DynamoDB テーブルへのバッチ書き込みリクエストを処理するときにエラーが発生するという欠陥があります。Lambda 関数で、現在のコードでは、DynamoDB batchWrite 関数が 単一呼び出しにつき最大 25 の書き込み (PUT) リクエストで最大 16 MB のデータで構成されている必要があることが考慮されていません。そのため、ddbItemsWrite 関数を送信する前に、コードを適切に変更して ddbItemsWrite 関数を 25 のバッチに対応させるか、または、ハンドラー組み込み関数で項目を 25 リクエストの一連のグループにします。25 以上のツイート項目のバッチが送信されると検証の例外が発生します。これは、小規模なテストシナリオでは検出されにくくても、本稼働ワークロードでは失敗となるバグのよい例です。  デッドレターキュー これで、ddbItemsWrite Lambda 関数に例外をスローさせるイベント、または、レコードを処理する際に失敗となるイベントを認識できたので、デッドレターキュー (DLQ) を活用するのに最適なシナリオとなります。AWS Lambda DLQ 機能は Amazon S3、Amazon SNS、AWS IoT のような非同期イベント、または直接の非同期呼び出しでのみ使用可能で、Amazon Kinesis または Amazon DynamoDB ストリームのようなストリーミングイベントのソース向けではないので、最初のステップはこの Lambda 関数を 2 つの関数に分けることです。最初の Lambda 関数は Kinesis ストリームの処理に対応し、2 つめの関数は最初の関数で処理されたデータを取り出し DynamoDB にツイート情報を書き込みます。その後、上記のとおり DynamoDB へのツイートのバッチを書き込む際に生じるエラーのために、2 つめの Lambda 関数で DLQ をセットアップします。ターゲットを DLQ にセットアップするときに 2 つのオプションがあります。Amazon SNS トピック、または Amazon SQS キューです。この説明の中では、Amazon SQS キューの使用を選択します。そのため、DLQ を使用する際の最初のステップは、SQS 標準キューの作成です。標準キュータイプは高トランザクションスループットのあるキューです。メッセージが最低 1 回配信され、メッセージの別のコピーも配信されます。メッセージが、送信された順序とは異なる順序で配信されることがあります。SQS キューとキュータイプの詳細については、「Amazon SQS ドキュメント」をご覧ください。私のキュー、StreamDemoDLQ が作成されたら、この選択したキューの詳細タブから ARN をつかみます。コンソールを使用してこの関数に DLQ リソースを指定しない場合は、この SQS キューをエラーとイベント失敗通知のための DLQ ターゲットとして識別するため、Lambda 関数のためにキューの ARN が必要です。また、この SQS キューにアクセスする目的で Lambda 実行ロールポリシーにアクセス許可を追加するために ARN を使用します。

Lambda 関数に戻り、[Configuration] タブを選択して [Advanced settings] セクションを開きます。[DLQ Resource] フィールドで SQS を選択し、[SQS Queue] フィールドのドロップダウンから 私の [StreamDemoDLQ] キューを選択します。

SQS DLQ へ正常にメッセージを送信するには、Lambda 関数の実行ロールは明示的に sqs:SendMessage のアクセスを許可する必要があります。そのため、私の Lambda ロール lambda_kinesis_role に以下の SQS アクセス権限のための IAM ポリシーがあることを確認しました。


これで、Amazon SQS を使用して Lambda 関数のためのデッドレターキューを正常に設定できました。Lambda のデッドレターキューの詳細については、「AWS Lambda 開発者ガイド」の「トラブルシューティングとモニタリング」セクションをお読みください。また、デッドレターキューに関する「AWS コンピューティングブログの投稿」をご確認ください。

C# Support
前述のとおり、AWS re:Invent で Lambda に追加された別のすばらしい特徴は、オープンソース .NET Core 1.0 プラットフォームによる C# 言語のサポートです。Lambda コンソールはまだコンパイル済み言語の編集を提供していないので、C# Lambda 関数を記述するには、AWS Toolkit、Yeoman、または .NET CLI で Visual Studio のツールを使用できます。C# で記述された Lambda 関数をデプロイするには、AWS ToolKit for Visual Studio の Lambda プラグインを使用するか、または .NET Core コマンドラインでデプロイパッケージを作成します。C# Lambda 関数ハンドラーをクラスのインスタンスまたは静的メソッドとして定義する必要があります。2 つの関数パラメーターがあります。1 つめは、イベントデータである入力型で、もう 1 つは、タイプ ILambdaContext の Lambda コンテキストオブジェクトです。AWS のサービスのイベントデータ入力オブジェクトタイプには以下のものがあります。

  • Amazon.Lambda.APIGatewayEvents
  • Amazon.Lambda.CognitoEvents
  • Amazon.Lambda.ConfigEvents
  • Amazon.Lambda.DynamoDBEvents
  • Amazon.Lambda.KinesisEvents
  • Amazon.Lambda.S3Events
  • Amazon.Lambda.SNSEvents

Lambda の C# サポートの詳細について説明したので、DevDayStreamProcessor Lambda 関数を C# 言語で書き換えましょう。この例では、Lambda 関数を記述するのに Visual Studio IDE を使用します。また、関数をデプロイするのに、AWS Lambda Visual Studio プラグインを活用します。Lambda で AWS Toolkit for Visual Studio を使用するには、Visual Studio 2015 Update 3 バージョンと NET Core ツールが必要なことに留意してください。Visual Studio 2015 Update 3 と .NET Core のインストールの詳細については、こちらをお読みください。Visual Studio を使用して C# 関数を作成するには、新しいプロジェクトを開始し、[AWS Lambda Project (.NET Core)] を選択して ServerlessStreamProcessor という名前を付けます。

この関数を記述するのに AWS Toolkit for Visual Studio を活用することの大きな利点は、Lambda コンソールを使用するのと同様の方法で Visual Studio の中で Lambda 設計図を使用できることです。それで、DevDayStreamProcessor を C# でレプリケートするために、Simple Kinesis Function 設計図を選択します。

Lambda 関数を C# で記述する場合、クラスの宣言やターゲットのハンドラー関数を Lambda 関数としてマークする必要はありません。また、CloudWatch ログを記述する場合は、標準 C# の Console クラスの WriteLine 関数を使用するか、ILambdaContext インターフェイスの一部である ILambdaContext の LogLine 関数を使用することができます。所定の Kinesis ストリームにアクセスするためのテンプレートでは、C# Lambda 関数の ServerlessStreamProcessor を記述するために Node.js コードの DevDayStreamProcessor と同じ変数名を使用します。以下の C# Lambda ハンドラー関数をご覧ください。

using System.Collections.Generic;
using Amazon.Lambda.Core;
using Amazon.Lambda.KinesisEvents;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Newtonsoft.Json.Linq;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializerAttribute(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

namespace ServerlessStreamProcessor
{
    public class LambdaTwitterStream
    {
        string twitterID, timeStamp;
        int itemNum = 0;
        
        private static AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient();
        List<TwitterItem> dataItemsBatch = new List<TwitterItem>();
        
        public void FunctionHandler(KinesisEvent kinesisEvent, ILambdaContext context)
        {
            DynamoDBContext dbContext = new DynamoDBContext(dynamoDBClient);
            context.Logger.LogLine($"Beginning to process {kinesisEvent.Records.Count} records...");
            
            foreach (var record in kinesisEvent.Records)
            {
                context.Logger.LogLine($"Event ID: {record.EventId}");
                context.Logger.LogLine($"Event Name: {record.EventName}");

                // Kinesis data is base64 encoded so decode here
                string tweetData = GetRecordContents(record.Kinesis);
                context.Logger.LogLine($"Decoded Payload: {tweetData}");
                tweetData = @"" + tweetData;
                JObject twitterObj = JObject.Parse(tweetData);
                
                twitterID = twitterObj["id"].ToString();
                timeStamp = DateTime.Now.Millisecond.ToString();
                itemNum++;
                context.Logger.LogLine(timeStamp);
                context.Logger.LogLine($"Twitter ID is: {twitterID}");
                context.Logger.LogLine(itemNum.ToString());

                TwitterItem ddbItem = new TwitterItem()
                { 
                    TwitterID = twitterID,
                    TwitterUser = twitterObj["username"].ToString(),
                    TwitterUserPic = twitterObj["pic"].ToString(),
                    TwitterTime = DateTime.Parse(twitterObj["time"].ToString()).ToUniversalTime().ToString(),
                    Tweet = twitterObj["text"].ToString(),
                    TweetTopic = twitterObj["topic"].ToString(),
                    Tags = twitterObj["hashtags"] != null ? twitterObj["hashtags"].ToString() : String.Empty,
                    Location = twitterObj["loc"] != null ? twitterObj["loc"].ToString() : String.Empty,
                    Country = twitterObj["country"] != null ? twitterObj["country"].ToString() : String.Empty,
                    TimeStamp =  timeStamp,
                    RecordNum = itemNum
                };
                
                dataItemsBatch.Add(ddbItem);
            }

            context.Logger.LogLine(JObject.FromObject(dataItemsBatch).ToString());
            ddbItemsWrite(dataItemsBatch, 0, dbContext, context);
            context.Logger.LogLine("Success - Completed Successfully");
            context.Logger.LogLine("Stream processing complete.");
        }

C# で記述された Kinesis ストリームプロセッサと当初の Node.js コード間の注意すべき差異はわずかです。C# Lambda 関数でデフォルトでサポートされている入力パラメータータイプは System.IO.Stream タイプであるため、Kinesis base64 文字列は、設計図で提供されている GetRecordContents 関数で StreamReader (エンコーディングは ASCII) を使用してデコードされます。

private string GetRecordContents(KinesisEvent.Record streamRecord)
{
    using (var reader = new StreamReader(streamRecord.Data, Encoding.ASCII))
    {
        return reader.ReadToEnd();
    }
}

ツイートのデータを DynamoDB テーブルに書き込むために、Visual Studio 内で NuGet パッケージマネージャーを経由して DynamoDB; AWSSDK.DynamoDBv2 の AWS .NET SDK NuGet パッケージを Lambda 関数プロジェクトに追加しました。また、DynamoDB テーブルに保存されるデータにマッピングするために .NET データオブジェクトとして TwitterItem も作成しました。DynamoDB 用の AWS .NET SDK 高レベルプログラミングインターフェイス、オブジェクト永続性モデルを使用して、ddbItemsWrite C# 関数の BatchWrite オブジェクトクラスを介して書き込む TwitterItem オブジェクトのコレクションを作成しました。

private async void ddbItemsWrite(List<TwitterItem> items, int retries, DynamoDBContext ddbContext, ILambdaContext context)
{
BatchWrite<TwitterItem> twitterStreamBatchWrite = ddbContext.CreateBatchWrite<TwitterItem>();
        
        try
        {
            twitterStreamBatchWrite.AddPutItems(items);   
            await twitterStreamBatchWrite.ExecuteAsync();
        }
        catch (Exception ex)
        {
            context.Logger.LogLine($"DDB call failed: {ex.Source} ");
            context.Logger.LogLine($"Exception: {ex.Message}");
            context.Logger.LogLine($"Exception Stacktrace: {ex.StackTrace}");
        }      
}

AWS Toolkit for Visual Studio を使用して、C# Lambda 関数を作成する別のメリットは、1 回クリックするだけで Lambda 関数を直接 AWS にデプロイできることです。ソリューションエクスプローラーでプロジェクト名を選択し、右クリックすると、メニューオプションに Publish to AWS Lambda が出て、AWS へのデプロイ用の Lambda 関数について含めるべき情報のメニューが表示されます。

ハンドラー関数の署名は Assembly :: Namespace :: ClassName :: Method の命名法に従います。したがって、ここに示される C# Lambda 関数の署名は ServerlessStreamProcessor :: ServerlessStreamProcessor.LambdaTwitterStream :: FunctionHandler であることに注意してください。この情報は [Upload to AWS Lambda] ダイアログボックスに提供され、[Next] を選択して、関数にロールを割り当てます。

完了すると、AWS toolkit が提供するプラグイン (以下に示す) を使用して Lambda コンソールまたは Visual Studio で、Lambda 関数開発の反復アプローチのためにトリガーするイベントソースのサンプルデータを使用してテストできます。

C# 言語を使用した AWS Lambda 関数の作成に関しての詳細については、「AWS Lambda 開発者ガイド」、またはコンピューティングブログの C# のサポートを発表した投稿をご覧ください。

API Gateway 収益化および開発者ポータル
マイクロサービスモーメンタムに従ってきたのなら、マイクロサービスのソリューションを構成する個別のサービスへのアクセスと公開を管理するためにスマートエンドポイントの使用または REST API 経由での API gateway の使用 (またはその両方) が必要なアーキテクチャーパターンを認識している場合があります。Amazon API Gateway により RESTful API の作成と管理をして AWS Lambda 関数、外部 HTTP エンドポイント、他の AWS のサービスを公開できるようになります。加えて、Amazon API Gateway により、クライアントおよび外部開発者が、HTTP プロトコル、または、プラットフォーム/言語対象の SDK を介してデプロイされた API にアクセスできるようになります。AWS Marketplace の SaaS サブスクリプションの導入と API Gateway と AWS Marketplace との統合により、AWS Marketplace の API Gateway を使用して、作成した API を顧客が直接利用できるようにすることで、API の収益化が可能になりました。AWS のお客様は、既存の AWS アカウントを使用して、マーケットプレイスで公開されている API をサブスクライブして支払うことができます。API Gateway と AWS Marketplace との統合により、AWS Marketplace で開始するプロセスは簡単です。開始するには、Amazon API Gateway で、使用プラン機能を有効にしていることを確認する必要があります。

有効化した後、使用プランを作成します。目標のレートおよびバーストリクエストのしきい値を使用して、スロットリングを有効にし (必要に応じて)、最後に、一定のタイムフレームあたりの目標リクエストのクォータを指定して、クォータを有効にします (選択した場合)。

次に、使用プランと関連付ける API と関連するステージを選択します。特定の API を使用プランに関連付けることを選択できないため、これはオプションの手順であることに注意してください。

あとは、API キーを使用プランに追加または作成するだけです。使用プランの作成において、この手順もまたオプションであることにご注意ください。

使用プラン StreamingPlan ができたので、マーケットプレイスで API を販売する準備のための次のステップに進むことができます。さまざまな API とその制限を使用して、複数の使用プランを作成し、これらのプランを AWS Marketplace で、差別化された API 製品として販売するオプションがあります。

ただし、顧客が新しい API 製品を購入できるようにするため、AWS Marketplace では、各 API 製品にサブスクリプションリクエストを処理する外部開発者ポータルがあり、API の詳細情報および使用管理機能を提供する必要があります。このようなマーケットプレイスでの外部開発者ポータルに対する顧客のニーズにより、新しいオープンソース API Gateway 開発者ポータルサーバーレスウェブアプリケーションの実装が誕生しました。API Gateway 開発者ポータルプロジェクトの目標は、開発者のサインアップを許可しつつ、顧客が数ステップの簡単な手順に従って、API Gateway で構築した API のカタログをリスト表示するサーバーレスウェブアプリケーションを作成することです。API Gateway 開発者ポータルは AWS Serverless Express に構築されており、AWS により発行されたオープンソースライブラリーで、Node.js Express フレームワークを使用して、ウェブアプリケーション/サービスを構築するために AWS Lambda および Amazon API Gateway を利用する際に役立ちます。加えて、API Gateway 開発者ポータルアプリケーションは AWS SAM (サーバーレスアプリケーションモデル) テンプレートを使用して、そのサーバーレスリソースをデプロイします。AWS SAM は簡略化された CloudFormation テンプレートおよび仕様で、AWS でのサーバーレスアプリケーションの管理とデプロイを簡単にします。API Gateway ポータルを使用して開発者ポータルを構築するには、GitHub から aws-api-gateway-developer-portal プロジェクトをクローン作成することから始めます。

AWS CLI および Node.js の最新版をインストール済みであれば、Mac および Linux OS ユーザー用のコマンドラインで、“npm run setup” を実行して、開発者ポータルを設定します。Windows ユーザーは、コマンドラインで “npm run win-setup” を実行して、開発者ポータルを設定します。

結果として、S3 で実行する機能的なサンプル開発者ポータルウェブサイトができ、これをカスタマイズして独自の API 用の開発者ポータルを作成できます。

サンプルの開発者ポータルウェブサイトのフロントエンドは、React JavaScript ライブラリを使用して構築されており、バックエンドは aws-serverless-express ライブラリを使用して、AWS Lambda 関数が実行されています。加えて、SNS イベントソースを使用した Lambda 関数は、顧客が AWS Marketplace コンソールを介して API をサブスクライブまたはサブスクライブ解除する際の通知のためのリスナーとして作成されています。このリファレンスプロジェクトを使用した API Gateway 開発者ポータルウェブアプリケーションの構築、カスタマイズ、デプロイの手順についての詳細は、アーキテクチャと実装について詳細に説明している「AWS コンピューティングブログの投稿」を参照してください。  API を収益化する次の主なステップは、AWS Marketplace でアカウントを作成することです。アカウントをまだ作成していない場合、登録は「AWS Marketplace Seller Guide」で説明されている必要な前提条件を満たしていることを確認し、AWS Marketplace 管理ポータルのセラー登録フォームに入力するだけです。以下で、セラー登録フォームの冒頭のスナップショットを確認できます。

API を一覧表示するには、API を説明する製品ロードフォームに入力し、API の価格を設定して、API サブスクリプションプロセスをテストする AWS アカウントの ID を指定します。このフォームを入力する場合、API 開発者ポータル用の URL も送信する必要があります。販売者登録が完了したら、AWS Marketplace 製品コードが指定されます。Marketplace 製品コードを API 使用プランと関連付ける必要があります。この手順を完了するために、API Gateway コンソールにログインし、API 使用プランに移動します。[Marketplace] タブに移動し、製品コードを入力します。これにより、API Gateway は、API が使用されると測定データを AWS Marketplace に送信します。

Amazon API Gateway が管理する API が使用プランにパッケージ化され、付随する API 開発者ポータルが作成され、販売者アカウント登録が完了し、製品コードが API プランと関連付けられたので、AWS Marketplace で API を収益化する準備ができました。API Gateway で作成された API の収益化に関する詳細については、関連するブログの投稿と API Gateway 開発者ガイドドキュメントを確認してください。

要約
ご覧いただいたとおり、AWS チームは 2016 年中、サーバーレスアーキテクチャの作成およびデプロイにおける顧客エクスペリエンスを向上させるため、また、API Gateway が管理する API を生成し、収益をあげるためのメカニズムを提供するため努力してきました。AWS Lambda および Amazon API Gateway の製品のドキュメントをご覧になり、これらのサービス、およびすべての新しくリリースされた機能の詳細を確認してください。

Tara

AWS LambdaのC#サポートの発表

本日、AWS Lambdaのサポート言語としてC#を発表しました。新しいオープンソースの.NET Core 1.0ランタイムを使用すると、さまざまな一般的な.NETツールからC#コードをAWS Lambdaに簡単に公開できます。 .NET開発者は、C#言語と使い慣れた.NETツールを使用して、Lambda関数とサーバーレス アプリケーションを作成できます。 Visual Studio、Yeoman、およびdotnet CLIにおけるツール サポートによって、C#で記述された個々のLambda関数またはサーバーレスアプリケーション全体をLambdaおよび Amazon API Gatewayに簡単に展開できます。

LambdaAWSサーバーレスプラットフォームの中核です。もともと2015年に発売されたLambdaでは、インフラストラクチャやスケーリングを心配することなく、Node.jsPython、およびJavaコードをAWSに展開することができます。これにより、開発者はアプリケーションのビジネスロジックに集中でき、インフラストラクチャの維持と拡張に時間を費やす必要がありません。今日まで、.NET開発者はこのモデルを利用することができませんでした。サポートされている言語のリストにC#を追加し、サーバーレスアプリケーションを作成すためにLambdaAPIゲートウェイを利用する新しいカテゴリの開発者ができたことを嬉しく思っています。

 

C#でのLambda

単純なC#ラムダ関数を見てください。 既にNode.js、Python、JavaでLambdaを使っていたなら、これはよく分かるはずです:

using System;
using System.IO;
using System.Text;

using Amazon.Lambda.Core;
using Amazon.Lambda.DynamoDBEvents;
using Amazon.Lambda.Serialization.Json;

namespace DynamoDBStreams
{
    public class DdbSample
    {
        private static readonly JsonSerializer _jsonSerializer = new JsonSerializer();

        [LambdaSerializer(typeof(JsonSerializer))]
        public void ProcessDynamoEvent(DynamoDBEvent dynamoEvent)
        {
            Console.WriteLine($"Beginning to process {dynamoEvent.Records.Count} records...");

            foreach (var record in dynamoEvent.Records)
            {
                Console.WriteLine($"Event ID: {record.EventID}");
                Console.WriteLine($"Event Name: {record.EventName}");

                string streamRecordJson = SerializeObject(record.Dynamodb);
                Console.WriteLine($"DynamoDB Record:");
                Console.WriteLine(streamRecordJson);
            }

            Console.WriteLine("Stream processing complete.");
        }


        private string SerializeObject(object streamRecord)
        {
            using (var ms = new MemoryStream())
            {
                _jsonSerializer.Serialize(streamRecord, ms);
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
    }
}

Lambdaでサポートされている他の言語と同様に、関数の入力と戻り値の型を扱うための選択肢がいくつかあります。最も基本的な選択は、System.IO.Streamの低レベルストリームインタフェースを使用することです。また、アプリケーションのアセンブリレベルまたはメソッドレベルでデフォルトのシリアライザを適用することも、Amazon.Lambda.Coreライブラリによって提供されるILambdaSerializerインターフェイスを実装することによって独自のシリアライゼーションロジックを定義することもできます。

ProcessDynamoEvent関数の関数シグネチャを見て、シグネチャ内のDynamoDBEventに注意してください。これは、Lambdaが提供するAmazon.Lambda.Coreライブラリと、他のAWSイベントタイプのためのさらに多くのクラスから来ています。このNuGetパッケージにプロジェクトの依存関係を追加すると、staticLambdaロガー、シリアライゼーション インターフェイス、およびLambdaコンテキストオブジェクトのC#実装にアクセスできます。

ロギングでは、C#Consoleクラス、Amazon.Lambda.Core.LambdaLoggerクラスのLogメソッド、またはコンテキストオブジェクトのLoggerプロパティによって提供される静的なWriteメソッドまたはWriteLineメソッドを使用できます。 C#プログラミングモデルの詳細については、「AWS Lambda開発者ガイド」を参照してください。

 

AWS Toolkit for Visual Studio

AWS Toolki for Visual Studio は、.NET Core Lambda関数とサーバーレスアプリケーションの開発、テスト、および展開をサポートします。 このツールキットには、容易に開発を始めるために、次の2つの新しいプロジェクトテンプレートが用意されています: AWS Lambda Projectテンプレートは、単一のCLambda関数を持つ単純なプロジェクトを作成します。 AWS Serverlessアプリケーションテンプレートは、AWS Serverless Application ModelAWS SAM)に従って、小さなAWSサーバーレスアプリケーションを作成します。 このテンプレートは、API GatewayRESTエンドポイントを介して公開された複数のラムダ関数で構成された完全なサーバーレスアプリケーションを開発する方法を示しています。 また、AWS SAMでは、アプリケーションがプロジェクトのテンプレートの一部として使用するAWSリソースをモデル化できます。

コードが準備できたら、プロジェクトを右クリックし、ソリューションエクスプローラで[Publish to AWS Lambda…]を選択してVisual Studioから直接展開できます。 そこから、デプロイメント・ウィザードがデプロイメント・プロセスをガイドします。

 

.NET Core CLIを使用したクロスプラットフォーム開発

.NET Coreの優れた機能の1つは、クロスプラットフォームのサポートです。 従来の.NETフレームワークでは、開発者はWindows上でアプリケーションを構築して実行する必要があります。 ただし、.NET Coreを使用すると、任意のプラットフォームでC#コードを開発し、任意のプラットフォームに展開することができます。Windowsで開発しておらず、AWS Toolkit for Visual Studioにアクセスできない場合でも、.NETツールを使用してCLambda関数とサーバーレスアプリケーションをAWSに簡単に公開できます。 AWS Toolkit for Visual Studioを使用していても、dotnet CLIの使い方を知ることは、ビルドとデプロイメントプロセスの自動化に役立ちます。.NET Coreプロジェクトを作成したら、Yeomanのようなツールを使用してdotnet CLILambdaツールを有効にします。 Amazon.Lambda.ToolsNuGetパッケージに依存するツールを新しいプロジェクトに追加するだけです。

Amazon.Lambda.Tools NuGetパッケージは、新しいdotnet CLIにコマンドを追加します。これにより、使用しているプラットフォームに関係なく、Lambda関数とサーバレスアプリケーションをAWSにデプロイできます。 Windows上のVisual Studioで開発している場合でも、dotnet CLIAWS Lambdaツールは、アプリケーションのCI / CDパイプラインを設定するのに役立ちます。dotnet CLIの新しいラムダコマンドの詳細については、プロジェクトディレクトリに「dotnet lambda help」と入力してください。

 

まとめ

我々は、.NET Core ランタイムを通してC#アプリケーションに対してAWS Lambdaを利用可能にすることに興奮しています。 C#Lambda関数の作成に関する詳細は、「AWS Lambda開発者ガイド」を参照してください。 AWS Toolkit for Visual Studioをダウンロードして開始するか、dotnet CLIのLambda拡張を確認してください。

 

原文: Announcing C# Support for AWS Lambda (翻訳: SA福井)

Lambda@Edge – プレビュー

ちょうど先週、私が Hacker News上で書いたコメントがきっかけでAWSのお客様から興味深いメールを頂きました。

彼はS3上でホストしているシングルページのアプリケーションを動作させていて(こちらについてはAmazon S3で静的なWebサイトの運用が可能に をご覧下さい。)、Amazon CloudFrontを経由して少ないレイテンシーで提供していると教えてくれました。そのページは、AWS Elastic Beanstalk上でホストしているAPIを使って、それぞれのユーザー向けにカスタマイズして表示するいくつかの動的な要素を含みます。

彼が説明してくれた彼の課題はこちらです。

適切に検索エンジンのインデックスを取得するために、またFacebookやTwitterないで正しく表示するためのコンテンツのプレビューをするためには、それぞれのページが事前に表示されたバージョンを提供する必要があります。こちらを実現するには、一般ユーザーがヒットするたびに、私たちのサイトはノーマルのフロントエンドをCloudFrontから提供する必要があります。しかし、もしユーザーエージェントがGoogle / Facebook / Twitter等にマッチする場合は、その代りに私たちは事前に表示されたバージョンへリダイレクトさせる必要があります。

私たちはこのユースケースについてよく分かっており、興味深いソリューションを準備中であることを彼に秘密を漏らすことなく伝えました。他のお客様もまた、エッジにおいてクイックな判定によりカスタマイズしたいと伝えてくれてました。

お客様に近いロケーションでHTTPリクエストを”賢く”処理しなければならないユースケースがあることがわかりました。これらには、HTTPヘッダの検査および変更、アクセスコントロール(特定のcookieを必要とする)、デバイス検出、A/Bテスト、クローラーまたはbotsのための処理または特別な対応、レガシーシステムに適応させるためにユーザーフレンドリーなURLを書き換えるユースケースを含みます。多くのこれらのユースケースは、シンプルなパターンマッチングやルールによって表現可能なユースケースよりも多くの処理や判定を必要とします。

Lambda@Edge
これらのユースケースのサポートを提供するために、私はLambda@Edgeのプレビューをラウンチしています。この新しいLambdaベースの処理モデルにより、ますます増加するAWSエッジロケーションのネットワーク内で動作するJavaScriptコードを書くことが出来ます。

CloudFrontのディストリビューションを通して流れるリクエストやレスポンスを処理する軽量なロジックを書くことができます。4つの異なるイベントに対するレスポンスの中でコードを実行できます。

Viewer リクエスト – あなたのコードは、コンテンツがキャッシュされるか否かに関わらず、あらゆるリクエストにおいて動作します。こちらがシンプルなヘッダ処理用のコードです。

exports.viewer_request_handler = function(event, context) {
  var headers = event.Records[0].cf.request.headers;
  for (var header in headers) {
    headers["X-".concat(header)] = headers[header];
  }
  context.succeed(event.Records[0].cf.request);
}

Origin リクエスト – リクエストされたコンテンツがエッジでキャッシュされていない時に、Originに転送される前にコードを実行します。ヘッダを追加したり、既存のヘッダを編集したり、URLを編集したりすることが可能です。

Viewer レスポンス – キャッシュされているか否かに関わらず、すべてのレスポンスにおいてコードを実行します。Viewerに戻す必要のないヘッダをクリーンアップするためにこちらを利用できます。

Origin レスポンス – キャッシュミスにより Originへコンテンツを取りに行き、エッジへレスポンスを戻した後でコードを実行します。

リクエストやレスポンスに含まれるURLやメソッド、HTTPバージョン、クライアントIPアドレス、ヘッダなどのさまざまな要素へコードからアクセスできます。まず最初にヘッダを追加、削除、そして編集することができるようになる予定です。すぐに、bodyを含むすべての値に対して読み込み/書き込みの完全なアクセスができるようになる予定です。

JavaScriptコードは、リクエスト/レスポンスパスの一部になるでしょう、そしてそれは効率的で、重要で、自己完結型のものでなければなりません。他のWebサービスをコールすることは出来ません、また他のAWSリソースへアクセスできません。128MBメモリ内で動作しなければならず、また50ms以内で完了しなければなりません。

開始するには、新しいLambda function を作成して、あなたのディストリビューションをトリガーとして設定し、新しいエッジランタイムを選択します。

その後で通常通りコードを書きます。Lambdaはエッジロケーションでの舞台裏での処理をしてくれます。

興味深いですか?
このクールな新しい処理モデルはいくつかのとてもクールな新しいアプリケーションや開発ツールの作成を導いてくれると信じています。あなたがこちらを使って何をもたらしてくれるか待ちきれません。

私たちは本日Lambda@Edgeの制限付きのプレビューをラウンチします、そして利用者を募集しています。もしあなたが関連しそうなユースケースをお持ちで、こちらを試す準備が出来れいれば、ぜひこちらにご応募ください。

-Jeff

翻訳は舟崎が担当しました。原文はこちらです。

AWS Lambda の新機能 – 環境変数とサーバーレスアプリケーションモデル (SAM)

AWS Lambda とサーバーレスアプリケーション開発をめぐる興奮のとりこになっています。過去 1〜2 年間に週刊 AWS で、多くのサーバーレスの成功事例、ツール、オープンソースプロジェクトを紹介しました。今回は Lambda に追加された重要な機能として、環境変数と新しいサーバーレスアプリケーションモデルについて説明します。

環境変数
開発者なら、だれでも複数の環境で利用できるコードを構築したいと思います。コードを簡単に再利用するには、実行時に設定値を受け入れられるように構築する必要があります。設定値とは、コードの環境をカスタマイズするためのテーブル名、デバイス名、ファイルパスなどです。たとえば、多くのプロジェクトは開発環境、テスト環境、本稼働環境ごとに設定が異なります。Lambda 関数に環境変数を指定できるようになりました。これでコードを変更または再デプロイすることなく設定の変更が可能になり、これまで以上にサーバーレスアプリケーション開発が効率化されます。各環境変数はキーと値のペアです。キーと値は AWS Key Management Service (KMS) で暗号化され、必要に応じて復号されます。関数あたりの環境変数の数には制限がありませんが、合計サイズは 4 KB を超えることができません。 Lambda 関数を新規作成する場合は、同時に環境変数も設定します。最新バージョンの関数の値は変更できますが、以前のバージョンの値は変更できません。次の例では、シンプルな Python 関数を作成して、いくつかの環境変数を設定し、その環境変数をコードから参照しています (このために os ライブラリをインポートする必要がありました)。

Lambda に用意されているデフォルトのサービスキーを使えば、この機能を使用しても料金はかかりません (独自のキーを使用する場合は、リクエストあたりの KMS の通常料金が適用されます)。この新しい機能の詳細とさまざまな活用方法については、AWS Compute Blog で「サーバーレスアプリケーションを簡素化する Lambda 環境変数」を参照してください。

AWS サーバーレスアプリケーションモデル
サーバーレスアプリケーションを構築するために、Lambda 関数、Amazon API Gateway リソース、Amazon DynamoDB テーブルを併用する場合があります。新しい AWS サーバーレスアプリケーションモデル (AWS SAM) を使うと、これらのすべてのコンポーネントを、AWS CloudFormation でネイティブにサポートされている簡略化された構文で記述できます。この構文を使用するには、CloudFormation テンプレートに次のような Transform セクション (CloudFormation の新しい要素) が含まれている必要があります。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

テンプレートの他のセクションでは、Lambda 関数、API Gateway のエンドポイントとリソース、DynamoDB テーブルを指定します。各関数宣言では、ハンドラー、ランタイム、および関数のコードが含まれている ZIP ファイルへの URI を指定します。API は、イベントを定義して暗黙的に宣言するか、Swagger ファイルを指定して明示的に宣言することができます。DynamoDB テーブルは、テーブル名、プライマリキー (名前とタイプ)、プロビジョニングされたスループットのみが必要な簡略化された構文を使用して宣言します。必要に応じてすべてのオプションを使用することもできます。これで、Lambda コンソールで新しい Export オペレーションを使用し、Lambda 関数の AWS SAM ファイルとデプロイパッケージを生成できるようになりました。[Actions] メニューをクリックして、[Export function] を選択します。

次に、[Download AWS SAM file] または [Download deployment package] をクリックします。

私の関数の AWS SAM ファイルは次のとおりです。

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: A starter AWS Lambda function.
Resources:
  ShowEnv:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python2.7
      CodeUri: .
      Description: A starter AWS Lambda function.
      MemorySize: 128
      Timeout: 3
      Role: 'arn:aws:iam::99999999999:role/LambdaGeneralRole'

デプロイパッケージは ZIP ファイルで、関数のコードが含まれています。このファイルを S3 にアップロードし、SAM ファイルの CodeUri を更新してサーバーレスアプリケーションの一部として使えるようにします。これは手動で行うことも、新しい CLI コマンドのペア (aws cloudformation packageaws cloudformation deploy) を使って自動化することもできます。このオプションの詳細については、新しい記事「簡略化されたサーバーレスアプリケーションの管理とデプロイの概要」で「サーバーレスアプリのデプロイ」セクションを参照してください。Lambda 関数の設計図をエクスポートすることもできます。コーナーにあるダウンロードリンクをクリックします。

次に、[Download blueprint] をクリックします。

ZIP ファイルには、AWS SAM ファイルとコードが含まれています。

この新しい仕様の詳細と実際の使い方については、AWS Compute Blog で「簡略化されたサーバーレスアプリケーションの管理とデプロイの概要」を参照してください。

Jeff;

サーバーレス Chatbot コンテストに入賞した皆様、おめでとうございます!

私は 8 月に AWS サーバーレス Chatbot コンテストについて発表し、皆様に AWS Lambda および Amazon API Gateway を使用して Slack 用の Chatbot を構築していただきますようお願いしました。

先週、仲間の審査員である Tim Wagner (AWS Lambda のジェネラルマネージャー) および Cecilia Deng (Tim のチームのソフトウェア開発エンジニア) と一緒にビデオを見て、62 点の応募作品をすべて評価しました。私たちは応募作品の機能や多様性、そして作品の実行中の動作を示す魅力的なビデオの作成に対する応募者の努力に感心しました。長時間にわたって審査した結果、合計 9 点の入賞作品を選定しました。8 点は個人、チーム、小規模組織の作品で、1 点は大企業の作品です。難しい話は抜きにして、さっそく始めましょう。

個人、チーム、小規模組織
サーバーレス Slackbot ヒーロー賞の入賞作品は以下のとおりです。各入賞作品には、AWS re:Invent のチケット 1 枚、ホテルの宿泊割引、公表、サーバーレスコンピューティング基調講演中の宣伝、クールな賞品、および 100 USD の AWS クレジットが贈られます。これらの多くのボットのコードは、GitHub で確認することができます。入賞作品をアルファベット順に示します。

AWS Network Helper“このプロジェクトの目標は、サーバーレスアーキテクチャで実行する AWS ネットワークトラブルシューティングスクリプトを提供し、チャットボットとして Slack 経由で相互作用させることです。GitHub repo

B0pb0t – “食事の時間をすばらしいものに。” GitHub repo

Borges – “Borges は複数言語の Slack チーム用のリアルタイム翻訳ツールです。” GitHub repo

CLIve – “CLIve は AWS EC2 インスタンスの管理を非常に簡単にします。CLIve は自然言語を理解するため、新しい CLI を学習する必要はありません。”Litlbot – “Litlbot はクラスの受講者とリアルタイムのやり取りを可能にし、講義や学習をより濃密な体験にします。” GitHub repo

Marbot – “アマゾン ウェブ サービスから DevOps チームにアラートを転送します。”

Opsidian – “自然言語を使って Slack から AWS インフラストラクチャで共同作業を行います。”

ServiceBot – “人、機械、およびエンタープライズ間のコミュニケーションプラットフォームです。” GitHub repo

大企業
サーバーレス Slackbot 大企業賞の入賞作品は以下のとおりです。

Eva – “チームの仮想旅行アシスタントです。” GitHub repo

感謝と祝辞
時間を取ってコンテストに作品を応募していただき、皆様方に個人的に感謝いたします。

入賞した皆様おめでとうございます。AWS re:Invent でお目にかかりたいと思っています。

Jeff;

 

追伸 – このリストで独自の Chatbot のアイデアが浮かんだ場合は、サーバーレス Chatbot の構築ビデオをご覧いただき、サーバーレス Chatbot サンプルをご活用ください。

AWS Lambda と Amazon API Gateway で Express アプリケーションを実行

ExpressNode.js のウェブフレームワークです。これを使用すると、「サーバーレス」ウェブサイトやウェブアプリケーション、API を簡単にデプロイできます。サーバーレス環境では、大方またはすべてのバックエンドロジックがステートレスのオンデマンドで実行します (詳細情報については Mike Roberts によるブログ「Serverless Architectures」をご覧ください)。今月初旬に公開したブログ (「API Gateway の更新 – API 開発を簡素化する新機能」) で紹介した新しい Amazon API Gateway 機能と AWS Lambda を併せて使用した場合、既存の Express アプリケーションをサーバーレスで実行することができます。API Gateway を使用すると API を中心に開発者のエコシステム構築を可能にする使用量プランなど追加機能を利用したり、キャッシュにより応答性と費用対効果に優れたアプリケーション構築を行うこともできます。

AWS は aws-serverless-express パッケージを提供することで Express アプリケーションから LambdaAPI Gateway への移行をお手伝いしています。このパッケージには実例が含まれています、ぜひご活用ください。

Express コードとアプリケーションを API GatewayLambda に移行する場合に利用できる 2 つのリソースをご紹介します。

Jeff;

サーバーレスでChatbot コンテスト開催

AWS Serverless Chatbot コンテストの審査員にならないかとのオファーが来たので、喜んで引き受けることにしました。

Chatbot の構築
AWS LambdaAmazon API Gateway を使用して Slack 用の chatbot を構築してください。他の API (Slack Events API が便利) や追加サービス (AWS その他)、その他のデータソースも使用することができます。コンテストの参加作品はクリエイティブかつオリジナルであり、Stack ユーザーに本当の価値を提供できるものでなければなりません。AWS Free Tier は Lambda、API Gateway、そしてその他の AWS サービスへのアクセスを無料でご提供します。AWS の新規および既存のユーザーは Lambda リクエスト 100 万件、そして 400,000 GB/秒のコンピューティング時間を無料で利用することができます。AWS の新しいユーザーはサインアップしてから 12 か月間、API Gateway への API コールを毎月 100 万件ご利用いただけます。

コンテスト参加作品
Chatbot が完成したら、パッケージやマーケティングにも力を注ぐことをおすすめします。参加作品の一環として次のアイテムを提供することも忘れないでください。

  • Chatbot を実際に使用した様子を示すビデオ資料
  • 参加作品の機能やユニークな点に関する概要
  • パブリックまたはプライベート GitHub リポジトリのリンク (chatbot を実行するために必要なファイルすべてを含む)
  • chatbot のテスト手順と使用手順

コンテストの参加作品となる chatbot は新規または既存のアプリケーションどちらでも構いませんが、必ず Lambda と API Gateway を使用してください。コードはビデオで見せたように動作しなければなりません。提出物は必ず英語で作成してください。また、参加作品は同じ提出者、チーム、組織が提出したその他のアプリと大きく異なるものでなければなりません。

賞品
個人、チーム、社員数 50 人以下の組織が Serverless Chatbot Hero 賞に参加することができます。この賞には AWS re:Invent のチケット 1 枚、ホテルの割引、Serverless State of the Union スピーチで名前が挙がること、そして素敵なプレゼント、AWS クレジット 100 USD、さらに参加作品のボットを宣伝するチャンスなどが含まれます。このコンテストでは 8 つの賞を設ける予定です。大規模な組織は賞金なし、評価のみの賞に参加することができます。ルールと資格基準の詳細は FAQ をご覧ください。

スケジュール
コンテストのスケジュールは次のとおりです。

  • 2016 年 8 月 10 日 – 9 月 29 日 – 提出期間
  • 10 月 3 日 – 10 月 7 日 – AWS 審査員による決定期間
  • 10 月 15 日 – 受賞者の発表

 

今すぐ開始
コンテスト参加の手順を簡単にご説明します。

  1. ルールと資格基準のガイドラインをお読みください。
  2. AWS Serverless Chatbot コンテストに登録します。
  3. AWSSlack 開発者用のアカウントを作成します。
  4. リソースページにアクセスし、API とサービスの詳細をご覧ください。
  5. お客様の参加作品となる chatbot を構築してください。サンプルコード aws-serverless-chatbot-sample から始めることをおすすめします。
  6. 提出用のビデオ資料とその他の資料を作成してください。
  7. 2016 年 9 月 29 日の午後 5 時 (東部標準時) までに提出してください。

皆さんの参加作品をお待ちしています。

便利なオンラインセミナー
コンテスト参加に役立つ、今後開催予定のオンラインセミナーをご紹介します。

過去に開催したオンラインセミナーもご活用ください。

Jeff