Amazon Web Services ブログ

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 Auroraアップデート: クロスリージョン・クロスアカウントサポートの拡張、T2.Small DBインスタンス、リージョンの追加

Amazon Auroraの最近のアップデートを振り返ってみたいと思います。Amazon AuroraはMySQL互換のハイパフォーマンスなデータベースです(間もなくPostgreSQL互換のAuroraもリリース予定です)。Amazon Auroraの紹介は、【AWS発表】Amazon Auroraをご利用頂けるようになりました!や【AWS発表】Amazon Aurora – Amazon RDSに費用対効果の高いMySQL互換のデータベースが登場!!をご覧ください。

最近Auroraへ追加された機能は以下のとおりです

  • クロスリージョンスナップショットコピー
  • 暗号化されたデータベースのクロスリージョンレプリケーション
  • 暗号化されたスナップショットのアカウント間の共有
  • US West (Northern California)リージョンのサポート
  • T2.smallインスタンスサポート

 

クロスリージョンスナップショットコピー

Amazon Auroraのスナップショット(自動・手動取得に関わらず)リージョン間でコピー出来るようになりました。スナップショットを選択し、Snapshot ActionsからCopy Snapshotを選択します。その後、リージョンを選択後、新しいスナップショットの名前を入力します。

au_copy_snap

この操作の中で、暗号化済みスナップショットも選択可能です。詳細はドキュメントをご覧ください。

 

暗号化されたデータベースのクロスリージョンレプリケーション

Amazon Aurora DBを作成する際に暗号化オプションを設定出可能です。

au_enable_encr

数クリックで他のリージョンにリードレプリカを作成することが出来るようになりました。この機能を利用することで、マルチリージョン、ハイアベイラビリティなシステムが構築可能になりますし、ユーザに近い位置にデータを移動することも可能です。クロスリージョンリードレプリカを作成するには、既存のDBインスタンスを選択し、メニューからCreate Cross Region Read Replicaを選択するだけです。

au_ccrrr_menu

その後、Network & Securityからリージョンを選択し、Createをクリックします。

au_pick_dest_reg

レプリケーション先のリージョンには必ず2つ以上のアベイラビリティゾーンを含んだDB Subnet Groupが必要です。

このパワフルな新機能について詳細は、ドキュメントをご覧ください。

 

暗号化されたスナップショットのアカウント間の共有

Amazon Aurora DBインスタンスを作成する際に、定期的に自動でスナップショットを行う設定が可能です。この他にも、数クリックで任意のタイミングでスナップショットを作成することも可能です。

au_take_snapshot

DBインスタンスが暗号化されている場合はスナップショットも暗号化されます。

AWS間で暗号化されたスナップショットを共有出来るようになりました。この機能を使うためには、DBインスタンスはdefault RDS keyではないマスターキーで暗号化されている必要があります。まず、スナップショットを選択し、Snapshot ActionsメニューからShare Snapshotを選択します。

au_share_snap_menu

そして、共有先のAWS Account IDを入力し(それぞれのアカウント毎にAddをクリックします)、Saveを選択します。

au_share_snap

この他にも、スナップショットの暗号化で使用したキーも共有する必要があります。この機能の詳細はドキュメントをご覧ください。

 

US West (Northern California)リージョンのサポート

Amazon Aurora DBをUS West (Northern California) リージョンでご利用頂けるようになりました。Auroraをご利用頂けるリージョンのリストは以下の通りです。

  • US East (Northern Virginia)
  • US East (Ohio)
  • US West (Oregon)
  • US West (Northern California)
  • Canada (Central)
  • EU (Ireland)
  • EU (London)
  • Asia Pacific (Tokyo)
  • Asia Pacific (Sydney)
  • Asia Pacific (Seoul)
  • Asia Pacific (Mumbai)

それぞれのリージョンでの価格については、こちらをご覧ください。

 

T2.smallインスタンスサポート

t2.small DBインスタンスをご利用頂けるようになりました。

au_launch

これらの経済的なインスタンスは、開発環境とテスト環境、および負荷の少ないプロダクションワークロードに最適です。また、Amazon Auroraの経験を積むこともできます。これらのインスタンス(昨年11月にリリースしたt2.mediumを含む6つのインスタンスと同様)は、Auroraが利用できるすべてのAWSリージョンで利用可能です。

t2.small DBインスタンスのオンデマンド価格はUS East (Northern Virginia)リージョンでは、1時間あたり$0.041からご利用いただけ、3年のAll Upfrontリザーブドインスタンスをご利用頂くと、1時間あたり$0.018となります。さらに詳細な価格についてはAmazon Auroraの料金ページをご覧ください。

Jeff; (翻訳は星野が担当しました。原文はこちら)

新機能 – 作成時に EC2 インスタンスと EBS ボリュームにタグ付け

2010 年に、EC2 インスタンスでのリソースへのタグ付け およびその他の EC2 リソースが発表されました。その発表以来、リソースあたりのタグ付けできる数が 10 から 50 へ引き上げられ、また、リソースグループとタグエディタの導入により、タグはより役に立つものとなりました。お客様はタグを使用して、所有権の追跡、コスト計算の処理の向上、コンプライアンスプロトコルの導入、および IAM ポリシーからのアクセスとリソースの管理などを行っています。AWS のタグ付けモデルでは、リソース作成とリソースのタグ付けという別個の機能を提供しています。これは柔軟性が高く、多くのユーザーに役立ってきましたが、リソースがタグ付けされていない状態で存在すると、時間枠が小さくなります。2 つの異なる機能を使用すると、リソースの作成だけは成功してもタグ付けが失敗し、リソースがタグ付けされていない状態になってしまいます。以下の 4 つの新たな機能により、タグ付けをより柔軟で役に立つ仕方で行えます。作成時のタグ付け – EC2 インスタンスと EBS ボリュームのタグはリソースを作成する API 呼び出しの一部として指定できます。タグの使用の強制 – EC2 インスタンスまたは EBS ボリュームの特定のタグは強制的に使用するように IAM ポリシーを記述できます。リソースレベルのアクセス許可 – 皆様からのリクエストにより、 CreateTagsDeleteTags 機能では、IAM のリソースレベルのアクセス許可がサポートされるようになりました。ボリューム暗号化の強制 – 新しく作成された EBS ボリュームに対して、暗号化を強制的に使用するように IAM ポリシーを記述できます。作成時のタグ付け EC2 インスタンスと EBS ボリュームのタグはリソースを作成する API 呼び出しの一部として指定できるようになりました (呼び出しがインスタンスとボリュームの両方を作成する場合は、インスタンスと各ボリュームに異なるタグを指定できます)。リソースの作成とタグ付けは自動的に行われ、オペレーション (RunInstancesCreateVolume、および、リソースを作成するその他の機能) が成功するには、両方が成功する必要があります。インスタンスやボリュームを作成した後に実行するタグ付けのスクリプトを構築する必要はもうありません。EC2 インスタンスを起動するときにタグを指定する方法は以下のとおりです (インスタンスが起動するときに、CostCenter および SaveSnapshotFlag タグも、作成されるすべての EBS ボリュームに設定されます)。

詳細については、「タグの使用」を参照してください。リソースレベルのアクセス許可 CreateTagsDeleteTags では、多くのお客様のリクエストにより、IAM のリソースレベルのアクセス許可がサポートされるようになりました。これにより、既存のリソースのタグキーおよび値をさらに制御できます。また、RunInstancesCreateVolume では、リソースレベルのアクセス許可がさらにサポートされるようになりました。これにより、作成時にリソースにタグ付けできるユーザーおよびグループを制御できます。さらに詳しくは、「AWS CLI または AWS SDK で使用するサンプルポリシー」を参照してください。タグの使用の強制 – 特定のタグを強制的に使用するように IAM ポリシーを記述できます。たとえば、次のような名前が付けられたタグの削除をブロックするポリシーを記述できます: 所有者 または アカウント。または、特定の既存のリソースに新しいタグを作成するのを許可しない「拒否」ポリシーを記述できます。IAM ポリシーを使用して、 DepartmentCostCenter タグの使用を強制すると、より正確なコスト配分レポートを作成するのに役立ちます。より強力なコンプライアンスとセキュリティポリシーの実装のために、 DeleteTags へのアクセスを、リソースがユーザー名でタグ付けされていない場合に限り制限することもできます。タグの使用を強制する機能により、リソースへのアクセス、所有権、コスト配分を正確に制御できます。以下は、すべての新しく作成されたボリュームに対し、costcenter および stack タグ (それぞれ「115」および「prod」の値を持つ) の使用を要求するステートメントです。

"Statement": [
    {
      "Sid": "AllowCreateTaggedVolumes",
      "Effect": "Allow",
      "Action": "ec2:CreateVolume",
      "Resource": "arn:aws:ec2:us-east-1:123456789012:volume/*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/costcenter": "115",
          "aws:RequestTag/stack": "prod"
         },
         "ForAllValues:StringEquals": {
             "aws:TagKeys": ["costcenter","stack"]
         }
       }
     },
     {
       "Effect": "Allow",
       "Action": [
         "ec2:CreateTags"
       ],
       "Resource": "arn:aws:ec2:us-east-1:123456789012:volume/*",
       "Condition": {
         "StringEquals": {
             "ec2:CreateAction" : "CreateVolume"
        }
      }
    }
  ]

ボリューム暗号化の強制 新たにサポートされるようになった追加の IAM リソースレベルのアクセス許可を使用して ( RunInstancesCreateVolume)、作成された EBS ブートボリュームまたはデータボリュームに対して、暗号化を強制的に使用するように IAM ポリシーを記述できます。これを使用すると、規制要件に対応でき、エンタープライズセキュリティポリシーを実施し、必要な監査要件に従ってデータを保護できます。以下はサンプルステートメントで、 RunInstancesCreateVolume の IAM ポリシーに組み込み、EBS ボリュームの暗号化を強制できます。

"Statement": [
        {
            "Effect": "Deny",
            "Action": [
                       "ec2:RunInstances",
                       "ec2:CreateVolume"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:volume/*"
            ],
            "Condition": {
                "Bool": {
                    "ec2:Encrypted": "false"
                }
            }
        },

詳細について、また、サンプルポリシーを見るには、「AWS CLI または AWS SDK で使用するサンプルポリシー」および「Amazon EC2 の IAM ポリシー」を参照してください。今すぐ利用可能 ご覧の通り、リソース作成時のタグ付けと新しいリソースレベルのアクセス許可の組み合わせ、およびタグの操作関数により、EC2 リソースへのアクセスを追跡し制御できます。この新しい機能は、AWS GovCloud (US)China (Beijing) を除くすべてのリージョンで今すぐ利用できます。AWS Management ConsoleAWS Command Line Interface (CLI)AWS Tools for Windows PowerShell、または AWS API から、今すぐ使用を開始できます。いずれ、他の EC2 リソースタイプのサポートを追加することも計画しています。詳しくは今後お知らせします。

Jeff;

Amazon Connect – クラウド上のカスタマーサポートセンター

すべてのビジネスの成功にとって、カスタマーサービスは不可欠です。多くの組織は、音声ベースのカスタマーサービスを大規模に提供するために、コールセンターを運営しています。コールセンターは、最低でも着信通話を対応可能なエージェントにルーティングします。より高度なシステムでは、カスタマイズされた問い合わせツリーを作成する機能や、その他の統合音声応答 (IVR) システムなど、さらに高度なルーティングとやり取りがサポートされます。従来、IVR システムは設置が困難で、ライセンスが高価であり、キャパシティーベースの料金が一般的でした。

Amazon カスタマーサービス組織は、お客様に最高レベルのサービスを提供することを目指しています。これを大規模に行うため、当社組織は世界中に散在した 50 以上のグループと子会社センターに勤務する数万人のエージェントを雇用し、さまざまな言語を話すお客様をサポートしています。

Amazon Connect へようこそ
今日は Amazon Connect についてお話ししたいと思います。当社カスタマーサービスチームの多くで使用されているのと同じテクノロジー上に構築された Amazon Connect により、お客様はクラウドベースのサポートセンターを数分でセットアップできます。お客様は独自のサポートセンターを作成し、(IVR と同様の) 問い合わせフローを設計し、完全にウェブベースの最新のインターフェイスを使用してエージェントを配置します。Amazon Connect は IT チームや専門コンサルタントの支援を必要とせず、簡単に設定して、ビジネスの意思決定者が直接実行できます。デプロイするハードウェアはなく、エージェントごとのライセンスもありません。その代わり、顧客に費やした分数と、電話の時間に基づいて料金をお支払いいただきます。このスケーラブルな従量制モデルにより、電話問い合わせ件数が予測不能であるか、急激に増大する、またはその両方である状況において、Amazon Connect を使用できます。Amazon Connect は以下を含む多くの異なる AWS のサービスで使用できます。

Amazon S3Amazon Connect は S3 を使用して、通話 (音声) およびレポートの無制限の暗号化されたストレージを提供します。

AWS Lambda – これにより、顧客の問い合わせの一部としてサーバーレス方式でコードを実行できます。このコードは CRM またはデータベースからデータをプルし、そのデータを使用して独自のカスタマーエクスペリエンスを提供できます。

Amazon Lex – Alexa の背後にあるのと同じテクノロジーを利用した自然言語の会話型インターフェイスを、顧客からの問い合わせに使用できます。Amazon Connect のこの機能は現在プレビュー形式でリリースされていて、間もなく詳細がわかる予定です。

AWS Directory ServiceAmazon Connect は既存の Active Directory を参照するか、新規に作成できます。このディレクトリは、ユーザー (管理者、マネージャー、またはエージェント) の ID とアクセス権限を保存するために使用されます。

Amazon KinesisAmazon Connect は問い合わせトレースレコード (CTR) を Amazon Kinesis にストリーミングできます。ここから、Amazon S3 または Amazon Redshift にプッシュし、Amazon QuickSight またはその他のビジネス分析ツールを使用して分析できます。

Amazon CloudWatchAmazon Connect はリアルタイムのオペレーションメトリクスを Amazon CloudWatch に発行します。このメトリクスにより、1 秒あたりの着信通話数、キューに保持されている数などがわかります。このメトリクスを使用して、カスタマーセンターのパフォーマンスを監視し、適切な数のエージェントを配置していることを確認できます。

Amazon Connect の利点と特徴
Amazon Connect の主要な利点と特徴について見てみましょう。

Cloud-PoweredAmazon Connect は AWS の不可欠な部分であり、堅牢、スケーラブル、可用性に優れるよう設計されています。各サポートセンターインスタンスは複数の AWS アベイラビリティーゾーンで実行されます。シンプル – 既に説明したように、Amazon Connect はビジネスの意思決定者によって設定および実行されるよう設計されました。グラフィカルなコンソールにより、セットアッププロセス (グラフィカルな問い合わせフローの設計を含む) が簡単で効率的になります。

柔軟Amazon Connect で利用される Contact Flow Editor (CFE) には、やり取り、統合、管理フロー、分岐などのブロックが含まれています。問い合わせフローには、事前に録音された音声のプロンプト、生成された音声、Lex を利用したやり取り、既存のシステムやデータベースとの統合、エージェントとの会話、通話の転送などを組み合わせて含めることができます。

経済的Amazon Connect の従量制モデルにより、運用コストは実際の使用量に沿ったものに維持することができます。エージェント側では、Amazon Connect には高品質の音声をサポートするソフトフォンが含まれます。

Amazon Connect ツアー
カスタマーサポートセンターをセットアップしてみましょう。Amazon Connect コンソールで作業を開始します。[Get started] をクリックします。

既存のディレクトリを使用するか、新規のディレクトリを作成できます。ここでは、新規のディレクトリを作成します。サポートセンターの URL をセットアップして続行します。この URL により、サポートセンターのユーザーがサインインできます。

次に、自分を管理者として設定します。

サポートセンターは電話の着信、発信、またはその両方を行うことができます。発信は問い合わせフローの一部として、またはエージェントによって行うことができます。ここでは必要なことを指定します (直通番号、フリーダイヤル番号、またはその両方は後で選択します)。

次に、通話の録音とレポート用に S3 の場所 (バケットとプレフィックスを含む) を指定します。個別の AWS Key Management Service (KMS) 暗号化キーとともに、それぞれに別のバケットとプレフィックスを使用できます。

次に、選択内容を確認して [Create instance] をクリックします。

数秒後に、Amazon Connect インスタンスの準備が整い、[Get started] をクリックできます。

Amazon Connect で、前に入力した管理者認証情報を使用してログインし、[Let’s go] をクリックして続行します。

これで、フリーダイヤル番号または直通電話番号を選択して、最初の着信を受け付けるようセットアップできます。

最初の着信を受け付ける準備が整いました。

私の携帯電話から番号をダイヤルして、オプションについて説明します。「1」を押してエージェントと話す選択をすると、ソフトフォンは電話に出るよう求めます (私はエージェントの役割を果たします)。

これで Amazon Connect をセットアップし、着信を受け付けることができるため、ダッシュボードを操作してサポートセンターを設定できます。

コールセンターに関連付けられている電話番号を表示できます。

そして追加の番号 (最大 10 個の直通ダイヤルと 10 個のフリーダイヤル) を要求し、幅広い国の番号から選択できます。

画面の下部で、番号が呼び出されたときに有効にする問い合わせフローを選択できます。

ダッシュボードに戻ります。次のステップはオペレーションの時間の設定です。オペレーションの既存の時間のリストを表示したり、新しいリストを作成したりできます。

複数のオペレーション時間を持ち、それぞれをキューにアタッチするか、問い合わせフローから参照できます。これで、問い合わせ (着信通話) のエージェントへのルーティングをモデル化するキューを作成できます。キューは優先順位 (通常またはプレミアムサポートのさまざまなレベル) を表すか、さまざまなビジネススキルまたは言語レベルのエージェントを表すことができます。

また、プロンプトを作成する機能もあります。これらは、問い合わせフローから参照できる音声スニペットです。既存の WAV ファイルをアップロードするか、ブラウザ内から録音できます。

次に、新しい問い合わせフローを作成することも、既存の問い合わせフローを編集することもできます。問い合わせフローにより、問い合わせ後のカスタマーエクスペリエンスが定義されます。デフォルトでセットアップされるサンプルフローを示します。

メニューで目的のブロックを見つけ、キャンバスにドラッグして、フローに接続できます。

次に、ブロックのヘッダーをクリックしてセットアップします。プロンプトを使用するか、音声の静的テキストまたは動的テキストを選択できます (動的な音声は、おそらくデータベースのルックアップから生じた音声フローにアタッチされた値を参照します)。

最も強力で一般的なブロックの 1 つにより、問い合わせフロー中に Lambda 関数を呼び出すことができます。この関数はデータベースからデータをプルする、CRM に接続する、または必要なタイプのビジネスロジックを実装することができます。この関数は入力としてキーと値のペアとともに提供され、出力として同じものを返します。返された値はフローの実行と関連付けられます。

次のステップでは、1 つ以上のキューで構成され、優先順位が関連付けられたルーティングプロファイルを作成します。優先順位により、エージェントは適切な順序 (低い数値ほど優先順位が高くなる) で複数のキューに対応できます。優先順位と遅延を組み合わせて、ユーザーとサポートセンターのニーズに合ったルーティングルールをセットアップできます。

最終ステップでは、ユーザー (管理者、マネージャー、エージェントなど) を追加して権限を与えます。これはユーザーごとに行うか、複数のユーザーの定義を含む CSV ファイルをインポートして行うことができます。Hello World という名前のユーザーを追加する方法を次に示します。

また、エージェントの階層も作成できます (地域または部門のレポートに最適です)。Amazon Connect では、セキュリティプロファイルを使用して、各タイプのユーザーに割り当てられたアクセス権限を管理できます。

さらに、リアルタイムと履歴のオペレーションメトリクスにもアクセスできます。リアルタイムのメトリクスの一部を示します (保持時間と表示されるフィールドは必要に応じてカスタマイズできます)。

メトリクスは CloudWatch に発行され、そこでアラームの実行に使用できます。この短いツアーで、Amazon Connect についてほどほど十分な説明ができたことを願っています。お客様がこれをどのようにして使用してサポートセンターを更新し、顧客に提供できるサービスのレベルを向上させたかお聞かせいただければ幸いです。

おわかりのように、これはリッチで強力なサービスであり、カスタマイズと拡張の余地が十分にあります。お客様が独自に使用できる高度な機能や設定オプションが数多くあります。

今すぐ利用可能
Amazon Connect は、US East (Northern Virginia) リージョンで今すぐ利用可能で、サポートセンターをすぐに作成することができます。説明したように、料金は従量制です。お客様はサポートセンターごと、および有効な通話 (着信または発信) ごとに分単位で料金をお支払いいただきます。AWS 無料利用枠の一部として、90 分のサポートセンターの利用、2 つの電話番号 (直通およびフリーダイヤル)、直通番号への 30 分の着信通話、30 分の着信フリーダイヤル通話、30 分の発信通話を、すべて 1 か月ごとに、年間を通じて無料で利用できます。

Jeff;

追伸 – Amazon Connect Images アルバムで、私の LEGO ビルド全体をご覧ください。

Amazon Athena のパフォーマンスチューニング Tips トップ 10

Amazon Athena は、S3 に保存されたデータに対して標準 SQL で簡単に分析を行える、インタラクティブクエリサービスです。Athena はサーバーレスのためインフラ管理の必要がなく、また実行したクエリのぶんだけ料金を支払うかたちになります。Athena は簡単に使えます。Amazon S3 上のデータに対してスキーマを定義し、標準 SQL でクエリを投げるだけです。

このブログポストでは、クエリパフォーマンスを改善するための 10 個の Tips をご紹介します。Tips には、Amazon S3 に置かれたデータに関するものと、クエリチューニングに関するものがあります。Amazon Athena は Presto を実行エンジンとして使用しているため、ここでご紹介する Tips のうちのいくつかは、Amazon EMR 上で Presto を動かす際にも当てはまります。

このポストは、読者の方が Parquet, ORC, Text files, Avro, CSV, TSV, and JSON といった、さまざまなファイルフォーマットについての知識を持っていることを前提としています。

ベストプラクティス: ストレージ

このセクションでは Athena を最大限に活用するために、どのようなデータ構造にするべきかについて議論します。ここで議論する内容は、Amazon EMR 上の Spark, Presto, Hive で Amazon S3 のデータを処理する場合にも、同様に当てはまります。

1. データをパーティションに分ける

パーティショニングとは、テーブルをいくつかに分割し、日付や国、地域といったカラムの値単位でまとめることをさします。パーティションは仮想カラムとして動作します。パーティションをテーブルの作成時に定義することで、クエリでスキャンするデータ量を減らすことができ、その結果パフォーマンスが向上します。パーティションに基づいてフィルタを指定することで、クエリで読み込むデータ量を制限することができます。より詳細については、Partitioning Data を参照してください。

Athena では Hive のパーティショニングをサポートしており、以下のいずれかの記法を使用します。

  1. カラム名のあとに = 記号をつけ、そのあとに値を記述する
    s3://yourBucket/pathToTable/<PARTITION_COLUMN_NAME>=<VALUE>/<PARTITION_COLUMN_NAME>=<VALUE>/

    データセットがこの形でパーティションわけされている場合には、テーブルにパーティションを一括で認識させるために、MSCK REPAIR TABLE を実行します

  2. もしデータの “Path” が上記のフォーマットでない場合には、個々のパーティションに対して、ALTER TABLE ADD PARTITION コマンドを実行することで、パーティションを認識させることができます
    s3://yourBucket/pathToTable/YYYY/MM/DD/
    Alter Table <tablename> add Partition (PARTITION_COLUMN_NAME = <VALUE>, PARTITION_COLUMN2_NAME = <VALUE>) LOCATION ‘s3://yourBucket/pathToTable/YYYY/MM/DD/’;

    注意: このやり方を用いることで、S3 上のどの場所にあるオブジェクトに対してでも、パーティションを認識させることができます

以下の例は、S3 バケットに置かれたフライトテーブルが、year でパーティションわけされているものになります。

$ aws s3 ls s3://athena-examples/flight/parquet/
PRE year=1987/
PRE year=1988/
PRE year=1989/
PRE year=1990/
PRE year=1991/
PRE year=1992/
PRE year=1993/

year カラムに対して ‘WHERE’ 句を用いることで、読み込むデータ量を制限できます。

SELECT dest, origin FROM flights WHERE year = 1991

パーティションキーには、複数のカラムを指定することができます。同様に、そのカラムが特定の値のものだけをスキャンすることができます。

s3://athena-examples/flight/parquet/year=1991/month=1/day=1/
s3://athena-examples/flight/parquet/year=1991/month=1/day=2/

パーティション対象のカラムを決める際には、以下の点を考慮してください:

  • フィルタとして使われるカラムは、パーティションの有力候補になります
  • パーティショニング自体にコストがかかります。テーブル内のパーティション数が増えるにつれ、パーティションのメタデータを取得して処理するためのオーバーヘッドが大きくなり、かつ 1 パーティションあたりのデータサイズは小さくなります。過剰に細かくパーティショニングすると、パフォーマンス上の利点が失われます
  • データが特定パーティションに偏っており、かつ多くのクエリがその値を使う場合には、同様にパフォーマンス上の利点が失われます

例:

以下のテーブルでは、パーティション分けされたテーブルと、そうでないテーブルのクエリ実行時間を比較しています。両テーブルには、無圧縮のテキストフォーマットデータが 74GB 含まれています。パーティション分けされたテーブルは、l_shipdate カラムによって 2526 個のパーティションに分けられています。

クエリ パーティション分けされていないテーブル コスト パーティション分けされたテーブル コスト 削減度合い
実行時間 スキャンされたデータ量 実行時間 スキャンされたデータ量
SELECT count(*) FROM lineitem WHERE l_shipdate = '1996-09-01' 9.71 秒 74.1 GB $0.36 2.16 秒 29.06 MB $0.0001

99% 価格削減

77% 速度向上

SELECT count(*) FROM lineitem WHERE l_shipdate >= '1996-09-01' AND l_shipdate < '1996-10-01' 10.41 秒 74.1 GB $0.36 2.73 秒 871.39 MB $0.004 98% 価格削減
73% 速度向上

ただし以下に示すように、パーティショニングにはペナルティもあります。過剰にパーティション分けしないように気をつけてください。

クエリ パーティション分けされていないテーブル コスト パーティション分けされたテーブル コスト 削減度合い
実行時間 スキャンされたデータ量 実行時間 スキャンされたデータ量
SELECT count(*) FROM lineitem; 8.4 秒 74.1 GB $0.36 10.65 秒 74.1 GB $0.36 27% 速度低下

2. ファイルを圧縮・分割する

各ファイルが適切なサイズ(詳しくは次のセクションを参照)であるか、ファイルが分割可能であれば、データの圧縮によってクエリの実行速度は著しく向上します。データサイズが小さいほど、S3 から Athena へのネットワークトラフィックが軽減されます。

分割可能なファイルの場合には並列実行性を増すために、Athena の実行エンジンがファイルを分割して、複数のリーダーで処理します。単一の分割不可能なファイルを扱う場合には、単一リーダーのみがファイルを読み込むことができ、そのほかのリーダーは待機状態のままです。すべての圧縮アルゴリズムが分割可能なわけではありません。一般的な圧縮フォーマットとその属性について、以下のテーブルにまとめました。

アルゴリズム 分割可能か否か 圧縮の度合い 圧縮 + 解凍速度
Gzip (DEFLATE) いいえ 高い 普通
bzip2 はい 非常に高い 遅い
LZO いいえ 低い 速い
Snappy いいえ 低い とても速い

一般的に、アルゴリズムの圧縮率が高くなるほど、圧縮および解凍に必要な CPU リソースが増えます。

Athena の場合は、デフォルトでデータ圧縮が行われ、かつ分割可能な Apache Parquet や Apache ORC といったファイルフォーマットの利用をおすすめします(訳注: ここでは、ファイルフォーマットと圧縮フォーマットが混ざっている点に注意してください。Parquet や ORC はファイルフォーマットであり、圧縮フォーマットではありません。ですが、Parquet や ORC はデフォルトのエンコーディング法の中に、辞書エンコーディングという簡単な圧縮処理が含まれています。ここの記述は、そのことを表しています。また Tips の 4 番目で述べているように、Parquet/ORC に対して、さらに Snappy のような圧縮アルゴリズムを指定することが可能です)。もしそれらを利用できない場合には、適切なサイズに分割した BZip2 や Gzip を試してください。

3. ファイルサイズを最適化する

データ読み込みが並列で行われ、データブロックがシーケンシャルに読み込まれる場合に、クエリが効率的に実行されます。分割可能なファイルフォーマットであるようにしておくことで、ファイルの大きさに関わらず並列処理が行われます。

ただしファイルサイズが非常に小さい場合、特に 128MB 未満の場合には、実行エンジンは S3ファイルのオープン、ディレクトリのリスト表示、オブジェクトメタデータの取得、データ転送のセットアップ、ファイルヘッダーの読み込み、圧縮ディレクトリの読み込み、といった処理に余分な時間がかかります。その一方で、ファイルが分割不可能でサイズが非常に大きいときには、単一のリーダーがファイル全体の読み込みを完了するまで、クエリ自体の処理は行われません。この場合、並列性が下がってしまいます。

細切れファイル問題に対する解決法のひとつとして、EMR の S3DistCP ユーティリティがあります。これを使うことで、小さなファイル群を大きなオブジェクトへとまとめることができます。S3DistCP は、大量のデータを最適なやり方で HDFS から S3、S3 からS3 、S3 から HDFS へと移動させる際にも利用できます。

大きなファイルにまとめるのは、複数の利点があります:

  • 高速な一覧表示
  • S3 へのリクエスト数の削減
  • 管理するメタデータの削減

:

以下では、単一の大きなファイルのテーブルと、5000 個の小さなファイルのテーブルとで、クエリ実行時間を比較しています。データはテキストフォーマットで、サイズは 7GB です。

クエリ ファイル数 実行時間
SELECT count(*) FROM lineitem 5000 files 8.4 秒
SELECT count(*) FROM lineitem 1 file 2.31 秒
実行速度 72% 向上

4. 列指向データの作成を最適化する

Apache Parquet と Apache ORC はポピュラーな列指向データフォーマットです。両者には列方向圧縮、さまざまなエンコーディング、データ型に合わせた圧縮、プレディケイトプッシュダウン(訳注: プレディケイトプッシュダウンとは、WHERE 句や GROUP BY 句などの処理を効率的に行うための手法です。例えば GROUP BY に対するプレディケイトプッシュダウンでは、各リーダーで読み込んだデータについて、全データで GROUP BY を行う前に、各ワーカー内であらかじめ GROUP BY をしておき、その結果を集約ワーカーに転送する、といったプロセスをとります。各ワーカーで先に集約を行うことでデータの転送コストが下がり、結果的にパフォーマンスが向上します。このように、クエリの実行パイプラインの最後で行う処理を、効率化のためにあらかじめ各プロセスでおこなっておく(= プッシュダウン)のが、プレディケイトプッシュダウンの役割となります)といった、データを効率的に持つための機能があります。両者はともに分割可能です。一般的に、高い圧縮率やデータブロックのスキップによって、S3 から読み込むデータが減り、その結果よりよいクエリパフォーマンスが得られます。

チューニング可能なパラメーターのひとつとして、ブロックサイズまたはストライプのサイズがあります。Parquet におけるブロックサイズ、 ORC におけるストライプサイズというのは、バイトサイズ単位で表されるもので、単一ブロックで保持できる最大行数を意味します。ブロックまたはストライプのサイズが大きいほど、単一ブロックで格納できる行数も多くなります。デフォルトでは Parquet のブロックサイズは 128MB で、ORC のストライプサイズは 64MB になります。テーブル内に大量のカラムがある場合は、各カラムのブロック単位で効率的にシーケンシャル I/O を行えるように、より大きなブロックサイズにすることをおすすめします。

そのほかのパラメーターとして、データブロックの圧縮アルゴリズムが挙げられます。Parquet のデフォルト圧縮フォーマットは Snappy ですが、それ以外に圧縮なし、 GZIP、そして LZO も使用可能です。ORC のデフォルトは ZLIB ですが、それ以外に圧縮なしと Snappy が利用可能です。デフォルトの圧縮アルゴリズムからはじめて、10GB 以上のデータサイズになった場合には、それ以外の圧縮アルゴリズムを試してみることをおすすめします。

Parquet/ORC ファイルフォーマットは、ともにプレディケイトプッシュダウン(プレディケイトフィルタリングとも呼ばれます)をサポートしています。Parquet/ORC はともに、ブロック内にカラムの値を保持するだけでなく、最大値/最小値のようなブロックごとの統計データも持っています。クエリが実行される際に、統計情報によって当該ブロックを読み込む必要があるか、スキップしてよいかを判断します。スキップするブロック数を最適化するための一つの方法として、Parquet や ORC で書き出す前に、よくフィルタされるカラムでデータをソートしておくやり方があります。これによって、各ブロックにおける最小値と最大値の差分が、全体としてもっとも小さくなることが保証されます。これによって、フィルタ効率を向上させることができます。

Amazon EMR 上で Spark や Hive を実行することで、既存のデータを Parquet や ORC に変換できます。 詳細については、S3のデータをAmazon Athenaを使って分析する のブログポストを参照してください。また以下のリソースもあります:

ベストプラクティス: クエリ

Athena ではクエリの実行エンジンとして Presto を使用しています。クエリ実行時に Presto がどのように動いているか理解することで、クエリの最適化方法について把握することができます。

5. ORDER BY を最適化する

ORDER BY 句はクエリの実行結果をソートして返します。ソートを実行するために、Presto はデータのすべてのレコードを単一のワーカーに送り、それからソートを実行します。この処理は Presto のメモリを大量に消費するため、クエリの実行時間が非常に長くなります。最悪の場合には、クエリが失敗します。

トップ N の値をみるために ORDER BY 句を使用する場合には、単一ワーカーでソートを実行するのではなく、LIMIT 句によって各ワーカーにソートとリミットの処理をプッシュし、ソートにかかるコストを大きく削減してください。

:

データセット: 7.25GB、無圧縮、テキストフォーマット、6000万行

クエリ 実行時間
SELECT * FROM lineitem ORDER BY l_shipdate 528 秒
SELECT * FROM lineitem ORDER BY l_shipdate LIMIT 10000 11.15 秒
速度 98% 向上

6. JOIN を最適化する

2 つのテーブルを結合する際には、両者のうち大きなほうを左側に、小さなほうを右側に指定してください。Presto は JOIN 句の右側で指定されたテーブルを各ワーカーノードに転送して、左側のテーブルを順になめていくことで結合を行います。右側のテーブルを小さくすることで、メモリ消費量を少なく、クエリを高速に実行することができます。

:

データセット: 74GB、無圧縮、テキストフォーマット、6億200万行

クエリ 実行時間
SELECT count(*) FROM lineitem, part WHERE lineitem.l_partkey = part.p_partkey 22.81 秒
SELECT count(*) FROM part, lineitem WHERE lineitem.l_partkey = part.p_partkey 10.71 秒
価格削減 / 速度向上 53% 速度向上

例外として、複数のテーブルをまとめて結合する場合と、クロス結合が行われる場合があります。Presto は結合の実行順序の最適化をサポートしていないため、が左側から右側に対して結合処理が行われます。そのためテーブルを左側から大きい順に並べることにより、結合条件に合わせたテーブルの並びにならない場合、クロス結合が実行されてしまいます(訳注: 以下の例の上側のクエリの場合、まず lineitem と customer とで結合処理が行われます。しかし結合条件にあるのは lineitem と orders、ccustomer と orders のため、lineitem と customer の間ではクロス結合が行われてしまいます。その結果得られた巨大なテーブルと orders の間で,次の結合処理が行われます。クロス結合は非常にコストの高い処理のため、この場合は 30 分以内にクエリが完了せず、タイムアウトしてしまっています)。

:

データセット: 9.1GB、無圧縮、テキストフォーマット、7600万行

クエリ 実行時間
SELECT count(*) FROM lineitem, customer, orders WHERE lineitem.l_orderkey = orders.o_orderkey AND customer.c_custkey = orders.o_custkey Timed Out
SELECT count(*) FROM lineitem, orders, customer WHERE lineitem.l_orderkey = orders.o_orderkey AND customer.c_custkey = orders.o_custkey 3.71 seconds

7. GROUP BY を最適化する

GROUP BY 演算子は、指定されたカラムの値に応じてレコードを各ワーカーノードに分散し、各ノードはメモリ内に対象の値を保持します。レコードが追加されると、メモリ内の GROUP BY 対象のカラムを比較します。一致した場合には、対象となる値を集約します。

クエリ内で GROUP BY を使う際には、カーディナリティ(訳注: カラム内のユニークな値の個数)が高い順にカラムを並べてください(これはユニークな値の数が多いほど、データが各ワーカーに均等に分散するためです)。

SELECT state, gender, count(*) 
           FROM census 
GROUP BY state, gender;

もうひとつの最適化方法は、可能ならば GROUP BY の対象を文字列でなく数字にすることです。数字は文字列に比べて必要とするメモリが少ないため、高速に処理することができます。

またその他の方法として、SELECT の中で扱うカラム数を制限することによって、レコードをメモリに確保したり、GROUP BY で集約する際に必要とするメモリ総量を減らすやり方があります。

8. LIKE 演算子を最適化する

文字列のカラムに対して、複数の値でフィルタリングする際には、一般的に LIKE よりも RegEx を使う方が望ましいです。LIKE を使う回数が多いほど、また文字列カラムのサイズが大きいほど、RegEx の効果も大きくなります。

:

データセット: 74GB、無圧縮、テキストフォーマット、6億行

クエリ 実行時間
SELECT count(*) FROM lineitem WHERE l_comment LIKE '%wake%' OR l_comment LIKE '%regular%' OR l_comment LIKE '%express%' OR l_comment LIKE '%sleep%' OR l_comment LIKE '%hello% 20.56 秒
SELECT count(*) FROM lineitem WHERE regexp_like(l_comment, 'wake|regular|express|sleep|hello') 15.87 秒
速度向上 17% 向上

9. 近似関数を使う

大規模なデータセットを処理する際の典型的なユースケースとして、COUNT(DISTINCT column) を使って、特定のカラムのユニークな値ごとのレコード数を求めるというものがあります。例として挙げられるのは、ウェブサイトを訪れたユニークユーザーを求めるというものです。

もし正確な値が必要ない場合、例えばサイト内のどのウェブページを突っ込んで調べるべきか判断するといったケースでは、approx_distinct() の使用を検討してみてください。この関数は、全文字列を捜査するかわりに、ユニークなハッシュの数をカウントすることで、メモリ使用量を最小限におさえます。この手法の欠点は、得られた値に 2.3% の標準誤差を持つことです。

:

データセット: 74GB、無圧縮、テキストフォーマット、6億行

クエリ 実行時間
SELECT count(distinct l_comment) FROM lineitem; 13.21 秒
SELECT approx_distinct(l_comment) FROM lineitem; 10.95 秒
速度向上 17% 向上

詳しくは Presto ドキュメントの Aggregate Functions を参照してください。

10. 必要なカラムだけを読み込む

クエリを実行する際に、すべてのカラムを使用するかわりに、最後の SELECT 句で必要なカラムだけに絞ってください。処理対象のカラム数を減らすことで、クエリの実行パイプライン全体で処理しなければいけないデータ総量を削減できます。これは特に、大量のカラムがあるテーブルや、文字列ベースのカラムが主体のテーブルにクエリを投げるときに有効です。

:

データセット: 7.25GB、無圧縮、テキストフォーマット、6000万行

クエリ 実行時間
SELECT * FROM lineitem, orders, customer WHERE lineitem.l_orderkey = orders.o_orderkey AND customer.c_custkey = orders.o_custkey; 983 秒
SELECT customer.c_name, lineitem.l_quantity, orders.o_totalprice FROM lineitem, orders, customer WHERE lineitem.l_orderkey = orders.o_orderkey AND customer.c_custkey = orders.o_custkey; 6.78 秒
価格削減 / 速度向上 145 倍速度向上

結論

このポストでは、Amazon Athena および Presto エンジンにおけるインタラクティブ分析を最適化するための、ベストプラクティスについて述べました。これらは Amazon EMR 上で Presto を動かす際にも、同様に適用可能です。

原文: Top 10 Performance Tuning Tips for Amazon Athena (翻訳: SA志村)

NICE EnginFrame – AWS のユーザーフレンドリーな HPC

去年、AWS が NICE 買収の契約に署名したこと、そして両社が協力し合い高パフォーマンスと科学計算において今まで以上に優れたツールとサービスを開発していく予定であることをブログでお知らせしました。そして本日、NICE EnginFrame 2017 をリリースするに至りました。この製品は AWS Cloud のパワー、スケール、柔軟性を活用する技術的および科学的なアプリケーションのセットアップと実行のプロセスをシンプルにするように設計されています。1 時間以内に、完全に機能する HPC クラスターをセットアップし、シンプルなウェブベースのユーザーインターフェイスを介してアクセスすることができます。すでに EnginFrame を使用している場合は、引き続きオンプレミスで実行したりクラウドに移動することができます。

AWS Inside
クラスター (1 つ以上のクラスターを起動することも可能) は Virtual Private Cloud (VPC) 内にあり、複数の AWS サービスや機能を使用して構築されています。そうした機能とは Amazon Linux AMI、共有 Amazon Elastic File System、NFS スタイルのファイルストレージ、ユーザー認証の AWS Directory Service、トラフィック管理の Application Load Balancers などを実行している Amazon Elastic Compute Cloud (EC2) インスタンスなどです。このようなマネージド型サービスはワークロードや作業に集中しやすくすることができます。システムソフトウェアのアップグレード、パッチ、処理やストレージのスケーリング、そして自分でクラスターを構築した場合に伴うその他の責任などを心配する必要がありません。EnginFrame は AWS CloudFormation テンプレートから起動します。パラメーター化し自己完結型のテンプレートは、起動する各クラスターが同じ様に設定されることを確実にします。テンプレートを実行すると 2 つの異なる CloudFormation スタック (AWS リソースの集合) が作成されます。

Main Stack – このスタックは自分のクラスターが共有している EFS ベースのストレージと、デフォルトのクラスタースタックへの受信リクエストをルートするアプリケーションロードバランサーをホストします。このスタックは IAM ロールや SSL 証明書のセットアップや管理を担う一連の AWS Lambda 関数のホストでもあります。

Default Cluster Stack – このスタックはメインスタックが管理し、手間の掛かるタスクを処理する場所になっています。このクラスターは CfnCluster によりサポートされています。不要になったコンピューティングノードを終了することで必要に応じてスケールアップやスケールダウンを行うことができます。EnginFrame も実行します。

EnginFrame ポータル
クラスターを起動すると、ウェブベースの EnginFrame ポータルを使用して連係動作します。このポータルはアプリケーション (バッチとインタラクティブの両方) とデータ、ジョブへのアクセスを許可します。ご自分 (もしくはクラスターの管理者) は、バッチアプリケーションや特定のファイルタイプに関連付けられているアクションのテンプレートを作成することができます。EnginFrame にはジョブの出力を追跡できるようにするインタラクティブなファイルマネ―ジャとスプーラービューが含まれています。このリリースで、NICE は同時に複数のファイルをアップロードできるようにする新しいファイルアップローダーを追加しました。ファイルアップローダーは一般的によく使用されているファイルをキャッシュすることでアップロード時間を削減することもできます。

EnginFrame の実行
EnginFrame を詳しく理解するために AWS で使用する EnginFrame のクイックスタートのページを開始してみました。リージョンには US East (Northern Virginia) リージョンを選択し [Agree and Continue] をクリックしました。

自分の AWS アカウントにログインし CloudFormation コンソールにアクセスしました。CloudFormation テンプレートの URL はすでに入力済みだったので [Next] をクリックしました。

スタックを設定します。名前を指定しネットワーク設定をセットアップしてパスワードを入力しました。

EC2 キーペアを選び自分のクラスター用に設定をセットアップしました (EC2 の新しいユーザーであれば、まず作成してからダウンロードする必要があります)。[Next] をクリックします。

足跡のためにタグ (キーと値) を入力します。ただしこの場合は IAM ロールアドバンスドオプションはそのままにし、もう一度 [Next] をクリックします。

次のページで設定を確認し (ここでは表示していません)、CloudFormation が私の代わりにいくつかの IAM リソースを作成することを了承します。次に [Create] をクリックします。

CloudFormation が必要な AWS リソースをすべて作成、設定、連係させます (このプロセスは約 30 分ほど掛かるので犬の散歩をするのに丁度いいでしょう‘)。

EnginFrame クラスターのステータスが CREATE_COMPLETE になったらそれをクリックし Output のセクションを開いて EnginFrameURL を探します。

URL は自己署名の SSL 証明書を使用する Application Load Balancer を参照するようになっているので、意図的にそのサイトにアクセスすることを確認する必要があります。

今起動した CloudFormation で EnginFrame が実行しています。ユーザー名 efadmin とスタック作成時に設定したパスワードでログインしました。

この時点でサービスを作成することができます。最初はまずシンプルに、アップロードしたファイルを圧縮するだけのサービスにしました。青色のタイトルバーで [Admin’s Portal] をクリックし、次にアクセスします。

[Manage] > [Services] > [New] をクリックしてサービスを定義します。

[Submit] をクリックし [Job Script] タブを選択したらデフォルトスクリプトにラインを追加し [Close] をクリックしてアクションウィンドウを閉じます。

新しいサービスを保存し [Test Run] をクリックして希望通りに動作するか確認します。デスクトップからファイルをアップロードし [Submit] をクリックしてジョブを起動します。

ジョブが私のクラスターで実行するようにキューが登録されます。

今回紹介したのは EnginFrame の機能のごく一部に限ります。

可用性と料金
EnginFrame 2017 は今すぐご利用いただけます。お支払いいただくのは使用した分の AWS リソース (EC2 インスタンス、EFS ストレージなど) となります。評価期間の最初の 90 日は無料で EnginFrame をご利用いただけます。その後は同時ユーザー数をベースにライセンスの元で EnginFrame をご利用いただけます。

Jeff;

4 月の AWS Black Belt オンラインセミナーのご案内

こんにちは。ソリューションアーキテクトの焼尾です。AWS Black Belt オンラインセミナー4月の配信についてご案内させて頂きます。4,5月は組織変更などがあった方も多く、基本に立ち返り、AWSの基礎となるサービスを中心に開催します。また、AWS re:Invent 2016 にて発表された新モバイルサービスの一つ、Amazon Pinpoint も開催します。

speakers
4月の開催予定

サービスカット
4/5(水) 18:00-19:00 Amazon EC2
4/12(水) 18:00-19:00 Amazon VPC
4/19(水) 18:00-19:00 Amazon S3
4/26(水) 18:00-19:00 Amazon Pinpoint

ソリューションカット
4/11(火) 12:00-13:00 初心者向け クラウドコンピューティング はじめの一歩
4/18(火) 12:00-13:00 サーバレスによるアーキテクチャパターンのご紹介

お申し込みは、それぞれ上記のリンクより行って頂けます。キャンセルの際も連絡不要ですので是非お早めにご登録ください。Speaker、Staff 一同みなさまのご参加をお待ちしております。

Amazon AppStream 2.0 の新機能 – Fleet Auto Scaling、Image Builder、SAML、メトリクス、フリート管理

昨年終わりに私の同僚 Gene Farrell が紹介したのは Amazon AppStream 2.0 です。そのゲスト投稿で、彼は AppStream 2.0 を使用することにより HTML5 ウェブブラウザを快適に使いながら、どのデバイスでも安全にデスクトップアプリケーションを実行できる方法について説明しました (詳しくはこちらのブログをご覧ください)。たとえば、起動時に AppStream 2.0 Try it Now ページを使用したところ、すぐに Siemens Solid Edge を使い始めることができました。Try it Now ページで好きなアプリケーションを選んだだけです。

数秒後には Solid Edge を実行していました。インストールや設定の必要もありません。

 

皆様からのリクエスト – Enterprises、SMB、ISV の新機能を追加
re:Invent でリリースしてから、皆様からのリクエストにお応えするため AppStream 2.0 の微調整を行い、いくつかの機能を追加しました。こうした新機能は、今まで以上に簡単にアプリケーションをデプロイ、アクセス、管理、トラックできるようにし、AppStream で利用できます。すでに大方の新機能をリリースしていますが、各機能に関するブログは公開していなかったので、今回はこうした新機能について簡単にご説明します。では最新機能をご紹介します。Fleet Auto Scaling – この新機能は CloudWatch メトリクスを使用してデマンドの変化に対応すべく、フリートのスケールアップやスケールダウンを可能にします。これにより瞬時のアクセスを実現しながら、できる限り安価にアプリケーションを提供することができます。Image Builder – 自分が選んだアプリケーションを含む AppStream 2.0 イメージを構築できます。SAML 2.0 認証 – AppStream 2.0 と既存の SAML 2.0 に準拠したディレクトリを使用できます。ユーザーは既存の認証情報でログインすることができます。フリート管理 – アプリケーションを実行するインスタンスの管理オプションを追加しました。CloudWatch メトリクス – サイズやフリート全体の使用率を含む 7つの Amazon CloudWatch メトリクスを観察しモニタリングすることができます。では詳しく見てみましょう。

Fleet Auto Scaling
この新機能は新しい CloudWatch メトリクスにサポートされています。各フリートにスケーリングポリシーを関連付けることができるようになりました。様々なタイプのユーザーからの要求に応えたりコスト管理に利用できます。ユーザーに生産性アプリケーションを提供するために AppStream 2.0 を使用している場合は、営業時間中にキャパシティーがオンラインになっていることを確実にしたり、ユーザーの就業時間終了後はそれに合わせられるようにスケーリングポリシーを使用できます。スケールアウト (キャパシティー追加) そしてスケールイン (キャパシティー削除) ポリシーを持つフリートについては、次をご覧ください。

この機能を活用するにはフリート作成時にキャパシティーの最小値と最大値を設定しておきます。

これによりデフォルトポリシーを作成することができます。後日にポリシーを編集、追加、削除することができます (各フリートにつき 50 件までのポリシーを作成できます)。詳細は AppStream Fleet Auto Scaling をご覧ください。

Image Builder
この機能ではお好きな商用アプリケーションやプロプライエタリアプリケーションを含むカスタムイメージを作成することができます。これを行うには image builder というインスタンスを起動します。次にインスタンスにログインし、お好きなアプリケーションをインストールして設定、インスタンスの状態をイメージとしてキャプチャします。ログインやカスタマイズのプロセスはすべてお使いのウェブブラウザ内で行われます。キーのダウンロードやパスワードを覚える必要はありません。アプリケーションはイメージレジストリで表示され、ユーザーが利用できます。AppStream 2.0 コンソールから image builder を起動できます。

次に開始点 (既存のイメージ) を選びます。

名前を指定し、インスタンスのサイズを選び VPC をセットアップすることでビルダーを設定します。

[Review] をクリックして設定を確認し、ビルダーが起動するのを待ちます。

image builder に接続できるようになったら、アプリをセットアップしイメージを作成します。接続時には管理者とテストという 2 つの選択肢があります。

[ImageBuildAdmin] を選び (パスワード入力がリクエストされたら) [Log me in] を Admin Commands で見つけてクリックします。

ログイン後、Image Assistant アプリを起動しアプリのインストールやテストに使用します。

詳細については Image BuildersAppStream 2.0 Image Builder のチュートリアルをご覧ください。

SAML 2.0 認証
この機能は SAML 2.0 をサポートするあらゆる外部 ID プロバイダーの使用を許可します。これは Active Directory フェデレーションサービスPingFederate サーバーOktaShibboleth を含みます。

Setting Up SAML の手順を完了すると、ユーザーは既存の ID や認証情報を使用して AppStream 2.0 にログインすることができます。ユーザーやグループを管理したり、ユーザーの ID または場所をベースにアプリケーションへのアクセスを管理することができ、Multi-Factor Authentication (MFA) を使用できます。詳細については SAML 2.0 を使用して AppStream 2.0 でシングルサインオンアクセスを有効にするをご覧ください。すでに AWS マネジメントコンソールにフェデレーションアクセスをセットアップしている場合は、すでにご存知の情報を大方適用できます。

フリート管理
この機能はフリート (ユーザーのアプリケーションを実行しているインスタンスのグループ) をさらにコントロールできるようにします。1 つの画面で自分のフリートをすべて見ることができます。

フリートを 1 つ選び、それに対応することができます。

フリートのプロパティにはいつでも編集できるものもあります。VPC プロパティを含むその他においては、フリートが停止した場合のみ編集することができます。詳細についてはスタックとフリートをご覧ください。

CloudWatch メトリクス
AppStream は 8 つのメトリクスを各フリートの CloudWatch に発行します。

  • RunningCapacity – 実行中のインスタンス数
  • InUseCapacity – 使用中のインスタンス数
  • DesiredCapacity – 実行中または保留中のインスタンス数
  • AvailableCapacity – 使用可能なアイドル中のインスタンス数
  • PendingCapacity – プロビジョニング中のインスタンス数
  • CapacityUtilization – 使用中のフリートの割合 (%)
  • InsufficientCapacityError – キャパシティー不足により拒否されたセッション数

AppStream 2.0 コンソールでこうしたメトリクスを見ることができます。

こうしたメトリクスはフリートのサイズを微調整する場合に全体の使用状況を把握する上で便利です。どの CloudWatch メトリクスでも同じ様に、アラートを生成しメトリクスが希望範囲外にある場合に警告を発することができます。AWS Lambda 関数を使用して環境を変更したり、専用の通知を生成することもできます。詳細については Amazon AppStream 2.0 リソースのモニタリングをご覧ください。

今すぐ利用可能
これらのすべての機能は今すぐご利用いただけます。

Jeff;

 

サーバレス 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 辻 義一)

R で Amazon Athena を活用する

データサイエンティストはしばしば、R から SQL クエリを投げるときに、その裏側のビッグデータ基盤のインフラ管理を気に掛けなければなりません。Amazon Athena はインフラ管理の必要がなく、標準 SQL で簡単に S3 上のデータを直接分析できる、インタラクティブクエリサービスです。R と Amazon Athena の連携によって、データサイエンティストはインタラクティブな分析ソリューションのための、強力なプラットフォームを手に入れることができます。

このブログポストでは、Amazon EC2 インスタンス上で動作する R/RStudio から Athena に接続します。

事前準備

Athena との連携を開始する前に、以下のステップを完了してください。

  1. AWS アカウントの管理者に依頼して、Athena にアクセスするのに必要な権限を、Amazon の Identity and Access Management (IAM) コンソール経由で、自身の AWS アカウントに付与してもらってください。具体的には、IAM にあるデータサイエンティストのユーザーグループに対して、関連する Athena のポリシーをアタッチしますRAthena_1
  2. Amazon S3 バケットに、ステージングディレクトリを作成してください。Athena はクエリする対象のデータセットと、クエリ結果を置く場所として、このバケットを利用します。このポストでは、ステージングバケットを s3://athenauser-athena-r とします

注意: このブログポストでは、すべての AWS リソースは us-east-1 リージョンに作成します。ほかのリージョンでも Athena が利用可能かどうか、製品およびサービス一覧で確認してください。

EC2 上での R と RStudio の起動

  1. AWS上でRを実行する” のインストラクションにしたがって、EC2 インスタンス(t2.medium かそれ以上のサイズ)で Amazon Linux を動かし、R のセットアップを行います。始める前に、以下のステップを確認しておいてください
  2. このブログポストの “高度な詳細” の記述で、ステップ 3 まできたら、最新バージョンの RStudio をインストールするため、以下の bash スクリプトを実行してください。必要であれば、RStudion のパスワードも修正してください
#!/bin/bash
#install R
yum install -y R
#install RStudio-Server
wget https://download2.rstudio.org/rstudio-server-rhel-1.0.136-x86_64.rpm
yum install -y --nogpgcheck rstudio-server-rhel-1.0.136-x86_64.rpm
#add user(s)
useradd rstudio
echo rstudio:rstudio | chpasswd

Java 8 のインストール

  1. EC2 instance に SSH でログインします
  2. 古いバージョンの Java を削除します
  3. Java 8 をインストールします。これは Athena を動かすために必要です
  4. コマンドライン上で、以下のコマンドを実行します
#install Java 8, select ‘y’ from options presented to proceed with installation
sudo yum install java-1.8.0-openjdk-devel
#remove version 7 of Java, select ‘y’ from options to proceed with removal
sudo yum remove java-1.7.0-openjdk
#configure java, choose 1 as your selection option for java 8 configuration
sudo /usr/sbin/alternatives --config java
#run command below to add Java support to R
sudo R CMD javareconf

#following libraries are required for the interactive application we build later
sudo yum install -y libpng-devel
sudo yum install -y libjpeg-turbo-devel

.Renviron のセットアップ

R の環境変数 .Renviron に対して、必要となる Athena のクレデンシャルを追加します。

  1. AWS 管理者から、必要なクレデンシャルを AWS_ACCESS_KEY_ID および AWS_SECRET_ACCESS_KEY の形式で取得します
  2. Linux のコマンドプロンプトから以下のコマンドを打ち込んで、vi エディタを立ち上げます
    sudo vim /home/rstudio/.Renviron
    
    Provide your Athena credentials in the following form into the editor:
    ATHENA_USER=< AWS_ACCESS_KEY_ID >
    ATHENA_PASSWORD=< AWS_SECRET_ACCESS_KEY>
  3. 編集結果をセーブして、エディタを終了します

RStudio にログイン

続いて、EC2 上の RStudio にログインします。

  1. EC2 のダッシュボードからインスタンスのパブリック IP アドレスを取得して、ブラウザのアドレス欄に貼り付け、後ろに :8787(RStudio のポート番号)を付けます
  2. EC2 インスタンスに関連付けられたセキュリティグループm設定で、アクセス元の IP アドレスから 8787 ポートへのアクセスが許可されていることを確認してください
  3. 先ほど設定したユーザ名とパスワードで、RStudio にログインします

R パッケージのインストール

続いて、必要な R パッケージをインストールして、ロードします。

#--following R packages are required for connecting R with Athena
install.packages("rJava")
install.packages("RJDBC")
library(rJava)
library(RJDBC)

#--following R packages are required for the interactive application we build later
#--steps below might take several minutes to complete
install.packages(c("plyr","dplyr","png","RgoogleMaps","ggmap"))
library(plyr)
library(dplyr)
library(png)
library(RgoogleMaps)
library(ggmap)

Athena への接続

以下の R のスクリプトで、Athena ドライバーのダウンロードと、コネクションの設定を行います。アクセスしたいリージョンの JDBC URL に接続してください。

#verify Athena credentials by inspecting results from command below
Sys.getenv()
#set up URL to download Athena JDBC driver
URL <- 'https://s3.amazonaws.com/athena-downloads/drivers/AthenaJDBC41-1.0.0.jar'
fil <- basename(URL)
#download the file into current working directory
if (!file.exists(fil)) download.file(URL, fil)
#verify that the file has been downloaded successfully
fil
#set up driver connection to JDBC
drv <- JDBC(driverClass="com.amazonaws.athena.jdbc.AthenaDriver", fil, identifier.quote="'")
#connect to Athena using the driver, S3 working directory and credentials for Athena 
#replace ‘athenauser’ below with prefix you have set up for your S3 bucket
con <- jdbcConnection <- dbConnect(drv, 'jdbc:awsathena://athena.us-east-1.amazonaws.com:443/',
s3_staging_dir="s3://athenauser-athena-r",
user=Sys.getenv("ATHENA_USER"),
password=Sys.getenv("ATHENA_PASSWORD"))
#in case of error or warning from step above ensure rJava and RJDBC packages have #been loaded 
#also ensure you have Java 8 running and configured for R as outlined earlier

これで RStudio から Athena に接続する準備ができました。

サンプルクエリでテスト

# get a list of all tables currently in Athena 
dbListTables(con)
# run a sample query
dfelb=dbGetQuery(con, "SELECT * FROM sampledb.elb_logs limit 10")
head(dfelb,2)

RAthena_2

インタラクティブなユースケース

次に、分析と可視化のために R から Athena に対してインタラクティブなクエリを行ってみましょう。S3 上にあるパブリックデータセットの GDELT を使います。

GDELT データセットに対して、R から Athena のテーブルを作成します。このステップは “Amazon Athena – Amazon S3上のデータに対話的にSQLクエリを” で紹介されているように、AWS のマネジメントコンソール上からも実行することができます。

#---sql  create table statement in Athena
dbSendQuery(con, 
"
CREATE EXTERNAL TABLE IF NOT EXISTS sampledb.gdeltmaster (
GLOBALEVENTID BIGINT,
SQLDATE INT,
MonthYear INT,
Year INT,
FractionDate DOUBLE,
Actor1Code STRING,
Actor1Name STRING,
Actor1CountryCode STRING,
Actor1KnownGroupCode STRING,
Actor1EthnicCode STRING,
Actor1Religion1Code STRING,
Actor1Religion2Code STRING,
Actor1Type1Code STRING,
Actor1Type2Code STRING,
Actor1Type3Code STRING,
Actor2Code STRING,
Actor2Name STRING,
Actor2CountryCode STRING,
Actor2KnownGroupCode STRING,
Actor2EthnicCode STRING,
Actor2Religion1Code STRING,
Actor2Religion2Code STRING,
Actor2Type1Code STRING,
Actor2Type2Code STRING,
Actor2Type3Code STRING,
IsRootEvent INT,
EventCode STRING,
EventBaseCode STRING,
EventRootCode STRING,
QuadClass INT,
GoldsteinScale DOUBLE,
NumMentions INT,
NumSources INT,
NumArticles INT,
AvgTone DOUBLE,
Actor1Geo_Type INT,
Actor1Geo_FullName STRING,
Actor1Geo_CountryCode STRING,
Actor1Geo_ADM1Code STRING,
Actor1Geo_Lat FLOAT,
Actor1Geo_Long FLOAT,
Actor1Geo_FeatureID INT,
Actor2Geo_Type INT,
Actor2Geo_FullName STRING,
Actor2Geo_CountryCode STRING,
Actor2Geo_ADM1Code STRING,
Actor2Geo_Lat FLOAT,
Actor2Geo_Long FLOAT,
Actor2Geo_FeatureID INT,
ActionGeo_Type INT,
ActionGeo_FullName STRING,
ActionGeo_CountryCode STRING,
ActionGeo_ADM1Code STRING,
ActionGeo_Lat FLOAT,
ActionGeo_Long FLOAT,
ActionGeo_FeatureID INT,
DATEADDED INT,
SOURCEURL STRING )
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION 's3://support.elasticmapreduce/training/datasets/gdelt'
;
"
)

dbListTables(con)

上記のステートメントを実行すると、RStudio のコンソールに ‘gdeltmaster’ というテーブルが新しく作成されたのを確認できます。

RAthena_3

2015 年に US で開かれた CAMEO イベントの回数をカウントするクエリを、Athena テーブルに投げましょう。

#--get count of all CAMEO events that took place in US in year 2015 
#--save results in R dataframe
dfg<-dbGetQuery(con,"SELECT eventcode,count(*) as count
FROM sampledb.gdeltmaster
where year = 2015 and ActionGeo_CountryCode IN ('US')
group by eventcode
order by eventcode desc"
)
str(dfg)
head(dfg,2)

RAthena_4

#--get list of top 5 most frequently occurring events in US in 2015
dfs=head(arrange(dfg,desc(count)),5)
dfs

RAthena_5-300x140

上記の R の出力結果から、CAMEO イベントは 42 回という高頻度で行われたことがわかります。CAMEO のマニュアルから、このイベントの概要が “会議やその他のイベントのための、他の地域への出張” となります。

次に、この分析から得られる知見を使い、この特定のイベントに関連したすべての地域の座標リストを、Athena テーブルから取得します。

#--get a list of latitude and longitude associated with event “042” 
#--save results in R dataframe
dfgeo<-dbGetQuery(con,"SELECT actiongeo_lat,actiongeo_long
FROM sampledb.gdeltmaster
where year = 2015 and ActionGeo_CountryCode IN ('US')
and eventcode = '042'
"
)
#--duration of above query will depend on factors like size of chosen EC2 instance
#--now rename columns in dataframe for brevity
names(dfgeo)[names(dfgeo)=="actiongeo_lat"]="lat"
names(dfgeo)[names(dfgeo)=="actiongeo_long"]="long"
names(dfgeo)
#let us inspect this R dataframe
str(dfgeo)
head(dfgeo,5)

RAthena_6

続いて、アメリカ合衆国の地図を生成します。

#--generate map for the US using the ggmap package
map=qmap('USA',zoom=3)
map

RAthena_7

これで、Athena テーブルから得られた地理データが、地図上にプロットされました。これにより、2015 年に US でひらかれたすべての当該イベントについて、開催場所を可視化することができました

#--plot our geo-coordinates on the US map
map + geom_point(data = dfgeo, aes(x = dfgeo$long, y = dfgeo$lat), color="blue", size=0.5, alpha=0.5)

RAthena_8

結果を可視化することによって、あるイベントの開催場所が US の北東部に極めて集中していることを把握できました。

結論

この記事では Athena と R を使って、簡単なインタラクティブアプリケーションを構築する方法を説明しました。Athena は標準 SQL を用いて、ビッグデータを保存し、それに対してクエリをかけるのに使うことができます。またその一方で、R の持つ強力なライブラリ群を活用することで、Athena に対してインタラクティブにクエリを投げ、分析のインサイトを得ることができます。

質問やアドバイスなどがありましたら、コメント欄にフィードバックをお願いします。

原文: Running R on Amazon Athena (翻訳: SA志村)