AWS Lambda と Fastly instant purge を利用して S3 コンテンツの更新を即時反映する

Fastly CDN の特徴のひとつに、Instant purge(コンテンツの即時削除)があります。通常、CDN では更新の多いコンテンツはキャッシュすることができませんが、Fastly では Purge を即座に行うことが可能であるため、更新の多いコンテンツでもキャッシュすることが可能です。
ただし、コンテンツが変更されるたびに Instant purge を手動で行うのは理想的な運用とはいえません。ここでは AWS Lambda を利用して、S3 でのファイル更新を検知して、自動的に Instant purge を実行する方法を紹介します。

Lambda の設定

  1. Services から Lambda を選択し、Create a Lambda function をクリックします
  2. blueprint が表示されますが、ここでは Blank Function を選択します
  3. トリガーの設定画面が表示されるので、S3 を選択し、Bucket にコンテンツが配置される S3 バケットを選択し、Event type を PUT とします
    Screen Shot 0029-07-18 at 21.06.54.png
  4. Name / Description を入力し、Runtime はデフォルトの Node.js を選択します。
    Screen Shot 0029-07-18 at 21.11.26.png
  5. Code は下記のように設定します。hostname を Instant purge を行うドメインに変更してください。
    下記のコードでは、アップデートされたパスを key に格納し、options にドメイン、ポート番号、method(purge のため、PURGE) と共に設定し、http.request で Instant purge のリクエストを送信しています。
console.log('Loading event');
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var http = require('http');

exports.handler = function(event, context) {
   console.log('Received event:');
   console.log(JSON.stringify(event, null, '  '));
   // Get the object from the event and show its content type
   const bucket = event.Records[0].s3.bucket.name;
   const key = event.Records[0].s3.object.key;
   s3.getObject({Bucket:bucket, Key:key},
      function(err,data) {
        if (err) {
           console.log('error getting object ' + key + ' from bucket ' + bucket + 
               '. Make sure they exist and your bucket is in the same region as this function.');
           context.done('error','error getting file'+err);
        }
        else {
           console.log('CONTENT TYPE:' + data.ContentType + ' bucket: ' + bucket + ' path: ' + key);
           context.done(null,'');
        }
      }
   );

  var options = {
    hostname: 'www.example.com',
    port: 80,
    path: '/' + key,
    method: 'PURGE',
  };

  callback = function(response) {
  var str = '';

    //another chunk of data has been recieved, so append it to `str`
    response.on('data', function (chunk) {
      str += chunk;
    });

    //the whole response has been recieved, so we just print it out here
    response.on('end', function () {
      console.log(options.hostname + ':' + options.port + options.path + ' method:' + options.method);
      console.log(str);
    });
  }

  http.request(options, callback).end();
};

6 . Role は Choose an existing role を選択し、Existing role を選択します。
Screen Shot 0029-07-18 at 21.14.43.png

以上で設定は完了です。

動作確認

ここでは index.html ファイルを更新し、パージによりキャッシュ MISS となることを確認します。
1. curl コマンドでキャッシュヒットになることを確認します。

$ curl -svo /dev/null http://www.example.com/lambda
...
< Age: 3
...
< X-Cache: MISS, HIT
< X-Cache-Hits: 0, 1

2 . s3 上の lambda ファイルを更新します
3. curl コマンドでキャッシュミスになることを確認します。

$ curl -svo /dev/null http://www.example.com/lambda
...
< Age: 0
...
< X-Cache: MISS, MISS
< X-Cache-Hits: 0, 0

4 . CloudWatch のログでも下記のように PURGE リクエストが送信されていることが確認できます。
Screen_Shot_0029-07-18_at_22_40_08.png

続きを読む

Elasticbeanstalk(EC2)の1インスタンスでウェブアプリとワーカー実行をしたい

Elasticbeanstalk(以下EB)で動かしているウェブアプリ。今はたいして負荷があるわけじゃないので、1インスタンスで動かしてます。このウェブアプリが参照するデータを、生成するワーカーの実装が必要になりました。こういう時、真面目にやるならEBでワーカー環境を別に作成し、別インスタンスで起動する方法を取るのでしょう。

しかし、お金もったいないので1インスタンスでやりたい(笑)

そこでウェブアプリにワーカー起動用のHTTPリクエストを受け取るようにした。リクエストを受け取ったらバックグラウンド処理を開始し、HTTPレスポンスは即座に返すようにする。一応、外部からむやみに叩かれるのを防ぐために、URLパラメータにGUIDなど長くて予想不能な固定文字列が指定されていた時のみワーカー実行するものとする。

あとはこのURLを定期的にキックしてくれればいい。そこでLambdaとCloudWatchの出番。

Lambdaの関数作成

  • Lambda関数の作成
  • Blank Functionを選択
  • 名前とかロールは適当につける

コードのサンプル(node.js)

var https = require ('https');
exports.handler = function(event, context) {
    https.get("https://example.com/worker/sample?guid=XXXXXXXXXXXXXXXXXXXXX", function(res) {
        if (res.statusCode == 200) {
            console.log("SUCCESS!");
            context.done(null);
        } else {
            var message = "error: status_code:" + res.statusCode;
            context.done(message);
        }
    }).on('error', function(e) {
        context.done('error', e);
    });

これで呼び出されるとhttps://example.com/worker/sample をキックするLambda関数はできた。

CloudWatchのスケジュール作成

  • イベント > ルールを選択
  • ルールの作成でスケジュールを選択
  • 何分おきかとかcron形式で設定できるので設定する
  • ターゲットの追加で作成したLambda関数を選択する

これで、定期的にワーカー実行のURLをキックしてくれる。

続きを読む

AWSのLambdaとDynamoDBとAPIGatewayの連携

2017/7/8 現在の情報です。

作る順番

DynamoDB→Lambda→APIGatewayの順番に作っていきます。

下準備~IAMロールの作成~

IAMにロールの作成が必要です。
今回はLambdaからDynamoDBを呼び出させるので先に以下作業を行っておきます。

IAM > ロール > 新しいロールの作成

ロールタイプの選択画面が出るので、「AWS Lambda」を選択
ポリシーの設定画面が出るので

  • AmazonDynamoDBFullAccess
  • AWSLambdaDynamoDBExecutionRole

を選択します。
※他の記事を読むと、「AWSLambdaDynamoDBExecutionRole」だけで良いと書いてあったんですが
 なんかダメでした。

名前決めろって言われるので適当に「lambda-dynamodb-execution-role」とかにします。

で、ためらわず作成。

DynamoDBの設定

DynamoDBの画面よりテーブルの作成ボタンを押す
テーブル名、PKを決めろって言われるので適当に決める。
今回は適当にHogeテーブル、fugaカラム名にします。

しばらくしたら出来上がるので、項目タブ > 項目作成
ここでキー以外の項目を追加できます。piyoを追加しましょう。
追加する時についでに値も入れられるようです。

分かりにくいので図。

dynamo.png

左の方にあるプラスを押すと項目が増えていきます。
型を設定して、値を入れたら保存。するとpiyoカラムが追加されて、ついでに値も入ります。

はい、これでDynamoDBの設定は終わりです。簡単ですね。

Lambdaの設定

はい、次はLambdaです。

Lambdaの画面でためらわず、Lambda関数の作成を押します。

設計図の選択と言われるので、何言ってるか分からないからBlankFunctionを選びます。
トリガーの設定画面が出ますが、何かよく分からんので次へ。
はい、次の画面、大事です。

名前:fugafuga
説明:ぴよぴよ
ランタイム:Node.js 4.3
Lambda 関数のコード
 コードをインラインで編集 を選ぶ。

こんな感じのコードを書きましょう。

var AWS = require('aws-sdk');
var dynamo = new AWS.DynamoDB({
    region: 'ap-northeast-1'
});
exports.handler = function(event, context) {
    var params = {
        "TableName": "Hoge",
        "KeyConditionExpression":"fuga = :fugafuga",
        "ExpressionAttributeValues": {
            ":fugafuga" : {"S": event.fugafuga}
        }
    };
    console.log("event:", event);
    dynamo.query(params, function(err, data) {
        console.log("dynamo_data:", data);
        console.log("dynamo_err:", err);
        context.done(null, data);
    });

};

node.js読めなくても雰囲気でわかると思います。
Dynamoにつないで、Hogeテーブルのfugaテーブルがevent.fugafugaで取得した値と
同じものを取得しそうですね。

その下の方の「Lambda 関数ハンドラおよびロール」の設定。
ハンドラを「exports.handler」と入力して下さい。
そして、ついに出ました。ロールで最初に作った「lambda-dynamodb-execution-role」を選択します。

次へ、関数を作成をためらわずに押します。

Lambdaのテスト

テストしてみましょう。
関数作ったら上の方に嫌でも目につくテストボタン。押してみます。

謎の入力画面。パラメータを指定できそうなのでこんな感じで入力します。

{
  "fugafuga": "ThisisKey"
}

はい、やったね。上手くいきました。

{
  "Items": [
    {
      "fuga": {
        "S": "ThisisKey"
      },
      "piyo": {
        "S": "piyopiyopiyo"
      }
    }
  ],
  "Count": 1,
  "ScannedCount": 1
}

ぴよぴよ言ってますね。

APIGatewayの設定

はい、APIGatewayです。何のためらいもなく、APIの作成ボタンを押しましょう。

新しいAPIです。API名は適当に「piyopiyo」、説明も適当に「ぴよぴよ」と入力しましょう。
するとこんな画面になります。まずはメソッドを作りましょう。
このセレクトを選んで下さい。

apigateway.png

中身を取得したいのでGETメソッドを作りましょう。
すると何か聞かれるので「統合タイプ:Lambda関数」を選びます。せっかく作ったしね。
リージョンはap-northeast-1、Lambda関数はfugafugaでした。

保存ボタンを押すと、何か怖そうなダイアログが出ますが、怖くない、怖くない。
OKしましょう。

するとなんかイケてる画面になります。
この画面が、どこからどうAPIが呼び出されて、その後何を呼び出して、何を返すのか。
禅問答みたいですね。

apigateway2.PNG

パラメータの設定

APIたるものパラメータを受けて渡す必要があるでしょう。
まず受け方は、↑の図の「メソッドリクエスト」をクリックします。
すると色々設定デキそうですが今回は「URL クエリ文字列パラメータ」を設定します。
適当に「fuga」を設定します。これでfugaパラメータを受け取れるようになりました。

次に「統合リクエスト」をクリックします。
ここでは、APIGatewayからLambdaにパラメータを渡す設定をします。

本文マッピングテンプレートが隠れているので展開して
「リクエスト本文のパススルー」を「テンプレートが定義されていない場合 (推奨) 」を選択
その下の「マッピングテンプレートの追加」を押します。
するとContentTypeが設定できるので「application/json」を選択。
しかしひどいUI。

すると、その下に謎の入力箇所が現れるので、ここでやっと引き渡す値を設定できます。

{
    "fugafuga": "$input.params('fuga')"
}

はい、意味分からんですね。
$input.params(‘fuga’) は、APIGatewayが受ける変数です。?fuga=XXX みたいな感じです。
で、左の”fugafuga”は、Lambdaのeventが受け取る変数名になります。
うえーーの方のLambdaのプログラムでevent.fugafuga って書いてたアレに入ります。

最後。「メソッドレスポンス」を選択。
普通に返却すると日本語が化けるらしく、「本文マッピングテンプレート」にこれを設定します。
「application/json;charset=UTF-8」
もともとあった「application/json」は消します。

これで完成。

APIのデプロイから実行

はい、後はAPIをデプロイすれば使えます。
ここからデプロイを選びましょう。

apigateway3.PNG

デプロイされるステージ:新しいステージ
ステージ名:develop
説明:適当に。
ステージは本番、開発を分けるためのタグですね。
実際は何でも大丈夫です。

はい、デプロイするとURLが発行されます。
https://XXXXXX-api.ap-northeast-1.amazonaws.com/develop
みたいな感じになりますね。

これを押すと、nullが表示されると思います。寂しい。
なぜならパラメータが必要だから。
じゃあパラメータfugaを付けてみましょう。
https://XXXXXX-api.ap-northeast-1.amazonaws.com/develop?fuga=ThisisKey

{"Items":[{"fuga":{"S":"ThisisKey"},
"piyo":{"S":"piyopiyopiyo"}}],"Count":1,"ScannedCount":1}

やった!DynamoDBに入れた値が取れましたね。

はい、これで一連の作業はおしまいです。
結構調べながらやると、管理画面が過去の文言だったりフローが変わってたりと
罠が多かったので2017/7/8時点の情報でまとめました。
誰かの役に立つといいなー:sunny:

続きを読む

[AWS] Lambda + API Gatewayでサーバレスを始める 1

とりあえず、AWS Lambda と API Gateway でサクッとサーバレスをやってみます。
マネジメントコンソールから全部の実装・設定をやってしまいます。
AWS SAM とかは使ってないので、そのあたり(バージョン管理やCLIからのデプロイなど)は別の記事などで補完をお願いします。

ロールの作成

Lambda ファンクション作成時にロールを設定する必要があるので、あらかじめ IAM でロールを作成しておきます。

IAM > ロール > 新しいロールの作成

ロールタイプの選択

AWS Lambda を選択。
スクリーンショット 2017-07-03 9.31.23.png

ポリシーのアタッチ

ここで実行時に必要な権限をアタッチします(DynamoDBとかS3とかのアクセス権限)。
今回は特に何も必要ないので、AWSLambdaBasicExecutionRole をアタッチし、CloudWatch Logs へのアクセス権限のみ付与します。
チェックを入れて「次のステップへ」クリック。
スクリーンショット 2017-07-03 9.45.00.png

確認

ロール名を入力し(必要ならDescriptionを入力し)、ロールの作成をクリック。
スクリーンショット 2017-07-03 9.49.13.png

Lambda ファンクションの作成

先に API Gateway の設定をすることもできますが、ここでは先に Lambda を書きます。

Lambda > Lambda関数の作成 > Blank Function > (トリガーは設定せずに)次へ

関数の設定

関数名を入力し、ランタイムを選択します。
今回は Node.js 6.10 にします。
スクリーンショット 2017-07-03 9.51.41.png

先ほど作成したロールを選択して次へ。
スクリーンショット 2017-07-03 10.07.41.png

確認

内容確認して、「関数の作成」クリック。
スクリーンショット 2017-07-03 10.09.54.png

コードの変更

ひとまずJSONを返却するようにします。

exports.handler = (event, context, callback) => {
    callback(null, {"name": "hoge"});
};

API Gateway の設定

API Gateway > APIの作成

API名を入力して、「APIの作成」クリック。
スクリーンショット 2017-07-03 14.04.15.png

リソース作成

リソースのアクションから、メソッドの作成を選択。
スクリーンショット 2017-07-03 14.07.43.png

GETを選択肢、チェックマークをクリックして確定。
セットアップ画面になるので、Lambdaを作成したリージョン※1とLambdaファンクション名※2を入力して保存。
※1 : コンソールの上部で表示されているリージョンで作成されています。東京なら「ap-northeast-1」を選択。
※2 : 最初の文字を入力すれば、候補が表示されます。
スクリーンショット 2017-07-03 14.10.22.png

リソースが作成されたので、ひとまずテストを実行してみます。
スクリーンショット 2017-07-03 14.16.49.png

「テスト」ボタンをクリックすると、成功していることがわかります。
ステータスが200で、JSONが返ってきていることを確認してください。
スクリーンショット 2017-07-03 14.18.15.png

APIのデプロイ

リソースのアクションから「APIにデプロイ」を選択。
スクリーンショット 2017-07-03 14.44.41.png

「新しいステージ」を選択し、ステージ名を入力。
ここでは「prod」と入力。
スクリーンショット 2017-07-03 14.45.51.png

デプロイすると、APIエンドポイントが作成されます。
スクリーンショット 2017-07-03 14.48.14.png

CORSの設定

CORSの設定は、 API Gateway リソースのアクションから設定できます。
スクリーンショット 2017-07-03 14.54.42.png

設定を変更したあとは、再度APIをデプロイする必要があります。

パスパラメータ

「/prod/:id」ってしたい時の設定方法。

リソース > アクション > リソースの作成
スクリーンショット 2017-07-03 15.15.36.png

新たに子リソースを追加します。
その際、リソースパスの文字列を{}で括ります。
スクリーンショット 2017-07-03 15.17.37.png

リソース作成後、{id}にGETメソッドを作成します。
Lambdaの設定をします。
スクリーンショット 2017-07-03 15.23.44.png

APIのテスト実行画面で、パスが入力可能になっていることを確認します。
スクリーンショット 2017-07-03 15.25.03.png

Lambdaからパラメータを取得できるように設定します。
統合リクエストをクリック。
スクリーンショット 2017-07-03 15.31.25.png

本文マッピングテンプレート > マッピングテンプレートの追加
「application/json」と入力してチェックマーククリックで確定。
スクリーンショット 2017-07-03 15.32.54.png

以下のように、マッピングを記述します。
スクリーンショット 2017-07-03 15.36.18.png

{
  "id": "$input.params('id')"
}

Lambdaでパラメータを取得できるようになったので、以下のように変更します。
パラメータはeventから取得できます。

exports.handler = (event, context, callback) => {
    callback(null, {"id": event.id, "name": "hoge"});
};

テストを実行し、入力値が返ってきていることを確認してください。
スクリーンショット 2017-07-03 15.42.11.png

クエリパラメータ

「/prod?name=:name」ってしたい時の設定方法。

メソッドリクエストから設定します。
スクリーンショット 2017-07-03 15.45.10.png

URL クエリ文字列パラメータに「name」を入力し、チェックマークで確定します。
スクリーンショット 2017-07-03 15.46.17.png

パスパラメータの時と同様、統合リクエストからマッピングテンプレートを設定します。
スクリーンショット 2017-07-03 15.48.54.png

Lambdaを変更します。

exports.handler = (event, context, callback) => {
    callback(null, {"id": event.id, "name": event.name});
};

テストで、クエリ文字列が入力可能になっています。
入力値が返ってきていることを確認してください。
※idはクエリ文字列で入力できないのでundefinedになり、nameだけがJSONで返却されます。
スクリーンショット 2017-07-03 15.57.57.png

文字化けするときは

日本語が文字化けする場合、メソッドレスポンスで文字コードを設定します。
スクリーンショット 2017-07-03 16.02.49.png

200のレスポンス本文の「application/json」を編集(ペンマークをクリック)します。
スクリーンショット 2017-07-03 16.05.20.png

「;charset=UTF-8」を追記し、保存します。
スクリーンショット 2017-07-03 16.07.20.png

その2に続く→

続きを読む

古いruntimeのAWS Lambdaを一括削除する

Lambdaで古いruntimeが設定されているfunctionがあるとアラートが飛んできて鬱陶しいです。

AWS Lambda to end support for Node.js v0.10 runtime, please migrate to Node.js v4.3 or v6.10 immediately

LATEST 以外のバージョンのfunctionも古いruntimeが設定されていると、アラートが飛んで来るので、古いruntimeのfunctionはすべて削除してしまいます。

aws lambda list-functions | 
    jq ".Functions[].FunctionName" -r | 
    xargs -I{} aws lambda list-versions-by-function --function-name {} | 
    jq -r '.Versions[] | select(.Runtime == "nodejs" and .Version != "$LATEST") | .FunctionArn' | 
    xargs -I{} aws lambda delete-function --function-name {}

上のコマンドを実行するだけです。念のため、バージョンが $LATEST のものは除外しています。

aws cliを実行するのが直列なので時間がかかりますが、 xargs の -P オプションを使って適当に並列化すれば良さそうです。

続きを読む

AWS Lambdaでwebサイトの死活監視をして、Slackに報告する

はじめに

やりたかったこと

  • 定期的にwebサイトへリクエストを投げて、サーバの生死を確認したい
  • 複数の宛先をまとめてチェックしてほしい
  • 結果はSlackで確認したい
  • 報告は異常があった時だけでいいや

スキルレベル

  • EC2とかroute53は使うが、Lambdaは未経験
  • JavaScriptは日常的に使うが、Node.js未経験
  • Slack Web APIは経験あり

要件

  • 任意のホスト、任意のパスにリクエストを送り応答を受け取る
  • ステータスコード200なら正常とする
  • 幾つかのサイトを1つのLambda関数で監視する 追加や変更も簡単にしたい

作業

Lambdaを使用する準備

Lambda.png

関数の作成

AWSダッシュボードからLambdaを開き、「関数の作成」を選択。
なにやら「https-request」というテンプレートを発見。これを使うことにしましょう。

alive1.png

「https-request」を選択し、次へ。

alive4.png

このLambda関数を呼び出す条件を選択するようです。

とりあえず、5分ごとに起動するように設定してみました。
慣れているcron式で記入→「cron(0/5 * * * ? *)」
意味は左から順に、

0/5 * * * ? *
5分毎 毎時 毎日 毎月 曜日指定なし 毎年

となります。
「日」と「曜日」のみOR条件になっていて、毎日にするならどちらかを指定なしにしないとバリデーションエラーで進めないので気をつけましょう。これは普通のcronでも同じ。
最後の「年」はcronにはありませんね。

ここは後からでも設定・追加できるので、よくわからなければスルーでおk。
で、次

alive3.png

ロールは適当に作っちゃいました。ロールについてはこちら。
要するに、この関数を扱える権限の設定といったところ。
カンケーない人にはカンケーない項目なのでサクッと進みましょう。

Slack Web API

Slackに投稿するためのトークンを取得します。
@ykhiraoさんのこちらの記事Slack APIのTokenの取得・場所
を参考にさせていただきました。

もう一つ、投稿したいチャンネルのコードを取得します。
任意のチャンネルのURLに含まれる、この赤枠の部分です。
スクリーンショット 2017-07-01 12.55.35.png

コード


'use strict';

const https = require('https');
const querystring = require('querystring');

//Slack web API
const SLACK_HOST = 'slack.com';
const SLACK_PATH = '/api/chat.postMessage';
const TOKEN = 'トークン'; // 取得したSlackのトークン
const CHANNEL = 'チャンネル'; // 投稿したいチャンネルのコード
const NAME = 'INOKI BOT';
const ICON = ':rage1:';

function sendSlack(message, context){

    var formData = {
        token: TOKEN,
        channel: CHANNEL,
        text: message,
        as_user: false,
        icon_emoji: ICON,
        username: NAME,
    };
    var options = {
        hostname: SLACK_HOST,
        path: SLACK_PATH,
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
    };
    var req = https.request(options, function(res){
        res.on('data', function(d) {
            console.log(d + "n");
        });
    });
    req.write(querystring.stringify(formData));
    req.on('error', function(e){
        console.log("Slackにメッセージを送信できませんでしたn" + e.message);
    });
    req.end();
}



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

    /**
     * paramList
     * host: 検証したいホスト
     * path: 検証したいパス(200が返ってくるところ)
     * auth: Basic認証の"username:password"
     */
    var paramList = new Array(
        { host: 'example.com', path:'', auth: '' },
        { host: 'example.com', path: '/about', auth: '' },
        { host: 'api.fugafuga.jp', path: '/login', auth: 'hogehoge:hogehoge!' }
    );
    var index = 0;

    sendSlack('< 元気ですかー!');
    function checkAlive(index) {
        var option = paramList[index];
        if(index == paramList.length){
            context.succeed();
            return;
        }
        index++;

        // httpsでリクエストを送ってみる
        var req = https.request(option, function (response) {
            var code = response.statusCode;
            if (code != 200) {  // 負けること考えるバカいるかよ!
                var message = "n*【異常】* n" + option.host + option.path + " は元気がないようですn- STATUS CODE " + code;
                console.log(message);
                sendSlack(message, context);
            }
            else{   // 元気があればなんでもできる
                var message = option.host + " : " + code;
                console.log(message);
            }
            checkAlive(index);
        });
        req.on('error', function (error) {  // まるで屍のようだ
            var message = "n*【エラー】* n" + option.host + " にリクエストを送信できません";
            message += "n - ERROR MESSAGE : " + error.message + "n";
            console.log(message);
            sendSlack(message, context);
            checkAlive(index);
        });
        req.end();
    }

    checkAlive(index);
}

使い方としては、生死を確認したい宛先の情報をparamListに追加するだけ。
APIサーバだとアクセスを許可するドメインを制限したりする場合があると思うので、200が返ってくるパスを指定できるようにしています。
ついでにbasic認証も通せるように。

Node.jsとはいえただのJavaScriptで書けばいいのです。楽勝楽勝。

https.requestは非同期で実行されるので、そのままだとレスポンスを受け取る前に関数が終了してしまいます。
checkAlive関数を再帰的に呼び出し、一つ一つ実行していくような形で実装。
全てのホストを確認した後、context.success()を呼び関数を終了します。

この方法にはホストの状態によっては関数がタイムアウトするというデメリットがあります。
デフォルトでは1分になっている設定を増やせばタイムアウトしにくくはなりますが、まあ気持ち悪いですね。
Promiseとかでなんとかできたらいいな…(←たぶんやらない)
 

実行結果

コンソール出力

example.com : 200

*【異常】* 
example.com/about は元気がないようです
- STATUS CODE 404

*【エラー】* 
api.fugafuga.jp にリクエストを送信できません
 - ERROR MESSAGE : getaddrinfo ENOTFOUND api.fugafuga.jp api.fugafuga.jp:443

Slack

スクリーンショット 2017-07-02 0.54.16.png

example.comは例示用ドメインとして実際にアクセスできますが、/aboutなんてパスはないので404。
api.fugafuga.jpは存在しないドメインとしてエラーを吐きます。

なお、関数内でconsole.logを使って出力した部分はCloudWatchのロググループ(=Lambda関数名)で確認できます。

おしまい。

続きを読む

AWS概要

AWSについてこれから学んでいくのでその勉強内容をまとめていく。

1.AWSとは

AWS(Amazon Web Service)とはオンラインショッピングで有名なAmazonが提供するパブリッククラウドサービス。
サービスの豊富さと提供スピードの速さが特徴。

1.1アマゾンが提供するサービス

AWSでは多くのサービスが提供されているが、そのサービスを分類ごとに大別し、代表的なものを紹介する。

  • コンピューティング
  • ストレージ&コンテンツ配信
  • データベース
  • ネットワーク
  • 開発者用ツール
  • 管理ツール
  • セキュリティ&アイデンティティで
  • 分析
  • IoT
  • モバイル
  • アプリケーションサービス
  • エンタープライズアプリケーション

1.1.1 コンピューティング

AWSの中核となるサービス。
AWS超初心者の私でも聞いたことがあるEC2もここに分類される。

・EC2(Amazon Elastic Compute Cloud)

従課金性(使った分だけお金を払う)の仮想サーバ。
OSはLinuxやWindowsが用意されている。
EC2を活用してDockerを運用したりDockerイメージの保存・共有を行うサービスも提供されている。

・AWS Elastic Beanstalk

Paasサービス。
これを利用すれば.NETやPHP、Python、Ruby、Node.jsで開発したアプリをAWSに自動でデプロイできる。
例えばJavaアプリの場合はEclipceで開発してEC2に配置するというところまでを自動でやってくれる。

・AWS Lambda

クライアントからリクエストが来た時だけ動くイベントドリブン型のサービス。
EC2と違って常時起動しているわけではないので低コストで運用できる。

・Auto Scaling

CPU使用率などの条件に応じてEC2を拡張するサービス

・Elastic Load Balancing

負荷分散させるロードバランサのQWSバージョン。

1.1.2 ストレージ&コンテンツ

・Amazon S3

オンラインストレージサービス。

・Amazon CloudFront

世界中にコンテンツを配信するためのネットワークサービス

・Amazon EBS

EC2のデータを保持するストレージサービス。
EC2のHDやSSDのような役割。
EC2のインスタンスタイプがc4やM4だとストレージはこのEBSのみ。
EBSは確保した容量の分だけ料金がかかるので容量が大きいファイルを扱うときは注意が必要。

・Amazon Elastic File System

EC2の共有ファイルストレージサービス。
使用容量の増減に伴って自動で拡張/縮小する。

・Amazon Glacier

バックアップファイルなど、使用頻度は低いけど長期間保持しておきたいデータ向けの低価格ストレージサービス。

・AWS Import/Export Snowball

大容量データ転送サービス。
ペタバイトレベルのものでも転送可能。

・AWS Storage Gateway

オンプレとAWSを接続するGW

1.1.3 データベース

・Amazon RDS

RDBMSを運用するサービス。
MySQLやOracle、SQLServer等が運用可能。

・AWS Database Migration Service

データベース移行サービス

・Amazon DynamoDB

noSQLの構築/運用サービス。
noSQLとはビッグデータなどで使用されるDBMS。

1.1.4 ネットワーク

・Amazon VPC

AWS内にプライベートネットワークを構築するためのサービス。

・AWS Direct Connect

オンプレのネットワークとAWSのネットワークをつなぐためのサービス。

・Amazon Route 53

DNSシステムを構築するためのサービス。

1.1.5 開発者用ツール

・AWS CodeCommit

Git等のバージョン管理ツールを運用するためのサービス。

・AES CodeDeploy

開発したアプリを自動でデプロイするサービス

1.1.6 管理ツール

・Amazon CloudWatch

サーバ・ネットワークの状態をグラフィカルに確認できたり設定した閾値を超えたときにアラートを出すことができるサービス。

・AWS CloudFormation

テンプレートと呼ばれるファイルを作成することでAWSで構成するインフラ環境を自動で作成するサービス。

セキュリティ&アイデンティティ

IAM(AWS Identity and Access Management)

ユーザ認証などの認証機能を提供するサービス。

分析

Amazon EMR

ビッグデータの分散処理フレームワークであるApache Hadoopの実行基盤

Amazon Machine Lerning

データを基に機械学習をするサービス。
AIなどの研究に使われる。

IoT

AWS IoT

AWSとデバイスとの接続、ネットワーク管理、セキュリティ、データベースとの接続を提供するサービス。

モバイルサービス

Amazon Cognito

アカウント管理・認証、データ同期などを行うサービス。

AWS MobileSDK

OSに合わせた開発ツールを用意するサービス

アプリケーションサービス

Amazon SES

Emailの送受信サーバ

・Amazon Cloud Search

クラウド内のデータ検索を行うサービス。

エンタープライズアプリケーション

・Amazon WorkSpaces

デスクトップPCをクラウド上で実行するサービス。


ざっとまとめただけでもこの量。。。
全部のサービスの内容を理解するのは無理かもしれないけど
何かやろうとしたときにそういえばAWSにこんなサービスがあったような…
と思い出して選択肢の一つに入れれるようになりたい。

続きを読む