やーまんぶろぐ

気が向いた時にだけ書くブログ

Serverless Web Application Workshop をCLIでやってみた Lab 3: Administrative Interface

サーバーレスアーキテクチャ Advent Calendar 2016 の24日目の記事です。

「Serverless Web Application Workshop をCLIでやってみた Lab2: Beta Sign-up Mailing List」 の続きになります。
yamano3201.hatenablog.jp

大枠はこちらで紹介されています。
qiita.com

コンソールでの手順はREADMEに記載されています。
github.com

CLIに置き換えてみたものをメモしていきます。
作業はMacで、リージョンはバージニアを想定して書いてます。

ワークショップは全部で4つあります。

  • Lab 1: Static Website Hosting
  • Lab 2: Beta Sign-up Mailing List
  • Lab 3: Administrative Interface
  • Lab 4: Product Update Blog

今回はLab 3: Administrative Interfaceについて書いていきます。

やること

管理インターフェイスの作成。Cognito user poolを使って管理者を定義し、DynamoDBに記録されている登録ユーザ一覧を取得するLambdaとIAM roleを作成し、API Gateway(GET resource)でLambda Proxy連携とCognito user pool認証を設定してウェブアプリから呼び出せるAPI endpointを作成してウェブアプリ側に埋め込む。ウェブアプリで管理者としてログイン後、登録ユーザ一覧が表示される事を確認。

Cognito user poolを使って管理者を作成

  • まずはuser poolを作成します。
  • user poolに紐づく管理者を作成します。ユーザネームとパスワードで認証できます。
  • 後半でAPIGatewayのAuthorizerにuser poolを設定することで、ログインされたユーザのみAPIを呼び出せるように認可の設定をすることができます。
  • パスワードには大文字、数字、記号を入れて8文字以上の文字列を指定します。
$ export USER_POOL=$(aws cognito-idp create-user-pool --pool-name Wildrydes_Admin --admin-create-user-config AllowAdminCreateUserOnly=true | jq -r '.UserPool.Id')
$ export USER_POOL_CLIENT=$(aws cognito-idp create-user-pool-client --user-pool-id ${USER_POOL} --client-name web | jq -r '.UserPoolClient.ClientId')
$ aws cognito-idp admin-create-user --user-pool-id ${USER_POOL} --username yamano1023@gmail.com --temporary-password XXXXXX

LambdaとDynamoDBにアクセス可能なIAMロールの作成

  • LambdaとDynamoDBにアクセスできるIAMロールを作成しておきます。
  • ロールを作成してからポリシーをアタッチします。
$ export ASSUME_ROLE=assume_role.json
$ cat << EOF > ${ASSUME_ROLE}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
$ export LAMBDA_DYNAMODB_ROLE=$(aws iam create-role --role-name LambdaDynamoDBRole --assume-role-policy-document file://${ASSUME_ROLE} | jq -r  .'Role.Arn')
$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess --role-name LambdaDynamoDBRole
$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole --role-name LambdaDynamoDBRole

DynamoDBから登録ユーザ一覧を取得するLambdaを作成

  • ロジックはREADMEに書かれているコードをコピーします。DynamoDBから登録ユーザ一覧を取得するコードになっています。
  • コードはzip化して渡します。
$ cat << EOF > index.js
var aws = require('aws-sdk');
var dynamodb = new aws.DynamoDB({});

exports.handler = (event, context, callback) => {
 var params = {
   TableName: "Wildrydes_Emails"
 };

 dynamodb.scan(params, function(err, data) {
   if (!err) {
     var emails = [];
     data.Items.forEach((item) => emails.push(item.Email.S));

     context.succeed({
       statusCode: '200',
       headers: { 'Access-Control-Allow-Origin': '*'},
       body: JSON.stringify({ Emails: emails })
     });
   } else {
     context.fail(err);
   }
 });  
};
EOF

$ zip -r get_all_emails.zip index.js
$ export GET_ALL_EMAILS=$(aws lambda create-function --region us-east-1 --function-name GetAllEmails --role ${LAMBDA_DYNAMODB_ROLE} --runtime nodejs4.3 --handler index.handler --zip-file fileb://get_all_emails.zip | jq -r '.FunctionArn’)

Lambda連携とCognito user pool認証を設定したAPI Gateway作成

リソース作成

  • rest apiを作成します。
  • user poolを設定したAuthorizerを作成します。
  • emailsのリソースを作成します。emailsがそのままパスになります。
  • 今回のようにパスがルート直下の場合は、ルートIDを指定して作成します。
$ export API=$(aws apigateway create-rest-api --name Wildrydes | jq -r '.id')
$ export ACCOUNT=$(aws sts get-caller-identity | jq -r ".Account")
$ export AUTHORIZER=$(aws apigateway create-authorizer --rest-api-id ${API} --name Wildrydes_Admin --type COGNITO_USER_POOLS --identity-source 'method.request.header.Authorization' --provider-arns arn:aws:cognito-idp:us-east-1:${ACCOUNT}:userpool/${USER_POOL} | jq -r '.id')
$ export ROOT_ID=$(aws apigateway get-resources --rest-api-id ${API} | jq -r '.items | map(select(.path == "\/"))' | jq -r '.[].id')
$ export RESOURCE=$(aws apigateway create-resource --rest-api-id ${API} --parent-id ${ROOT_ID} --path-part emails | jq -r '.id')

OPTIONSメソッド作成

  • CORSを有効化するためにemailsリソースにOPTIONSメソッドを作成します。これを設定しないとブラウザからアクセスすることができないので注意が必要です。
  • メソッドリクエスト、統合リクエスト、統合レスポンス、メソッドレスポンスの4つを作成します。
    • リソースに対するメソッド (OPTIONS) を作成します。
    • MOCKタイプで統合リクエストを作成します。
    • メソッドレスポンスのレスポンスヘッダーにAccess-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Originを追加します。
    • 統合レスポンスでヘッダーのマッピングをします。
$ aws apigateway put-method --rest-api-id ${API} --resource-id ${RESOURCE} --http-method OPTIONS --authorization-type NONE --no-api-key-required --request-parameters '{}'
$ aws apigateway put-integration --rest-api-id ${API} --resource-id ${RESOURCE} --http-method OPTIONS --integration-http-method POST  --type MOCK --request-templates '{ "application/json": "{\"statusCode\": 200}" }' --passthrough-behavior WHEN_NO_MATCH
$ aws apigateway put-method-response --rest-api-id $API --resource-id $RESOURCE --http-method OPTIONS --status-code 200 --response-models '{"application/json": "Empty"}' --response-parameters "method.response.header.Access-Control-Allow-Headers=false,method.response.header.Access-Control-Allow-Methods=false,method.response.header.Access-Control-Allow-Origin=false"
$ aws apigateway put-integration-response --rest-api-id ${API} --resource-id ${RESOURCE} --http-method OPTIONS --status-code 200 --response-templates '{"application/json": ""}' --response-parameters '{"method.response.header.Access-Control-Allow-Headers": "'"'"'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"'"'" , "method.response.header.Access-Control-Allow-Methods": "'"'"'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"'"'", "method.response.header.Access-Control-Allow-Origin": "'"'"'*'"'"'"}'

GETメソッド作成

  • リソースに対するメソッド (GET) を作成します。
  • 認証の設定でuser poolを設定したAuthorizerを設定します。
  • Lambda 関数を GET メソッドの送信先に設定します。
  • prodステージにAPI をデプロイします。
  • API Gateway が Lambda 関数を呼び出すためのアクセス権限を付与します。ステージごとにアクセスを絞りたい場合は*をprodに変更します。
$ aws apigateway put-method --rest-api-id ${API} --resource-id ${RESOURCE} --http-method GET --authorization-type COGNITO_USER_POOLS --authorizer-id ${AUTHORIZER} --no-api-key-required
$ aws apigateway put-integration --rest-api-id ${API} --resource-id ${RESOURCE} --http-method GET --integration-http-method POST --type AWS_PROXY --uri "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/${GET_ALL_EMAILS}/invocations" --content-handling CONVERT_TO_TEXT
$ aws apigateway put-integration-response --rest-api-id ${API} --resource-id ${RESOURCE} --http-method GET --status-code 200 --response-templates '{"application/json": ""}'
$ aws apigateway put-method-response --rest-api-id ${API} --resource-id ${RESOURCE} --http-method GET --status-code 200 --response-models '{"application/json": "Empty"}'
$ aws apigateway create-deployment --rest-api-id ${API} --stage-name prod
$ aws lambda add-permission --function-name GetAllEmails --statement-id prod --action lambda:InvokeFunction --principal apigateway.amazonaws.com --source-arn "arn:aws:execute-api:us-east-1:${ACCOUNT}:${API}/*/GET/emails"

ワークショップ用に用意されたlab3のファイルをS3にsync

  • アプリコードは用意されたものを使います。
  • userPoolIdとuserPoolClientId、apiUrlを今回のものに書き換えてからsyncします。
  • /adminにアクセスしてログインします。
  • Cognito user poolを使って作った管理者でログインして、「View Emails」からDynamoDBから登録ユーザ一覧を取得して表示します。
$ cp lab2/scripts/config.js lab3/scripts
$ sed -i -e "s/userPoolId: \'\'/userPoolId: \'${USER_POOL}'/" lab3/scripts/config.js
$ sed -i -e "s/userPoolClientId: \'\'/userPoolClientId: \'${USER_POOL_CLIENT}'/" lab3/scripts/config.js
$ sed -i -e "s/apiUrl: \'\'/apiUrl: \'https:\/\/${API}.execute-api.us-east-1.amazonaws.com\/prod\'/" lab3/scripts/config.js
$ aws s3 sync lab3/ s3://${BUCKET_NAME} 
$ open https://$(cat cloudfront.json | jq -r '.Distribution.DomainName')/admin

最後に

CORSエラーの解消にけっこう時間を消費してしまいました。。
けっきょくLambda 関数を呼び出すためのアクセス権限が抜けていたのが原因でした。Lambda側の設定だったので見逃していました。

最後の1つも頑張ります。

【ソフトインストール不要】WMVファイルをiOSで再生できる形式(movファイル)に変換する方法

WMVファイルをiOSで再生しようとしたのですが、そもそもダウンロードできませんでした。
わざわざ変換ソフトとかは入れたくないので試行錯誤していたら、簡単にiOSで再生できたのでメモしておきます。

やること

Google DriveにあるWMVファイルを選択して、CloudConvertで変換するだけです。

Google Driveでファイルを選択

Google Driveにログイン → ファイルを選択して右クリック「Open with」 → 「CloudConvert」 を選択します。
f:id:yamano3201:20161221135730p:plain

CloudConvertで変換

変換後のファイル形式を選択して、「anything」 → 「video」 → 「mov」 を選択します。
「Save file to my Google Drive」にチェックが入っていることを確認して「Start Conversion」ボタンを押すと変換後のファイルがGoogle Driveに保存されます。
f:id:yamano3201:20161221141117p:plain

最後に

調べないでも触ってたらわかるというのは地味に素晴らしいですね。

今回はiOSで再生するユースケースでCloudConvertについて書いてますが、たくさんのファイル形式に対応しているので様々な場面で活躍できるサービスだと思います。

ファイル形式がたくさんあるだけでなく、直接CloudConvertにファイルアップロードできたり、APIがあったり、Dropbox連携ができたりと細かいところが作り込まれてて使えそうなサービスですね。

ふるさと納税でベビー用品を申し込み

今年もふるさと納税の申し込みをしたいと思います。

実質2000円負担で各自治体からお礼の品がもらえるのでやらないと損ですね。

ふるさとチョイスを使えば、自分がどれくらい使えるのか管理しながら購入まで簡単に行うことができます。
www.furusato-tax.jp

今年は子供が生まれたので0歳から1歳くらいまでで使えそうなものを中心に申し込みたいと思います。

基本的には2016年分は12/31までに申し込みが必要なので、まだの方は急いで申し込んでみてはどうでしょうか。

セーフティグッズ

これは買おうと思っていたので嬉しかったですね。
部屋の中に階段があるので、赤ちゃんが動き出す前に準備しておこうと思います。

絵本

絵本も欲しかったので嬉しいですね。

ワンストップ特例制度

確定申告の不要な給与所得者はワンストップ特例制度を使うと手続きも簡単です。
www.furusato-tax.jp

必要な書類と合わせて、送られてくる書類に記入して送り返すだけなので迷うことも少ないと思います。

ただし年収2,000万円以上の所得者や医療費控除のために確定申告が必要な場合や、
1年間の寄附先が6自治体以上になる場合は確定申告で寄附金控除を行う必要があります。

我が家は今年出産があり医療費控除のために確定申告が必要になるので、ワンストップ特例制度は使えないみたいですね。残念。

最後に

とてもありがたいことに、今年は親戚一同のふるさと納税を娘のために使わせていただきました。
当たり前ですが、私一人ではこんなに選べない。。

既に持っているのでベビーベッドやベビーカーなどは選びませんでしたが、他にもたくさんあるので探してみてはどうでしょうか。

5.X系のElasticSearch + KibanaをMacにインストール

本日、Elastic{ON}Tour 2016に参加します。
Tokyo 2016 | Elastic

準備として、5.X系のElasticSearch + KibanaをMacをインストールしたので手順をメモしておきます。

こちらを参考にしながらインストールしました。
innu.hateblo.jp

最新版の5.1.1をMacにインストールしました。

ElasticSearchダウンロード

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.1.1.tar.gz
$ tar xvzf elasticsearch-5.1.1.tar
$ cd elasticsearch-5.1.1
$ ./bin/elasticsearch
$ open http://localhost:9200

JSONが表示されたらOKです。

Kibanaダウンロード

$ wget https://artifacts.elastic.co/downloads/kibana/kibana-5.1.1-darwin-x86_64.tar.gz
$ tar xvzf kibana-5.1.1-darwin-x86_64.tar.gz
$ cd kibana-5.1.1-darwin-x86_64
$ ./bin/kibana
$ open http://localhost:5601

リッチなUIが表示されたらインストールOKです。

最後に

だいぶ昔のバージョンと、AWSのマネージドなElasticSearchしか触ったことがないので最新版でどんなことができるのか楽しみです。
本当はもっと触ってから参加する予定だったのですが、時間取れなかったです。。

会場に向かう電車でAdvent Calendar 2016くらい目を通してから参加したいと思います。
qiita.com

Serverless Web Application Workshop をCLIでやってみた Lab2: Beta Sign-up Mailing List

サーバーレスアーキテクチャ Advent Calendar 2016 の13日目の記事です。

「Serverless Web Application Workshop をCLIでやってみた Lab 1: Static Website Hosting」 の続きになります。
yamano3201.hatenablog.jp

大枠はこちらで紹介されています。
qiita.com

コンソールでの手順はREADMEに記載されています。
github.com

(できるだけ)CLIに置き換えてみたものをメモしていきます。
作業はMacで、リージョンはバージニアを想定して書いてます。

ワークショップは全部で4つあります。

  • Lab 1: Static Website Hosting
  • Lab 2: Beta Sign-up Mailing List
  • Lab 3: Administrative Interface
  • Lab 4: Product Update Blog

今回はLab 2: Beta Sign-up Mailing Listについて書いていきます。

やること

ベータサービスにユーザがサインアップするメーリングリストを作成。認証のいらないユーザなので、Cognito identity poolとIAM policyを使って、DynamoDBにメールアドレスが書き込まれ、DyanmoDB StreamsからのLambda連携で確認メールをSESを使って配信する。一般ユーザがサインアップ後、確認メールが自身のメールアドレスに届く事を確認する。

送信元メールアドレス検証

  • XXX@XXXXXX.XXXにはメールが受け取れる自分のアドレスを設定しましょう。
  • 登録した送信元メールアドレスに検証要求メールが届くので、リンクをクリックして検証しましょう
$ export EMAIL_ADDRESS=XXX@XXXXXX.XXX
$ aws ses verify-email-identity --email-address ${EMAIL_ADDRESS}

LambdaとSESにアクセス可能なIAMロールの作成

  • LambdaとSESにアクセスできるIAMロールを作成しておきます。
  • ロールを作成してからポリシーをアタッチします。
  • 後半のLambda作成まで出番はありません。
$ export ASSUME_ROLE=assume_role.json
$ cat << EOF > ${ASSUME_ROLE}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
$ aws iam create-role --role-name LambdaSESRole --assume-role-policy-document file://${ASSUME_ROLE}
$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonSESFullAccess --role-name LambdaSESRole
$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole --role-name LambdaSESRole

Emailの値を取得するためのAmazon DynamoDBテーブルを作成

  • DynamoDBテーブルを作成します。
  • 後で使うのでTableArnをレスポンスから取得しておきます。
$ aws dynamodb create-table --table-name Wildrydes_Emails --attribute-definitions AttributeName=Email,AttributeType=S --key-schema AttributeName=Email,KeyType=HASH --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 > dynamodb.json

$ export TABLE_ARN=$(cat dynamodb.json | jq -r '.TableDescription.TableArn')

認証のいらないユーザがアクセス可能なAmazon Cognito IDプールの作成

$ aws cognito-identity create-identity-pool --identity-pool-name wildrydes --allow-unauthenticated-identities > cognito.json
export COGNITO=$(cat cognito.json | jq -r '.IdentityPoolId')

認証のいらないユーザ用のIAMロールの作成とポリシーの付与

  • 手順通りコンソールからだと自動で作成されてセットされるので圧倒的にラクできます。無理やりCLIからIAMロール作成してみました。
  • Unauth Role(認証のいらないユーザ用のロール)につけるポリシーで、DynamoDBにPUTアクションを許可する設定を追加します。
  • READMEの手順で作るとAuth Roleにのみつくので注意しましょう。ここでの手順はUnauth Roleのポリシーも変更する手順としているので順番にコピペすれば大丈夫です。
  • 直接は使わないけどAuth_Roleも作成しておきます。おそらく作成してアタッチしないとダメな気がする。
$ export COGNITO_AUTH_ROLE=cognito_auth_role.json
$ cat << EOF > ${COGNITO_AUTH_ROLE}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "${COGNITO}"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}
EOF

$ aws iam create-role --role-name Cognito_wildrydesAuth_Role --assume-role-policy-document file://${COGNITO_AUTH_ROLE}
$ export COGNITO_POLICY=cognito_policy.json
$ cat << EOF > ${COGNITO_POLICY}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "dynamodb:PutItem",
      "Resource": "${TABLE_ARN}"
    }
  ]
}
EOF
$ aws iam put-role-policy --role-name Cognito_wildrydesAuth_Role --policy-name oneClick_Cognito_wildrydesAuth_Role --policy-document file://${COGNITO_POLICY}
  • 認証のいらないユーザ用のIAMロールの作成とポリシーの付与
$ export COGNITO_UNAUTH_ROLE=cognito_unauth_role.json
$ cat << EOF > ${COGNITO_UNAUTH_ROLE}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "${COGNITO}"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "unauthenticated"
        }
      }
    }
  ]
}
EOF
$ aws iam create-role --role-name Cognito_wildrydesUnauth_Role --assume-role-policy-document file://${COGNITO_UNAUTH_ROLE}
$ aws iam put-role-policy --role-name Cognito_wildrydesUnauth_Role --policy-name oneClick_Cognito_wildrydesUnauth_Role --policy-document file://${COGNITO_POLICY}

作成したAWS Cognito IDプールに作成したロールをセット

  • けっきょくCLIからAuthenticated role, Unauthenticated roleのアタッチがわかりませんでした。。
  • コンソールからアタッチしてください。。

ワークショップ用に用意されたlab2のファイルをS3にsync

  • アプリコードは用意されたものを使います。
  • regionとIDプールを今回のものに書き換えてからsyncします。
$ sed -i -e "s/region: \'\'/region: \'us-east-1\'/" lab2/scripts/config.js
$ sed -i -e "s/identityPoolId: \'\'/identityPoolId: \'${COGNITO}\'/" lab2/scripts/config.js
$ aws s3 sync lab2/ s3://${BUCKET_NAME}

CloudFront経由でアクセスしてSIGN UP

  • Lab1で作成したCloudFront経由でアクセスしましょう。
  • 画面の下のほうにあるSIGN UP画面からSIGN UPしましょう。
$ open https://$(cat cloudfront.json | jq -r '.Distribution.DomainName')

f:id:yamano3201:20161213004224p:plain

  • 最初に検証したメールアドレスを入力、エンターして、[SIGN UP]の文字が[THANK YOU]に変化することを確認しましょう。
  • これでDynamoDBにPUTされたことを確認しましょう。
  • PCのSafari, Chromeの場合はSUBMITボタンが押せなかったのでenterを押しましょう。
  • iPhoneSafariの場合はSUBMITボタンを押せました。

SESを使ってメールを送信するLambdaを作成

  • 最初に作ったLambdaSESRoleのARNを使います。
  • ロジックはREADMEに書かれているコードをコピーします。変更後のDynamoDBテーブルの値宛にメールを送信するコードになっています。
  • 環境変数で最初に検証したメールアドレスを渡しています。
  • コードはzip化して渡します。
$ export LAMBDA_SES_ROLE=$(aws iam get-role --role-name LambdaSESRole | jq -r  .'Role.Arn')
$ cat << EOF > index.js
var AWS = require('aws-sdk');
var ses = new AWS.SES({apiVersion: '2010-12-01'});

exports.handler = (event, context, callback) => {
  event.Records.forEach((record) => {
    var params = {
      Source: process.env.EMAIL_ADDRESS,
      Destination: {
        ToAddresses: [record.dynamodb.NewImage.Email.S]
      },
      Message: {
        Body: {
          Html: {
            Data: '<html><h1>Thank you!</h1><p>Wild Rydes is coming soon! Stay tuned for more info about unicorns near you!</p></html>'
          },
          Text: {
            Data: 'Wild Rydes is coming soon! Stay tuned for more info about unicorns near you!'
          }
        },
        Subject: {
          Data: 'Wild Rydes Limited Private Beta Confirmation'
        }
      }
    };

    ses.sendEmail(params, (err, data) => {
      if (err) context.fail(err);
      else     context.succeed(null);
    });
  });
};
EOF
$ export EMAIL_FUNCTION=email_function
$ zip -r ${EMAIL_FUNCTION}.zip index.js
$ aws lambda create-function --region us-east-1 --function-name ConfirmationEmail --role ${LAMBDA_SES_ROLE} --runtime nodejs4.3 --handler index.handler --zip-file fileb://${EMAIL_FUNCTION}.zip --environment Variables={EMAIL_ADDRESS=${EMAIL_ADDRESS}}

DynamoDBのトリガーを作成

  • Stream ARNを取得して使用します。
  • Lambdaコマンドからストリームをイベントソースとして設定します。
  • イベントソースにはAmazon KinesisストリームかAmazon DynamoDBストリームしか指定できません。
$ export STREAM_ARN=$(aws dynamodbstreams list-streams | jq -r '.Streams | map(select(.TableName == "Wildrydes_Emails"))' | jq -r '.[].StreamArn')
$ aws lambda create-event-source-mapping --event-source-arn ${STREAM_ARN} --function-name ConfirmationEmail  --enabled --batch-size 1 --starting-position LATEST

電子メールが送信されることを確認

  • 再度CloudFront経由でアクセスしてSIGN UPしましょう。
  • 手順の例では最初に検証したアドレスに+1の文字列を付与して、XXX+1@XXXXXX.XXX と入力してenterを押しています。
  • SIGN UPしたアドレス宛に、最初に検証したメールから送信されていたら完成です。

最後に

毎回思いますけどLambdaのデバッグが大変ですね。Lambda開発のベストプラクティスも調べて実践してみたいです。

残りもやっていきたいと思います。

Serverless Web Application Workshop をCLIでやってみた Lab 1: Static Website Hosting

サーバーレスアーキテクチャ Advent Calendar 2016 の10日目の記事です。Advent Calendar初参加になります。

先日、AWS re:Invent 2016 Recap に参加しました。
jawsug-yokohama.connpass.com

各スピーカーからAWS re:Invent 2016 の体験記を聞くことができました。今年は大量のサービスが出ていてキャッチアップが大変ですね。。

勉強会の中でAWS re:Invent 2016でサーバレスのワークショップが開催されてたことを知りました。
qiita.com

手順は英語ですがREADMEに詳細に書かれているので、読みながら簡単にできそうです。サーバレスならお金も安いので、個人アカウントで試せて安心ですね。
github.com

コンソールでの作業を、(できるだけ)CLIに置き換えてみたのでメモを載せていきます。
作業はMacで、リージョンはバージニアを想定して書いてます。

ワークショップは全部で4つあります。

  • Lab 1: Static Website Hosting
  • Lab 2: Beta Sign-up Mailing List
  • Lab 3: Administrative Interface
  • Lab 4: Product Update Blog

今回はLab 1: Static Website Hostingについて書いていきます。

やること

静的なウェブサイトをホストする為にS3 bucketを作成・設定。グローバル展開をする為にCloudFrontの設定・配信する。CloudFrontのURLからサイトが表示される事を確認。

Setup

  • AWSCLIやjqなど入ってなければインストールしておきましょう。
  • AWS configureでAccessKey, SecretAccessKeyは自分のもの、regionはus-east-1を指定しておきましょう。
git clone https://github.com/awslabs/aws-serverless-website-workshop.git
cd aws-serverless-website-workshop

バケット作成

  • バケットはユニークでなければダメなので、XXXXXXは読み替えて下さい。
$ export BUCKET_NAME=XXXXXX-wildrydes
$ aws s3 mb --region us-east-1 s3://${BUCKET_NAME}

・ポリシー追加

$ export PUBLIC_POLICY=public.json
$ cat << EOF > ${PUBLIC_POLICY}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::${BUCKET_NAME}/*"
    }
  ]
}
EOF
$ aws s3api put-bucket-policy --bucket ${BUCKET_NAME} --policy file://${PUBLIC_POLICY}

Static Website Hostingを有効にする

$ aws s3 website s3://${BUCKET_NAME} --index-document index.html

ワークショップ用に用意されたlab1のファイルをS3にsyncする

  • アプリコードは用意されているものを使います。

- 自分で作成したアプリコードがあれば、そちらをsyncするのも良いと思います。

  • Lab2も続きになるので用意されてるものを使いましょう。
$ aws s3 sync lab1/ s3://${BUCKET_NAME}

ブラウザで開く

  • SPAで動いているサービスを確認できると思います。
open http://${BUCKET_NAME}.s3-website-us-east-1.amazonaws.com

CloudFront作成

  • CloudFrontのCLIはまだプレビューになるので、まずは有効にしましょう。
$ aws configure set preview.cloudfront true
  • 次の設定変更に使用したいので、作成時に出力されるjsonをファイルに出力しておきます。
$ aws cloudfront create-distribution --origin-domain-name ${BUCKET_NAME}.s3-website-us-east-1.amazonaws.com > cloudfront.json

TTL変更

  • update用のjsonがうまく作れなかった。。
  • 作成時に出力されたjsonをうまく修正して、DefalutTTLを5に変更して、下のコマンドでアップデートできそうなのですが。。
$ aws cloudfront update-distribution --cli-input-json file://cloudfront.json
  • うまくいかないのでコンソールから手動で変更してコマンドは無視して下さい。

CloudFront経由で開く

  • StatusがDeployedになってから開いてください。2, 3分かかります。
  • 作成時のjsonからDomainNameを取り出して、ブラウザで開きます。
  • CloudFront経由で確認できたら完成です。
$ open https://$(cat cloudfront.json | jq -r '.Distribution.DomainName')

f:id:yamano3201:20161210080015p:plain

  • めんどいからやらないけど、S3に直接アクセスできる状態で終わりなの気持ち悪いな。。

最後に

ほとんどコピペでできるようになったのではないでしょうか。
あまりCLI触ったことない人は試してみてはどうでしょう。

残りも順番にやっていきたいと思います。

待ってました!Fire TV Stickを1250円オフの3730円で購入

待ってました!Fire TV Stickを1250円オフの3730円で購入しました!12/12までセールみたいです。
f:id:yamano3201:20161207224832j:plain

Amazon ファミリーに加入

前から欲しかったFire TV Stickを安く買えるということで、これを機にAmazon ファミリー(Amazon Prime)に加入しました。

Amazon ファミリーに加入すれば、年会費分のポイントがもらえるのでお得ですね。
Amazon.co.jp ヘルプ: Amazonファミリー特典の3,900円クーポンについて

購入

amazonのリンクから購入しました。

Fire TV Stick

Fire TV Stick

セットアップ

同梱の説明書とテレビ画面上の指示に従えば、簡単にセットアップ可能です。
リモコン操作もしやすいですね。
f:id:yamano3201:20161207224924j:plain

iOSアプリもインストールしておきました。

Amazon Fire TV Remote

Amazon Fire TV Remote

  • AMZN Mobile LLC
  • ユーティリティ
  • 無料

プライムビデオ視聴

さっそくプライムビデオ限定配信の松本人志のドキュメンタルというお笑い番組をみてみました。
Amazon CAPTCHA

限定配信の映像作品がみれるのも良いところですね。

最後に

PCをテレビにつないで見れば同じことはできていたのですが、やはり操作の簡単さが違いますね。

他にもFire TV Stick用のアプリでYoutubeの視聴やゲームなどもできるみたいですね。もう少し触ってみたいと思います。