Category: Serverless*


AWS サーバーレスアプリケーションのリポジトリの準備を整えてください

サーバーレスアプリケーションは、私が想像していたよりも早く主流になりました。毎日毎秒、数えきれないほどの AWS Lambda 関数が必要に応じて誕生し、重要なビジネス機能を処理して完了しています。ユーザーの皆様からは、このモデルの柔軟性、スケーラビリティ、コスト効率に優れた点において良い評価を頂いています。

当社は、AWS のすべてのお客様がサーバーレスな未来に向かって前進していただきたいと考えています。Lambda の発表後、当社はサーバーレスアプリケーションモデル (SAM) に従って、サーバーレスアプリケーションを AWS にデプロイおよび管理するプロセスをさらに簡略化しました。また、ウェブアプリモバイルバックエンドイメージ認識と処理リアルタイムのファイル処理IoTMapReduceリアルタイムのストリーム処理、およびチャットボットのイメージモデレーション用に、サーバーレスリファレンスアーキテクチャも公開しました。

今日は、次の一歩についてお話したいと思います。当社は、AWS のお客様によるサーバーレスアプリの発見とデプロイを可能な限り簡単にしたいと考えています。また、Lambda、SAM、サーバーレスアプリのオープンソースコミュニティを強化し、誰もが共有、参加して利点を得られる余地を作りたいと考えています。

AWS サーバーレスアプリケーションのレポジトリ
近日中に公開予定である AWS サーバーレスアプリケーションのレポジトリを少しだけご紹介します。サーバーレスアプリのプロデューサーとコンシューマー向けに設計されたこの AWS コンソールコンポーネントは、公開、検出、およびデプロイをサポートします。

プロデューサー (開発者、ISV、SaaS プロバイダ、AWS パートナー) は、レポジトリへの公開を簡単に行うことができます。アプリは SAM 形式である必要があり、SPDX ライセンス ID が付属し、グローバルな共有 (すべての AWS のお客様) またはプライベートな共有 (個人とチーム用のアクセスコントロール) のオプションがあります。ソースコードとその他のアプリケーションコンポーネントは、GitHub またはその他のソースコードレポジトリに保存し、参照により含めることができます。この場合も共有のコントロールが可能です。

お客様からの提出をお待ちしております。これは、他社 (Datadog、Here、Splunk、SignalFx) が作成中のレポジトリに加わります。

発行者向け
既に SAM を使用してサーバーレスアプリを構築している場合、提出の受け付け準備が間もなく整います。簡単に復習すると、SAM では、API アクションによってトリガーされ、S3 にアップロードされる Amazon API Gateway API、Amazon DynamoDB テーブル、および AWS Lambda 関数を定義できます。サーバーレスアプリは、Open Source Initiative (OSI) によって承認されたオープンソースライセンスに従って利用できる限り、サードパーティーライブラリを使用できます。リソースベースの IAM ポリシーを使用してアプリへのアクセスを制御できます。プライベートにするか、非常に選択的な基準に基づいてクロスアカウントアクセスを許可するか、一般公開できます。

コンシューマー向け
アプリは Lambda コンソールで見つけ、使用を開始できます。

また、各アプリのステータスを確認できます。

乞うご期待
この機能のすべては、AWS マネジメントコンソールAWS コマンドラインインターフェイス (CLI)、および API の豊富なセットからアクセス可能です。利用可能になり次第、詳細情報をお伝えします。

使用開始を希望される場合は、プレビューにサインアップしていただけます。

Jeff;

AWS Serverless Application Repository が登場します

私が想像していた以上に早くサーバレスアプリケーションはメインストリームになりました。毎日毎秒、数え切れないほどの AWS Lambda ファンクションが起動され、ビジネスクリティカルな処理を実行しています。ユーザの皆さんは その柔軟性、安定性、コスト効率の良さを好きだと言ってくれます。

私たちはすべてのAWSのお客様がサーバレスな未来へ向かえるようにしたいと考えています。AWS Lambdaのサービス提供開始後、サーバレスアプリケーションのデプロイおよび管理プロセスを簡素化するため Serverless Application Model (SAM) を提供しました。さらにサーバレスのリファレンスアーキテクチャを公開しました。現在、Web アプリケーションモバイルバックエンド画像認識&処理リアルタイムファイル処理IoTバックエンドMapReduceリアルタイムストリーミング処理、そしてチャットボット向けの画像加工 を公開しています。

2017年11月30日、私たちは次のステップをお伝えします。AWS コンソールからサーバレスアプリケーションを可能な限り容易に探し、見つけ、デプロイできるようにします。加えて Lambda、SAM、サーバレスアプリケーションに関するオープンソースコミュニティをサポートするため、誰もが共有し、参加し、メリットを得られる場を提供します。

(more…)

AWS AppSyncの紹介 – リアルタイムおよびオフライン機能を備えたデータ駆動型アプリケーションの構築

現在、モバイルデバイスや便利なアプリケーションは私達の生活にとって欠かせないものになっています。モバイルデバイスへの依存が高まるにつれ、私たちの注目を集めて何百万ものアプリケーションが爆発的に増加しています。これはモバイルデベロッパーにとって、高品質かつリアルタイムなユーザーが求めるアプリケーションを構築する必要があることを意味します。これにより、モバイルアプリケーションは、ユーザー間でのデータ同期、オフラインサポート、データディスカバリーなどの機能が実装されていることが必須になってきています。いくつかの記事、(InfoQDZone、モバイル開発ブログAlleviateTech)によると前述の機能を提供するうえで重要な要素の1つはクラウド型モバイルアプリケーションと言われています。 モバイルデータの同期やデータストレージなどに関しては特にこれが言えるようです。

このような背景から、クラウド上のデータ集約サービスを使って革新的なモバイルアプリケーションを開発するための新サービスを発表するのに最適なタイミングだと考え、AWS AppSync を紹介します。AWS AppSync は、フルマネージドなサーバーレスGraphQL サービスで、リアルタイムデータクエリ、同期、通信、およびオフラインプログラミングの機能を提供します。使い慣れていない人たちのために、GraphQL 仕様に関する情報を簡単に紹介しましょう。 (more…)

見逃していませんか? 最近公開された AWS サービスの概要

目を疑うほどの数のリリースやクラウドの最新技術が開発されています。今回のブログでは、この夏から秋の終わりまでにリリースされた優れたサービスや機能の近況報告の概要を紹介します。

今回ご紹介するサービスと機能:

  • RDS MySQL と Amazon Aurora で行うデータベースユーザー認証の AWS IAM
  • Amazon SES 評価ダッシュボード
  • Amazon SES オープンおよびクリックのトラッキングメトリクス
  • ソリューションビルダーチームによるサーバーレスイメージハンドラ
  • ソリューションビルダーチームによる AWS Ops Automator

では、詳しい内容を見てみましょう。

RDS MySQL と Amazon Aurora で行うデータベースユーザー認証の AWS IAM

AWS IAM を使用して、Amazon RDS データベースインスタンスやクラスターへのアクセスを管理したいと思ったことはありませんか?なんと、それを実現できるようになりました。Amazon RDS はユーザーが IAM を使用して MySQL や Amazon Aurora DB の Amazon RDS へのデータベースアクセスを管理できるようにする機能をリリースしました。

このサービス機能の良い所は、使用開始が実に簡単なことです。IAM を使用してデータベースユーザー認証を有効にするには、DB インスタンスまたはクラスターの作成、変更、復元を行う際に [Enable IAM DB Authentication] のチェックボックスをオンにします。RDS コンソール、AWS CLI および (または) Amazon RDS API を使用して IAM アクセスを有効にすることができます。

IAM 認証用のデータベース設定が完了すると、IAM セキュリティトークンサービスが生成した一時的なセキュリティ認証情報が提供され、クライアントアプリケーションがデータベースエンジンで認証します。データベースエンジンにパスワードを提供する代わりに、この認証情報を使用することができます。

IAM を使用してターゲットにした許可や認証を MySQL と Aurora に提供する場合の詳細情報については「Amazon RDS ユーザーガイド (Amazon RDS user guide)」をご覧ください。

Amazon SES 評価ダッシュボード

Amazon Simple Email Service のユーザーがメール送信でベストプラクティスガイドラインを利用するようにサポートするため、評価ダッシュボードをリリースしてメール送信の状態を包括的にまとめたレポートを提供するようになりました。送信したメールを積極的に管理するためのサポートを提供することで、ユーザーは送信メトリクス、コンプライアンスや実行のステータスを送信し、アカウント全体の状態の可視性を高めます。

評価ダッシュボードは次の情報を提供します。

  • Account status: アカウントの状態を示す説明です。
    • Healthy – 現在、アカウントに影響する問題はありません。
    • Probation – アカウントが停止猶予状態になっています。使用停止を避けるには停止猶予状態になっている理由を解決してください。
    • Pending end of probation decision – アカウントが停止猶予状態になっています。Amazon SES チームのメンバーはアクションを行う前にアカウントをレビューしてください。
    • Shutdown – アカウントが停止されました。Amazon SES を使用してメールを送信することはできません。
    • Probation – アカウントが停止猶予状態になっています。停止猶予状態になっている理由が解決されていません。
  • Bounce Rate: バウンスした送信済みメールの割合とバウンス率のステータスメッセージです。
  • Complaint Rate: 受信者がスパムとして報告した送信済みメールの割合と苦情率のステータスメッセージです。
  • Notifications: 別のアカウントの評価問題に関するメッセージです。

Amazon SES オープンおよびクリックのトラッキングメトリクス

Amazon SES に最近追加されたもう 1 つの優れた新機能はメールのオープンおよびクリックのトラッキングメトリクスです。メールのオープンおよびクリックのトラッキングメトリクス機能は、SES ユーザーが送信したメールがいつ開封されたか確認したり、メール内のリンクがいつクリックされたかをトラッキングすることを可能にします。この SES 機能を使うことで、メールキャンペーンのエンゲージメントや、その効率性を今まで以上にトラッキングできるようになります。

動作の仕組み

メール開封トラッキング機能を使用すると、SES はトラッキングの対象にするメールに透過的な小さなイメージを埋め込みます。そのメールが開封されると、メールアプリケーションクライアントは Amazon SES で、オープントラックイベントをトリガーするそのトラッキングを読み込みます。メールクリック (リンク) トラッキング では、メールや (または) メールテンプレートにあるリンクがカスタムリンクと置き換えられます。カスタムリンクがクリックされると、SES でクリックイベントが記録され、カスタムリンクはオリジナルメールのリンク先にメールユーザーをリダイレクトします。

新しい設定セットを作成したり、SES 内の既存の設定セットを変更することで、新しいオープントラッキングとクリックトラッキング機能を利用することができます。オープンおよびクリックメトリクスを取得するために Amazon SNSAmazon CloudWatch または Amazon Kinesis Firehose を AWS サービスとして選び、送信したいメールで新しい設定セットを選択すれば新機能を有効にできます。

AWS ソリューション: サーバーレスイメージハンドラと AWS Ops Automator

AWS ソリューションビルダーチームは、AWS でのアプリケーション構築や実行をサポートするため、アーキテクチャに関したよくある質問の回答を提供できるように努めています。ソリューションについては AWS Answers ページをご覧ください。秋の始めに AWS Answers で公開した新しい 2 つのソリューションはサーバーレスイメージハンドラAWS Ops Automator です。
サーバーレスイメージハンドラは、ユーザーが AWS Cloud で行うイメージ処理を動的に処理、操作、最適化することをサポートするソリューションを提供するために開発されました。このソリューションは、キャッシングに Amazon CloudFront を、そして AWS Lambda でイメージを動的に取得しイメージの変更を行い、Amazon S3 バケットでイメージを保存することを組み合わせています。さらに、サーバーレスイメージハンドラは、イメージ操作、処理、最適化を追加するオープンソースイメージ処理スイートの Thumbor を利用しています。

AWS Ops Automator ソリューションは、時間ベースまたはイベントベースのトリガーを使用して手動タスクを自動化しやすくします。たとえば、自動タスクのフレームワークを提供することでスナップショットスケジューリングを自動化します。また、タスクの追跡記録、ログ記録、リソースの選択、スケーリング、同時実行の処理、タスク完了の処理、API リクエストの再試行などもこれに含まれます。このソリューションには次の AWS サービスが含まれています。

  • AWS CloudFormation: タスク設定を生成するマイクロサービスやソリューションのコアフレームワークを起動するためのテンプレート
  • Amazon DynamoDB: イベントトリガー、リソースを定義するためのタスク設定データの保存とアクションとエラーの結果を保存するテーブル
  • Amazon CloudWatch Logs: 警告やエラーメッセージをトラックするログ記録を提供
  • Amazon SNS: ソリューションからのログ記録情報を受信するように登録済みのメールアドレスにメッセージを送信

さらに理解を深め、コーディングをお楽しみください。

Tara

AWS SAM Local(ベータ版) – サーバーレスアプリケーションをローカルに構築してテストする

今回、新ツール、SAM Local のベータ版がリリースされました。これにより、簡単にサーバーレスアプリケーションをローカルに構築してテストできるようになります。この記事では、SAM Local を使用し、クイックアプリケーションの構築、デバッグ、デプロイを実行します。これにより、エンドポイントに curl コマンドを使用してタブやスペースで投票できるようになります。AWS は サーバーレスアプリケーションモデル(SAM)を昨年導入しました。これにより、デベロッパーはサーバーレスアプリケーションをより簡単にデプロイできるようになっています。SAM の基本にまだなじみがない場合は、私の同僚である Orr が SAM の使用方法について書いた素晴らしい記事を参照してください。5 分ほどで読めます。基本的に、SAM は AWS CloudFormation 上に構築された強力なオープンソース仕様で、サーバーレスインフラストラクチャをコードとして簡単に保持できるようにすることを目的としています。また、可愛いマスコットもついてきます。

SAM Localでは、SAM の優れた点をすべてローカルマシンで利用できます。

  • 以下を使って、AWS Lambda 関数をローカルに開発してテストすることができます。 sam local Docker
  • Amazon Simple Storage Service(S3)Amazon DynamoDBAmazon KinesisAmazon Simple Notification Service(SNS)など、既知のイベントソースからの関数の呼び出しをシミュレートできます。
  • SAM テンプレートからローカルな Amazon API Gateway を開始し、ホットリロードで関数を素早く繰り返すことができます。
  • SAM テンプレートを素早く検証し、さらに、その検証を linters や IDE で統合できます。
  • Lambda 関数についてインタラクティブなデバッグサポートを利用できます。

SAM Local のインストール方法はいくつかありますが、NPM を使用するのが一番簡単です。 npm install -g aws-sam-local で素早く入手できます。また、ソースから直接インストールすれば確実に最新バージョンを入手できます。 go get github.com/awslabs/aws-sam-local (「sam」ではなく、「aws-sam-local」という名前でバイナリが作成されます)

それでは、簡単な SAM アプリケーションを書き込んでスペースやタブでの投票を行ってみましょう。非常にシンプルな、しかし強力なアーキテクチャ、API GatewayLambda 関数を使用し、結果を DynamoDB に保存します。最後は API に curl を実行できる必要があります。 curl https://SOMEURL/ -d '{"vote": "spaces"}' そして投票数を取得します。

以下に、シンプルな SAM template.yaml を示します。

AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  VotesTable:
    Type: "AWS::Serverless::SimpleTable"
  VoteSpacesTabs:
    Type: "AWS::Serverless::Function"
    Properties:
      Runtime: python3.6
      Handler: lambda_function.lambda_handler
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref VotesTable
      Events:
        Vote:
          Type: Api
          Properties:
            Path: /
            Method: post

Lambda 関数に公開する [dynamo_i] テーブルを作成します。環境変数の TABLE_NAME を使用します。

このテンプレートの有効性をテストするため、 sam validate を呼び出してタイプミスがないことを確認します。返ってくるのは、 「Valid」です。 Lambda 関数の作業に進みます。

import os
import os
import json
import boto3
votes_table = boto3.resource('dynamodb').Table(os.getenv('TABLE_NAME'))

def lambda_handler(event, context):
    print(event)
    if event['httpMethod'] == 'GET':
        resp = votes_table.scan()
        return {'body': json.dumps({item['id']: int(item['votes']) for item in resp['Items']})}
    elif event['httpMethod'] == 'POST':
        try:
            body = json.loads(event['body'])
        except:
            return {'statusCode': 400, 'body': 'malformed json input'}
        if 'vote' not in body:
            return {'statusCode': 400, 'body': 'missing vote in request body'}
        if body['vote'] not in ['spaces', 'tabs']:
            return {'statusCode': 400, 'body': 'vote value must be "spaces" or "tabs"'}

        resp = votes_table.update_item(
            Key={'id': body['vote']},
            UpdateExpression='ADD votes :incr',
            ExpressionAttributeValues={':incr': 1},
            ReturnValues='ALL_NEW'
        )
        return {'body': "{} now has {} votes".format(body['vote'], resp['Attributes']['votes'])}

これをローカルにテストします。通信のために実際に DynamoDB データベースを作成し、このデータベースに名前を設定する必要があります。環境変数の TABLE_NAME を使用します。これには env.json ファイルを使用します。コマンドラインでパスすることもできます。最初に以下を呼び出します。
$ echo '{"httpMethod": "POST", "body": "{\"vote\": \"spaces\"}"}' |\
TABLE_NAME="vote-spaces-tabs" sam local invoke "VoteSpacesTabs"

これで Lambda をテストします。スペースの投票数が返されるので、理論的にすべて問題なく機能していることがわかります。すべてをタイプするのは手間なので、 sam local generate-event api でサンプルイベントを作成してローカル呼び出しにパスします。API をローカルに実行するだけなので非常に簡単です。実際に sam local start-api でやってみましょう。これでローカルエンドポイントに curl を実行し、すべてをテストできるようになりました。
次のコマンドを実行します。 $ curl -d '{"vote": "tabs"}' http://127.0.0.1:3000/ 「tabs now has 12 votes」(タブの現在の投票数:12)と返ってきます。当然ながら、この関数は最初から完璧に書けたわけではありません。何度か編集と保存を繰り返しました。ホットリロードの利点の1つに、関数を変更しても新しい関数をテストするための追加作業が必要ないことが挙げられます。これにより、開発における反復作業が大幅に削減されます。

ネットワークを介して実際の DynamoDB データベースにアクセスすることを避けたい状況を考えてみましょう。どのような選択肢があるでしょうか?たとえば、DynamoDB Local をダウンロードして起動することができます。それには java -Djava.library.path= を使用します。/DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb 次に、Lambda 関数で AWS_SAM_LOCAL 環境変数を使用し、動作についての決定を行います。関数を少し変更してみましょう。

import os
import json
import boto3
if os.getenv("AWS_SAM_LOCAL"):
    votes_table = boto3.resource(
        'dynamodb',
        endpoint_url="http://docker.for.mac.localhost:8000/"
    ).Table("spaces-tabs-votes")
else:
    votes_table = boto3.resource('dynamodb').Table(os.getenv('TABLE_NAME'))

これでローカルエンドポイントがローカルデータベースに接続され、WiFi なしで簡単に作業できるようになります。

SAM Local はさらに、インタラクティブデバッグもサポートしています。Java や Node.js では、 -d フラグやポートをパスしてデバッガーをすぐに有効化できます。Python では、 import epdb; epdb.serve() などのライブラリを使用して接続できます。その後は、 sam local invoke -d 8080 "VoteSpacesTabs" を呼び出すことで、関数は実行を停止し、デバッガーの手順が完了するのを待機します。

これですべて機能するようになります。さっそくデプロイしましょう!

最初に sam package コマンドを呼び出します。これは aws cloudformation package のエイリアスです。このコマンドの結果を sam deploy に使用します。

$ sam package --template-file template.yaml --s3-bucket MYAWESOMEBUCKET --output-template-file package.yaml
Uploading to 144e47a4a08f8338faae894afe7563c3  90570 / 90570.0  (100.00%)
Successfully packaged artifacts and wrote output template to file package.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file package.yaml --stack-name 
$ sam deploy --template-file package.yaml --stack-name VoteForSpaces --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - VoteForSpaces

これで API に以下が出てきます。

これで本稼働ステージに移り、投票が多い場合にはレート制限を追加します。ローカルで作業してクラウドに簡単にデプロイすることもできます。1度目のデプロイで問題なく機能したときは本当にいい気分です。

これで、投票して結果をライブで見ることができます。http://spaces-or-tabs.s3-website-us-east-1.amazonaws.com/

SAM Local により、サーバーレスアプリケーションのテスト、デバッグ、デプロイが簡単になることを願っています。CONTRIBUTING.md ガイドを用意しています。是非プルリクエストを送信してください。構築が終わった際には是非ツイートでお知らせください。最新情報の記事やドキュメントはこちらで確認できます。

Randall

サーバレス JavaScript アプリケーションで SAML: Part I

このブログ記事は AWS の Richard Threlkeld, Gene Ting, Stefano Buliani によって AWS Compute Blog に投稿された「SAML for Your Serverless JavaScript Application: Part I」の翻訳記事です。

このブログ記事に掲載したコードや SAM テンプレートの全体は samljs-serverless-sample GitHub レポジトリにあります。手動でリソースを作成する事もできますが、GitHub レポジトリにある SAM テンプレートを使ってリソースを作成することを強くお勧めします。


SAML 認証連携を実現したくありませんか? AWS プラットフォームで使うことができる一時的なセキュリティ認証情報の発行を、短期間の SAML アサーションを交換で実現できます。

エンタープライズ Web アプリケーションを構築する時は、認証や認可が一貫して行われ業界のベストプラクティスに沿っている事が必須事項です。AWS では、ユーザに一意のIDを作成し、AWS のサービスにアクセスできる短期間の認証情報を使えるようにできる Amazon Cognito と呼ぶサービスを構築しました。これらの認証情報は、IAM ポリシーに基づくロールと関連付けて、異なるリソースへのアクセスを許可や拒否する事ができます。

この記事では、Amazon Cognito で SAML プロバイダと認証連携を行う異なる方式を紹介していきます。応用すると、異なるタイプの認証プロバイダ (IdP) と連携させることができます。Facebook、Twitterやその他のサードパーティのソーシャルメディアを IdP にする事もできます。Amazon Cognito のユーザプールと認証連携させ、独自のマネージドユーザディレクトリを作成することもできます。

例えば、ユーザが Active Directory Federation Services (ADFS) で認証する事ができる JavaScript アプリケーションを構築したいかもしれません。ユーザは AWS 認証情報で許可された範囲で API を呼び出して得た情報をアプリケーションに表示させたり、DynamoDB テーブルに書き込むことができます。AWS Mobileブログの記事「Announcing SAML Support for Amazon Cognito」では、新しい SAML 機能について Java、Android、iOS のサンプルコード付きで紹介しました。この記事では、ADFS フローのカスタマイズについて JavaScript のサンプルを交えて詳細に紹介します。

シナリオ

この記事では、クライアント側のフローを紹介します。SAML アサーションは Amazon API Gateway 経由で渡され、ブラウザ上のコードは Amazon Cognito Identity から直接認証情報を受け取ります。次回のブログ記事では、バックエンド側の処理を紹介します。SAML アサーションと認証情報は、AWS Lambda ファンクション内で処理でき、ビジネスロジックを実現するようカスタマイズしたり監査履歴を取ったりする事ができます。

このシナリオの全コードは SAM テンプレート含め、GitHub の samljs-serverless-sample レポジトリにあります。手動でリソースを作成する事もできますが、GitHub レポジトリにある SAM テンプレートを使ってリソースを作成することを強くお勧めします。

サーバレスのアーキテクチャとなっていますが、ADFS との連携は従来のコンピュート サービスである EC2 インスタンスのようなコンポーネントで置き換えることもできます。ADFS の用語や定義については「Claims-based identity term definitions」を参考にして下さい。

前提条件

このブログ記事では、ADFS が動作している環境が必要です。以下の事を実施して下さい。:

  1. AWS コンソールで ADFS との認証連携を設定。「Enabling Federation to AWS Using Windows Active Directory, ADFS, and SAML 2.0」を AWS CloudFormation テンプレートと共に参考にしてください。
  2. サインインページ(https://localhost/adfs/IdpInitiatedSignOn.aspx)からユーザ example\bob が ADFS-Dev と ADFS-Production の両方のグループとして認証出来ることを確認します。
  3. Amazon Cognito Identity のプールを作成します。

ADFS 設定の概要

チュートリアルを始める前に、幾つか AWS と SAML の設定を確認しましょう。まず、前提条件にある通り IAM ロールが作成されているかから確認して下さい。アプリケーション用に新しく IAM ロールと AD グループを作成してもかまいません。この記事では、「Enabling Federation to AWS Using Windows Active Directory, ADFS, and SAML 2.0」の記事の通り ADFS-Dev と ADFS-Production を利用します。

  1. IAM コンソールで、ロールを選択し ADFS-Ddev を選択し、信頼関係 (Trust Relationships) のタブを開き、以下のコードのようになっている事を確認します。:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::YOURACCOUNTNUMBER:saml-provider/ADFS"
          },
          "Action": "sts:AssumeRoleWithSAML",
          "Condition": {
            "StringEquals": {
              "SAML:aud": "https://signin.aws.amazon.com/saml"
            }
          }
        }
      ]
    }

このポリシーは “ADFS” という SAML IdP で認証されたユーザがロールを引き受ける事を許可しています。また、ポリシーには条件が含まれており、SAML アサーション内の AudienceRestriction が https://signin.aws.amazon.com/ である事となっています。SAML アサーションは ADFS から AWS に HTTP POST で SAMLResponse というヘッダとして送られて来ます。前提条件に記載されている設定が実施済みであれば、ADFS コンソールでは以下のように設定されており、利用者(Ralying Party)の URL として AWS メタデータ URL が指定されています。詳細については、「認証レスポンスの SAML アサーションを設定する」を確認して下さい。



認証後、ADFS は利用者のアプリケーションに自動的にリダイレクトします。

上記のスクリーンショットでは、認証後の SAMLResponse の値を見るために Chrome を利用しました。「トラブルシューティングのためにブラウザで SAML レスポンスを表示する方法」に記載されているとおり、他のブラウザでも同様のことを行えます。SAMLResponse を貼り付ければ、Audience、Roles や Destination などの値を見ることができる “SAML Decoder” がインターネット上にあります。パート 2 のブロク記事では、これをプログラムで行う方法を紹介します。

ADFS からサーバレス Web サイトにリダイレクトし、Amazon Cognito に繋げる

この1つ目のブログのシナリオの方が難しくありません。多くの組織での要件にベストな流れとなっています。ユーザは ADFS で認証して Amazon Cognito から AWS 認証情報を受け取り、アプリの中でアクションを行えます。このサンプルアプリケーションは:

  1. ADFS で認証するログイン メカニズムを変更して取り出すことで、SAMLResponse ヘッダを取り出します。ユーザが S3 上に配置されたウェブサイトを訪問した際に、自動的にこの仕組みが行われます。
  2. ADFS-Dev ロールの信頼ポリシーを変更し、Active Directory の AWS-gDev グループのメンバであれば Amazon Cognio から一時的な認証情報を受け取れるようにします。
  3. ユーザのロールを選択するコードをアプリケーションの中に組み込みます。このブログ記事では、ADFS-Dev ロールを選択します。

参考までに、AWS Console への認証連携の場合 #3 と同様の内容は、ADFS のウェブページ IdpInitiatedSignOn.aspx からリダイレクトされた後にラジオボタンでロールをクリックして選択する事で実現されます。より詳しい内容については、セキュリティブログの「Enabling Federation to AWS Using Windows Active Directory, ADFS, and SAML 2.0」をご覧下さい。もしユーザが 1 つの Active Directory グループのメンバだけであれば、SAMLResponse には複数のロールが含まれておらず、その場合は #3 は省略されます。構成は以下の図のとおりとなります。

チュートリアル: ADDFS からサーバーレス Web サイトにリダイレクトし、Amazon Cognito に繋げる

まず、サーバレス Web サイトをセットアップし、認証情報を取得するログインフローを開始させます。シングル Web アプリを配置するのには S3 を使用します。

S3 バケットの作成

  1. S3 のコンソールで、「バケットを作成」を選択して一意なバケット名を入力します。以下の例では “serverlessweb” としますが、皆様は何か他の名前として下さい。
  2. バケットを作成後、詳細設定のページで「プロパティ」を選び、「バケットポリシーの編集」をクリックします。
  3. 以下のポリシーを設定して下さい。YOURBUCKETNAMEGOESHERE は置き換えて下さい。このポリシーは、バケットに入っている HTML や JavaScript などのファイルを誰でも GET リクエストを行えるようにします。Web サイトにアクセスすると Web ブラウザは GET リクエストを発行し、このポリシーがリソースの読み込みをユーザに許可します。
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "PublicReadForGetBucketObjects",
              "Effect": "Allow",
              "Principal": "*",
              "Action": "s3:GetObject",
              "Resource": "arn:aws:s3:::YOURBUCKETNAMEGOESHERE/*"
          }
      ]
    }
  4. 「静的ウェブサイトホスティング」を選択し、「ウェブサイトのホスティングを有効にする」とします。フォームに「index.html」と「error.html」を入力します。

  5. 次に、HTML ファイルをバケットに追加して、https://YOURBUCKETNAME.s3-website-REGION.amazonaws.com をブラウザで開きページが見れるか確認します(YOURBUCKETNAME と REGION は読み替えて下さい。)。まずは以下の HTML をテンプレートとして使って下さい。
    <!DOCTYPE html>
    <html>
     <head>
      <title>
       Amazon Cognito SAML Example
      </title>
      <script src="aws-sdk.min.js">
      </script>
     </head>
     <body>
      <h1>
       Testing SAMLResponse
      </h1>
     </body>
    </html>
      
  6. JavaScript SDK から圧縮(Minify)されたバージョン aws-sdk.min.js をダウンロードして、HTML ファイルと同様にバケットに保存し、エラー無くロードできることを確認します。

(オプション) CloudFront ディストリビューションのセットアップ

次に進める前に、さらにもう1つセットアップしたいと思います。CloudFront ディストリビューションです。S3 静的 Web ホスティングに CloudFront やその他の CDN を使用することで、独自ドメイン名で SSL を使用することができるようになります。

API Gateway から HTTP サイトにリダイレクトする事もできるため強制ではありませんが、Web サイトや認証や認可のシステムはエンドツーエンドで HTTPS を使うべきです。以下がセットアップで行う内容です。

  1. CloudFront コンソールで、Web タイプのディストリビューションを作成します。
  2. 「Viewer Protocol Policy」には、「HTTPS Only」を選択します。
  3. 「Origin Domain Name」には S3 バケットを選択します。
  4. ベストプラクティス通り、「Restrict Bucket Access」を選択します。こうすることで、バケットが直接アクセスされることから守ることができます。これで CloudFront ディストリビューションのドメイン名で、サイトにアクセスできるようになると思います。

ログイン メカニズム

次に、ログイン メカニズムを構築します。

ウェブサイトではログインさせるために、ボタンを押させることも出来ますし、自動的に認証情報が有効かどうか確認してからログインのフローにリダイレクトをさせる事もできます。

この例では、2 つ目のアプローチを取ります。ユーザがページを訪れると JavaScript を使ってすぐに状態を確認し、初回の訪問であれば認証情報を入手するためにリダイレクトさせます。このページにはログインの流れの中で API Gateway から再度リダイレクトされても来るため、ログインの進捗に合わせ ADFS のログインページにリダイレクトさせるのと同様に、届いた SAMLResponse のデータをキャプチャする事も必要です。今回の例では、以下のような流れになります。:

function loginWorkflow(){
    var activelogin = sessionStorage.getItem('activelogin');
    if (activelogin=='inProgress'){                                   //ADFS login redirect from API Gateway
        var samlResponse = getParameterByName('SAMLResponse');
        sessionStorage.removeItem(‘activelogin’);
        if (samlResponse != null){
            getSamlCredentials(samlResponse.replace(/\s/g, ''));
        }
    }
    else if (activelogin === null) {                                 //First page visit. Redirect to ADFS login.
        var RPID = encodeURIComponent('urn:amazon:webservices');
        var result = 'https://localhost/adfs/ls/IdpInitiatedSignOn.aspx' + "?loginToRp=" + RPID;
        sessionStorage.setItem('activelogin', 'inProgress');
        window.location = result;
    }
    else {//Credentials exist, page refresh, etc.
        console.log('activelogin already exists in session and the value is ' + activelogin);
    }
}

上記では、ADFS IdP への呼び出しを始める時にセッション変数を設定し、SAMLResponse (getParameterByName() で取り出せる)と一緒にWeb サイトに戻って来た時には getSamlCredentials() 関数を呼び出します。

AWS が必要とする SAMLResponse 値は POST binding のみがサポートされていますが、S3 の静的ウェブサイトは、GET リクエストしか受け取ることができません。このため、JavaScript アプリケーションが ADFS からの SAMLResponse を受け取るために API Gateway を利用します。Lambda をプロキシとして利用し、SAMLResponse をクエリ文字列に入れて静的ウェブサイトにリダイレクトで戻ってこさせます。

Lambda 関数の設定

  1. Lambda のコンソールで、GitHub レポジトリにある /Scenario1/lambda/redirect/index.js を使って samlRedirect という名前の関数をランタイムは Node.js 4.3 で作成します。実行ロールにはログ保存のために CloudWatch Logs の権限だけが必要です。
  2. 基本的な実行ロールが既になければ、関数作成時に新しいロールを Lambda のコンソール上で作成する事ができます。
  3. LOG_LEVELREDIRECT_URL という名前の環境変数を作成し、LOG_LEVEL には info を REDIRECT_URL には S3 の静的ウェブサイトの URL(静的ウェブホスティングを有効にしている場合にはバケットのプロパティに表示されているエンドポイント、あるいは先程記載したオプションの CloudFront ディストリビューション設定をした場合はドメイン名)を設定します。

API Gateway 設定

  1. API Gateway のコンソールで、SAMLAuth あるいは何か似た名前を付けた API を作成します。
  2. リソース」 を選択し、「SAML」という名前の子リソースを作成します。
    lambdasamlone_7.png
  3. POST」メソッドを作成します。「統合タイプ」には「Lambda」を選択し、「samlRedirect」関数を指定します。「メソッドリクエスト」の「HTTP リクエストヘッダー」に「SAMLResponse」を設定します。
    lambdasamlone_8.png

先ほど作成した samlRedirect 関数では、クエリ文字列に SAMLResponse を付けた静的ウェブサイトの URL を location プロパティに設定します。リダイレクトが実行されるように、API Gateway が 302 ステータスコードを返すように設定します。

  1. メソッドレスポンス」でステータスコード 200 を削除し、302 を追加します。「レスポンスヘッダ」に「Location」を設定し、「レスポンス本文」には「コンテンツタイプ」に「application/json」、「モデル」に「Empty」と設定します。
    lambdasamlone_9.png
  2. 「統合レスポンス」で「メソッドレスポンス」のステータスが 200 のものを削除し、302 のものを追加します。レスポンスヘッダ「Location」の「マッピングの値」には「integration.response.body.location」を設定します。
    lambdasamlone_10.png
  3. Lambda 関数が SAMLResponse と RelayState を受け取れるように、「統合リクエスト」で「コンテンツタイプ」が 「application/x-www-form-urlencoded」の「本文マッピングテンプレート」を以下のように追加します。:

    {
    "SAMLResponse" :"$input.params('SAMLResponse')",
    "formparams" : $input.json('$')
    }
  4. 変更を保存します。
  5. /saml リソースで「アクション」から「CORS の有効化」を選択します。「CORS を有効にして既存の CORS ヘッダを置換」を行いします。

  6. アクション」から「API のデプロイ」を選択します。「ステージ」には「Prod」や似た名前を使用します。「ステージエディター」で、「SDK 生成」を選択します。「プラットフォーム」には「JavaScript」を選択し、「SDK の生成」を行い、どこかのフォルダに保存します。ADFS の設定に必要になるため、トップに表示されている「URL の呼び出し」をメモします。

ADFS リダイレクト設定

  1. ADFS のコンソールで、「利用信頼関係」にある Amazon Web Services のプロパティを開き、「利用者を自動的に更新する」の項目を無効(チェックしない)にします。
    lambdasamlone_11.png
  2. エンドポイント」のタブを開き、既にあるエンドポイントを編集します。「バインディング」は「POST」のままで、「URL」には API Gateway でデプロイした API の「URL の呼び出し」を入力します。URL の最後に 「/saml」を追加します。
    lambdasamlone_12.png
    これまで構築してきたことを復習します。:

    • Web ページはユーザが認証情報を持っていなければ、ADFS のログインページにリダイレクトします。
    • 認証に成功したら、ADFS は SAMLResponse を付けて Web ページにユーザを戻します(API Gateway 経由)。
    • SAMLResponse は元の Web ページにクエリ文字列の一部として渡されます。

    Amazon Cognito から認証情報を取得するには、JavaScript コードでこのクエリ文字列を取り出し getCredentialsForIdentity 呼び出しのパラメータの一部として渡す必要があります。

  3. Amazon Cognito の Federated Identities のコンソールで、前提条件でセットアップした認証プールを開きます。認証プールの ID を確認し、以下の JavaScript コードの先頭に利用するリージョン名と同様に記載します。
    const identityPool = 'YOURCOGNITOPOOLID';
    AWS.config.region = 'COGNITOREGION'; // Region
    
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: identityPool
    });
    
    var identityId = localStorage.getItem('cognitoid');
    if (identityId != null){
        console.log('Identity ID: ' + identityId);
        loginWorkflow();
    } else {
        console.log('Calling GetID');
        AWS.config.credentials.get(function(){
            console.log('Identity ID: ' + AWS.config.credentials.identityId);
            localStorage.setItem('cognitoid', AWS.config.credentials.identityId);
            identityId = localStorage.getItem('cognitoid');
            loginWorkflow();
        });
    }

このコードは、アプリケーションでユーザに Amazon Cognito で生成した一意の ID を付与する最初の部分です。その上で、クエリ文字列に SAMLResponse の値を入れて返させるために loginWorkflow() を呼び出します。

以下は Stack Overflow で紹介されているサンプルのユーティリティ関数で、クエリ文字列から特定の項目を取り出すためのものです。

function getParameterByName(name, url) {
    if (!url) {
      url = window.location.href;
    }
    name = name.replace(/[\[\]]/g, "\\$&amp;");
    var regex = new RegExp("[?&amp;]" + name + "(=([^&amp;#]*)|&amp;|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}

これで Web ページは ADFS から BASE64 エンコードされた SAMLResponse を取得しました。これを Amazon Cognito に渡せば AWS 認証情報を取得することが出来ます。Cognito の getSamlCredentials() 関数は以下のコードで、loginWorkflow() から呼び出されます。:

function getSamlCredentials(samlResponse) {
    var role = 'arn:aws:iam::ACCOUNTNUMBER:role/ADFS-Dev';
    var params = {
        IdentityId: identityId,
        CustomRoleArn: role,
        Logins: {
            'arn:aws:iam::ACCOUNTNUMBER:saml-provider/ADFS' : samlResponse,
        }
    };

    cognitoidentity.getCredentialsForIdentity(params, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            console.log('Credentials from Cognito: ');
            console.log(data.Credentials);
        }
    });
}

ARN にある ACCOUNTNUMBER は2つとも書き換える必要がある事に注意して下さい。今回は使用するロールがソースに直書きされています。もし、SAML クレームに複数のロールが入って返されないのであれば、このパラメータは省略することもできます。引き受けるロールを何かしらのロジックで選択するようにしたい場合もあると思います。このブログ記事のパート II ではクライアント側ではなくバックエンドでこれをできるようにする内容を含める予定です。

また、logins map にあるキーは IAM コンソールで作成した ADFS の IdP 登録の ARN で、値は samlResponse です。これもアカウント番号に書き換える必要があります。この情報により Amazon Cognito は SAMLResponse の値が信頼している対象の ADFS からのものであるか検証できます。

この時点でこのコードを試しても動作しません。Amazon Cognito の認証プールで、認証プロバイダとして SAML IdP を有効にする必要があります。

  1. Amazon Cognito の Federated Identities のコンソールで、プールを選択し、Authentication Providers までスクロールし、SAML を選択します。ADFS の IdP を示すチェックボックスを選択します。
  2. Save Changes をクリックします。
    lambdasamlone_13.png

次に、Amazon Cognito が有効な SAMLResponse アサーションを受け取った時に、ユーザがロールを引き受けられるように信頼ポリシーを変更します。Amazon Cognito は STSAssumeRoleWithWebIdentity API を呼び出してこれを実現します。

IAM のコンソールで、ADFS-Dev ロールの信頼ポリシーを以下のポリシーに編集します。(JavaScript コードのように適切な位置に Amazon Cognito のプール ID を挿入します。):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "YOURCOGNITOPOOLID"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}

これで Amazon Cognito の信頼ポリシーは設定できました。Web ページをテストして下さい。AWS サービスのリクエストへの署名に使える認証情報はコンソールログに (AccessKey, SecretKey, Token) の 3 つが含まれる形で “data” オブジェクトで出力されます。アプリケーションの共通のシナリオは、AWS_IAM 認証に設定された API Gateway のメソッド呼び出しを行うことです。認証情報は SDK のリクエストを使うことで渡す事ができます。上記の呼び出して指定したロールにその API を呼び出す権限があれば、メソッド呼び出しは成功します。

例えば、API Gateway で API を作成した場合、メソッドに AWS_IAM 認証を有効にできます。上記で指定されたロール(logins mapで指定)に、メソッド呼び出しの権限があることを確認して下さい。より詳しいことは、「API Gateway へのアクセスを IAM アクセス権限で制御する」をご覧下さい。API をデプロイした場合、SDK の生成を使ってそのステージの JavaScript SDK を生成してダウンロードできます。これからのメソッド呼び出しを Web ページに組み込む事ができます。より詳しいことは、「API Gateway で生成した JavaScript SDK を使用する」をご覧下さい。トピックの最後に、apigClientFactory.newClient コンストラクタにアクセスキーシークレットキーをどうやって渡すことができるか確認しましょう。

Amazon Cognito Identity は短期間だけ有効な認証情報(1 時間で無効になる)を利用するため、一時的なアクセスキー、シークレットキー、セッショントークンを、apigClientFactory.newClient コンストラクタに渡します。:

        var apigwClient = apigClientFactory.newClient({
        accessKey: data.Credentials.AccessKeyId,
        secretKey: data.Credentials.SecretKey,
        sessionToken: data.Credentials.SessionToken
    });

機能の動作確認ができる Web ページのコードは、GitHub レポジトリ内の /scenario1/website/index.html にあります。同じディレクトリにある configs.js ファイルを更新します。リージョン、Cognito Identity のプール ID、SAML IdP の ARN、ADFS-Dev ロールの ARN を変更します。SAM テンプレートを使って API Gateway に AWS_IAM 認証の MOCK エンドポイントを作成する事もでき、連携された認証情報が機能するか Web ページ上のテストボタンで確認する事ができます。

lambdasamlone_14.png

最後に

チュートリアルを通じて SAML 認証や Amazon Cognito を使った AWS 認証について深いレベルで理解する手助けになる事を願っています。まだ完了していなければ、少し時間をかけて頂き、GitHub レポジトリの samljs-serverless-sample にあるコードを実際に動かし確認して下さい。また感想についても教えてください。

このシナリオは最初のステップとして十分かもしれませんが、組織によってはより多くのことをする必要があるかもしれません。例えば、ロールの選択をユーザに任せたいやビジネスロジックに基づき独自の IAM 範囲を実装したい事もあるかと思います。このシリーズのパート 2 ではこれらをどのようにしたら実現できるかを見ていきたいと思います。

[訳注] このブログで紹介している方法では、ADFS におけるデフォルトの AWS の証明書利用者設定を変更します。そのため、同じ ADFS 環境で AWS のマネージメントコンソールへ認証連携してアクセスさせる事とは同時に実現できません。

原文: SAML for Your Serverless JavaScript Application: Part I (翻訳: SA 辻 義一)