AWS S3勉強まとめ

ブロックストレージ
EBS, インスタンスストア
→EC2にマウントして活用
→Block番号で管理

オブジェクトストレージ
S3, Glacier
→安価かつ高い耐久性を持つオンラインストレージ
→オブジェクト、それに付随するメタデータ、そのオブジェクトにアクセスするためのユニークなIDで構成

ファイルストレージ
EFS
→EC2から同時マウントできる共有ストレージサービス
→ファイルシステム

・S3特徴
→容量無制限、安価なストレージ(1GB3円)、データ容量に依存しない性能(RAIDやサーバー台数を考える必要なし)

・S3用途
①コンテンツ配信、保管サーバ
②ログ&データハブストレージ
③バックアップやDR

バケット
オブジェクトの保存場所。デフォルト100個/1アカウントまで作成可能。名前はグローバルでユニークな必要あり。
オブジェクト
データ本体。URLが付与される
キー
オブジェクトの格納URL
メタデータ
オブジェクトに付随する属性情報。システム定義メタデータ、ユーザ定義メタデータあり
リージョン
バケットを配置するAWSのロケーション
アクセスコントロールリスト(ACL)
バケットやオブジェクトのアクセス管理

・ストレージクラス
スタンダード
標準低頻度アクセスストレージ:スタンダードに比べて安価だが、データの読出し容量に対して課金
Glacier:最も低コスト。データの取り出しにコストと時間
低冗長化ストレージ:Glacierから取り出したデータの置き場所として利用

結果整合性(Eventual Consistency Readモデル)
「更新はそのうち全体に反映される」
読み取り一貫性
– あるトランザクションがデータを変更中のとき、ほかのトランザクションからは変更される前のデータを参照します。
– ほかのトランザクションからは変更前の確定されたデータを参照します。
– あるユーザーAが値をUPDATEしたとき、ユーザーBがそのデータを参照すると、戻ってくる値はUPDATE前の値となります。
– あるトランザクションで変更した確定前のデータをほかのトランザクションから参照することはできません。

・パソコンのファイルシステムやデータベースと同じようにロックやトランザクション処理は行われない
参考URL:https://dev.classmethod.jp/cloud/amazon-s3-eventually-consistent-and-consistent-read/

・アクセス管理
①ユーザポリシー
→IAMuserに対して権限設定
②バケットポリシー
→バケットごとに権限設定。クロスアカウントで使用する際など
③ACL
→バケット、オブジェクトごとに指定可能(オブジェクトACLが優先)

署名付きURL
AWS SDKで作成。S3のプライベートなオブジェクトに対して一定時間アクセスを許可

・Webサイトホスティング機能
静的なWebサイトをS3のみでホスティング可能
– バケット単位で指定
– 独自ドメインの設定→ドメイン名をバケット名として指定
– リダイレクト機能→任意のドメインにリダイレクト設定が可能
CloudFrontとの経由で配信することを推奨。バケットポリシーでHTTP/HTTPSリクエストのみを許可可能

VPCエンドポイント
プライベートサブネットからNATゲートウェイなどを経由せずに直接S3とセキュアに通信可能
同一リージョンのみ

S3 support for IPv6
追加費用なし
静的ウェブホスティングは使用不可

・暗号化
– サーバーサイド暗号化(サーバリソースを利用して格納データの暗号化)
– クライアントサイド暗号化(クライアント側で暗号化したデータをS3にアップロード)

クロスリージョンレプリケーション
異なるリージョン間のS3バケットオブジェクトのレプリケーションを実施
→オブジェクトに対する動作を非同期でレプリケーション
→対象元バケットはバージョニングの機能を有効にする必要あり
※リージョン間データ転送費用が発生

バージョン管理機能
誤操作による削除対策に有効
バケットに対して設定
任意のオブジェクトを参照可能
バージョニングのオブジェクト分も課金。保存期間も指定可能

ライプサイクル管理
バケット内のオブジェクトに対して、ストレージクラスの変更や、削除処理の自動化
データ登録→Standard保存(一定期間過ぎたら削除)→Standard-IA移動(一定期間過ぎたら削除)→Glacierにアーカイブ(一定期間過ぎたら削除)

・アーカイブ
S3上のデータを削除でGlacier側のデータも削除
S3には8KBのオブジェクト名とメタデータのみ保管

・復元
オブジェクトごと
一時的にS3の低冗長化ストレージに指定日数複製(Glacierと低冗長化ストレージ両方課金)
復元にかかる時間の選択肢は3つ
①Expedited:緊急のアクセス
②Standard:3-5時間。標準的
③Bulk:大量のデータ。5-12時間
それぞれによってコストが異なる

・オブジェクト移動
Standard⇔Standard-IA→Glacier
→Glacier

S3分析
Standard-IAとGlacierどちらにいつ移動すればいいだろうかという疑問に答える可視化ツール
→ライフサイクルポリシーの設定値の参考になる

S3インベントリ
S3のオブジェクトのリストを一気にcsvファイルで取得
スケジュールかも可能

・イベント通知
SNS:メール送信
SQS:キューメッセージの登録
Lambda:ファンクションの実行

・CloudWatchによる監視
ストレージメトリクス:バケット単位。1日単位でのレポート。追加費用なし
リクエストメトリクス:オブジェクト単位。通常のCloudWatch料金

CloudTrailによるAPI(操作ログ。Get, Delete, Putなど)管理
S3への操作ログを収集
監査対象とは別のS3バケットの用意推奨

Logging
バケットに対するアクセスログの出力設定可能

Tag管理
バケット/オブジェクトに対してタグの指定可能

・パフォーマンスの最適化
大きなサイズのファイルをアップロード、ダウンロード
RANGE GETを活用。マルチパートアップロード機能
大量のGETリクエストが発生する場合はCloudFrontを併用することを推奨

Transfer Acceleration(高速ファイル転送サービス)
AWSのエッジネットワークから最適化されたAWSのネットワークを経由する。
S3のデータ転送コストとは別に加算
※通常の転送より高速でない場合は、課金されない

コンテンツ配信サーバ
データをS3に配置、CloudFrontでキャッシュさせる
CloudFrontで静的コンテンツ配信。CloudFrontの料金はかからない
Webサーバーで動的コンテンツは処理

ログ&データハブストレージ
オンプレ:Direct Connectでログデータ収集
外部データソース;Kinesisで収集
AWS;S3に保管。Glacierにアーカイブ
分析:Redshift, EMR, Atenaなど

バックアップ、DR
クロスリージョンでデータの複製を保持
リージョン内でもDR設定

参考URL:https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-amazon-s3

続きを読む

Optimize Delivery of Trending, Personalized News Using Amazon Kinesis and Related Services

この記事に対して4件のコメントがあります。コメントは「小出さんだ!」、「グノシーさんの事例がグローバル!」、「AWSのマネージドサービス超活用事例」、「小出スペシャルの解説がAWS公式ブログに!」です。 続きを読む

「Microservices Meetup vol.6」に行ってきた

2017/1/19のデイリーストックランキングにランクインしました。

【毎日自動更新】Qiitaのデイリーストックランキング!ウィークリーもあるよ_-_Qiita.png


いままでの。
「Microservices Meetup vol.2」行ってきたメモ。
「Microservices Meetup vol.4」に行ってきた

図らずして1回おきに参加してますね。

Connpassのイベントページ

少し間が空いてしまったがまた定期的に開催していきたいです。
登壇したいよーって人は直接リプ投げてください
by @qsona さん

Microservices on AWS by @Keisuke69 さん

Keisuke Nishitani @ AWS

Specialist Solutions Architect

サーバーレスアプリケーション開発ガイド 2月発売

マイクロサービスのポイント

  • 管理運用まで含めて分散型
  • 各コンポーネントが独立している
    • 単独で実行できないのは適切に設計されていない

独立して分散していると負荷の高い機能の単位でスケールさせられる=コスト効率が良い

  • 一つのことをうまくやる

    • 複雑化したら分割する
  • 多言語

    • チーム(機能)にはそれぞれの問題に対して適切なツールを選択する自由がある
    • OS、言語、各種ツールに至るまで最適なアプローチを目指せる
  • 検索:Elasticsearch / Solr

  • ソーシャル:グラフDB

  • ログデータ:Cassandra

  • セッション:Redis

†AWSでは:AWSには100ちょいのサービスがあって、その中で更にチームが分かれている。
各チームに社内標準の開発プロセスは存在しない。

  • ブラックボックス

    • 詳細は外部のコンポーネントに公開されない
  • DevOps
    • マイクロサービスにおける組織原理

†AWSでは:運用のみのチームはない。オンコールも開発チームが請け負う

  • 俊敏性

    • 狭い範囲のコンテキストで活動=サイクルタイムが短い
    • システムもシンプル
    • パラレルな開発とデプロイが可能
  • イノベーション

    • 選択に対する権限と責任を持つのでイノベーションを起こしやすい
    • DevとOpsの対立がないため、効率化やイノベーションが起こしやすい
  • 拡張性

    • 適切に非干渉化されてていることで水平方向に単独にスケールできる
  • 可用性

    • ヘルスチェック、キャッシング、隔壁、サーキットブレーカーと言った仕組みは全体の可用性を向上させる

課題

  • 分散型であることは難しい

    • システム数が増える
    • 協調動作の難しさ
    • コンポーネント間のコミュニケーションメッセージ増によるレイテンシ低下
    • ネットワークの信頼性は無限ではない、帯域も無限ではない
  • 移行が大変
    • モノリシックなシステムの分割は難しい
  • 組織
    • 組織体制の変更が必要になるが、それは大変なこと
  • アーキテクチャの難易度
    • 非同期通信
    • データ整合性
    • やっぱりココが一番の課題
    • サービスディスカバリ
    • 認証
  • 運用の複雑さ

アーキテクチャ

一番シンプルなパターン

CloudFront – ALB – ECS – datastore(ElastiCache, Dynamo, )
|
S3

  • バックエンドをRESTfulなAPIにしたSPA
  • 静的なコンテンツはS3とCloudFront
    • CDN通すことでレイテンシが上がることもある
    • キャッシュとの併用を検討
  • ECSとAutoScalingをALBとともに使うことが多い
    • ALB(L7LB)でアプリレベルの情報をルーティング
    • コンテナインスタンスにリクエストを分散
    • ECSのコンテナを負荷に応じてスケールアウト/インする

コンテナのメリット

  • Portable
  • Flexible
  • Fast
    • 軽量で早い
    • ポータビリティと関連して開発サイクルも早く
  • Efficient

  • 一貫性のある環境

  • バージョン管理出来る

Dockerの特徴

  • Package
  • Ship
  • Run

ECS

  • 複数のコンテナをEC2のクラスタ上で一元管理

    • まだTokyoにきてないけど、FargateでEC2の管理もいらなくなるよ
    • EKS(Kubernetes)も発表されています

データストア

  • インメモリ

    • Memcached, Redis
    • ElastiCache
    • DB負荷の軽減
  • RDBMS
    • 無限のスケーリングには向いていない
    • Amazon RDS
  • NoSQL
    • 水平スケーリングをサポートするものが多い
    • テーブル結合ができないのでロジックの実装が必要になる場合も
    • Amazon DynamoDb, KynamoDB Accelarator(DAX)

APIの実装

  • APIの設計、改善、デプロイ、モニタリング、保守派手間がかかる
  • 異なるバージョンが混在すると大変

Amazon API Gateway

  • 複数バージョンとステージ
  • Cognite User Poolsと連携して認証を追加
  • スロットリング、モニタリング
  • バックエンドとしてLamdbaが使える

サーバーレス

  • サーバーはないに越したことはない
  • スケーリングと高可用性の担保が大変
CloudFront - API Gateway - Lamdba - datastore
   |                            (ElastiCache, Dynamo)
   |
  S3

課題をAWSでどうするか

サービスディスカバリ

  • お互いの死活確認や発見
  • ハードコードするとスケールできない

    • メタデータをどこに置くか
  • ALBを利用したサービスディスカバリ

  • DNS(Route53)のサービスディスカバリ

    • VPC単位の振り分け
  • ECSイベントストリームを使用したサービスディスカバリ

    • CloudWatchイベントで拾ってキック
    • LamdbaでRoute53に登録
    • これが一番多いかも
  • DynamoDBを使用したサービスディスカバリ

    • DNSキャッシュの問題がない
    • 自由度が高い
    • 実装が大変
    • DynamoDBストリームを活用して他のサービスへステータス変更を反映
  • イベントベースのアーキテクチャ

    • イベントで処理する
    • いわゆる結果整合性とも関連
    • Dual Write Problem
    • Event Sourcing
      • 状態の記録ではなく状態の変更「イベント」を記録
      • Amazon Kinesis
      • kinesisにpublishして他サービスはsubscribe
      • S3にログを残す
      • トランザクションログの仕組み

モニタリング

  • CloudWatch

    • ログファイルの一元化
    • CloudWatch LogsかS3に保存可能
    • ECSはCloudWatch Logsに一元化できる

分散トレース

  • AWS X-Ray
  • 複数サービスに分散したリクエスト処理を透過的に追える

LogWatchの先に Kinesis FireHorse – ほにゃほにゃ

スロットリング

  • 大事だよ

リトライ

  • 多くのエラーはリトライでカバーできるものが多い
  • リトライ多発で過負荷になることがある
    • Exponential back offもしくはフィボナッチ数列を利用したリトライ感覚の調整
    • 更に乱数でゆらぎを付けて重ならないように

LT:クラウド型医療系業務システムと Microservices への歩み by @hashedhyphen さん

https://speakerdeck.com/hashedhyphen/kuraudoxing-dian-zi-karutesisutemuto-microservices-hefalsebu-mi

クラウド型電子カルテシステムの話

  • メインロジックをRails
  • 常時接続をNode.js
  • バックエンドをScala
  • 基盤はAWS

ここに至る道のり

ファーストリリース前

  • レコメンドは大量のデータが必要

  • メインロジックで実現させようとすると厳しかった

    • Threadとか試したけど……
    • 別アプリケーションとして分離
    • JVM上でScala + Skinnyでスレッドアプリケーションンを実装
    • Microservicesちっくな構成へ
  • 障害検知時

    • メインロジック内のプロトタイプ版が動く!

会計機能リリース前

  • お金を扱う機能は安定性が欲しい
  • Scala + Cats による実装を別エンドポイントとして実装
  • マイクロサービスっぽい作りになっていたから自由度のある技術選択が出来た

まとめ

  • ちょっとマイクロサービス化したことで自由度が上がった
  • 原理主義的にならなくても恩恵がある
  • エンジニアの伸びしろ!

FrontEndからみるmicroserviceとBackendからみるmicroservice by @taka_ft さん

Takahiro Fujii @ Rakuten Travel

楽天内でも採用アーキテクチャはサービスによって異なる。

サービスとしては

  • コンシューマ向け
  • Extranet
  • In-house
  • other
    • ここまではWEBとモバイルがあって、100以上のAPIを利用する
  • API(内部APIを直接利用)

Phase 1

  • 大きなモノリシックなアプリだった
  • 機能がどんどん増えていく
    • 機能別で複数のモノリシックなアプリに分割
    • その後フロントエンドとバックエンドに分割

Phase 2

  • ドメインモデルを整理
  • なるべくRESTfulで作るようになっていった
  • 大きなAPIから小さなAPIに分離
  • I/Fの決定に時間がかかるようになった
  • API呼び出しが大変になった
  • Microservicesっぽくなってきた 2014年くらい

  • 国内予約、海外予約で多言語化だけではない商習慣に根ざしたドメインの差異による重複ロジックの増殖が起きた

  • Microservicesっぽくなってきたが、どんどん品質が下がっていった

Phase 3

(ちょうど前日にプレスリリース)サイト前面刷新に向けての取り組み

  • FrontendsはJavaScriptに刷新
  • API GatewayにKong

組織

  • フロントエンドチームが2人から始まって半年でReactエンジニアを集めて20人以上に

    • 日本人は2, 3人

UI Component

  • SpringからJavaScriptでSPAに変更
  • zeplinのデザインモックからUI Componentを実装するようになった
  • Storyboardを使ってUI Coponentを管理
  • ドメインを含むUI Componentはドメインと結び付きが強いことが多い=専用のオーケストレーションAPIを用意してUI Componentないで処理を閉じることが出来る
  • レスポンシビリティを明示的に定義

    • どこまでフロントエンドでやるか、どこからAPIからもらうか
  • フロントエンドの「使いやすいレスポンス」の要求

  • バックエンドの「汎用的でシンプルなレスポンス」の希望

    • これらのバランスを取る
  • API Gatewayはフロントエンド(UI)チームの管轄

    • ただし状況によってはバックエンド側に持っていくことも検討するつもり

LT: “マイクロサービスはもう十分”か? by @qsona さん

https://speakerdeck.com/qsona/enough-with-the-microservices

POSTDに投稿していた翻訳記事。

スタートアップ企業のほとんどはマイクロサービスをさいようすべきではない

銀の弾丸はない。

「チーム間の依存性」の解決にマイクロサービスというアプローチは違う。疎結合と分散は別。

組織が大きくなると、複数チームが1つのコードベースを触るようになる。そしてマイクロサービス化したくなる。

しかし、モノリスの分割で十分。

チームとは何か

  • 自律的に動けるべき

    • チームが増えるとコミュニケーションコストや、しがらみ
  • チームの分割は目的にそった分割を行う

  • 悪い分割の例: Dev / Ops

  • 依存度が低いほど自律的に動ける

  • High Output という本

  • 使命型組織/技術型組織

    • Micorservicesは使命型組織
    • 組織間が密ならサービス間も密になる

話戻して

  • スタートアップは組織をキレイに分割することが難しい
  • 分割しても密になってしまう

  • 大きなモノリスになるとやはり分割は難しい

    • ドメインの意識は必要
  • マイクロサービス設計しなくても「マイクロサービス精神」で開発すると効果的なのではないか

FiNCが初期からマイクロサービスでやってた理由

  • 単独の事業にできるような一つ一つのサービスを組み合わせて提供してきたから

あとで読み返して修正します。
資料パスの追加とかも。

続きを読む

「M-1グランプリ」の順位予想投票システム、ヤフー傘下2社がAWS上に構築

クラウドサービスは米アマゾン・ウェブ・サービスの「Amazon Web Services(AWS)」を選択。順位予想の投票をリアルタイムで受け付ける仕組みとして、ストリームデータ処理サービス「Amazon Kinesis」を採用した。このKinesisで受けたデータを、仮想マシンサービス「Amazon Elastic Compute Cloud(EC2)」上に稼働させた … 続きを読む

AWSとAzureとGCPを比較してみる – FaaS編

FaaSについてAWSとAzureとGCPを比較してみました。

注)

1. FaaS比較表

AWS Azure GCP
Lambda Functions Cloud Functions***
言語 Python,
node.js,
java,
C#,
go
ランタイムバージョン1.X
C#,
JavaScript,
F#,
Python*,
PHP*,
TypeScript*,
バッチ (.cmd、.bat)*,
Bash*,
PowerShell*

ランタイムバージョン2.X
C#**,
JavaScript**,
Java**
node.js***
最大実行時間 5分 10分 (従量課金プラン)
無制限 (App Serviceプラン)
9分
直接HTTPアクセスを受け付けるか 受け付けない(API Gatewayと連携必要) 受け付ける 受け付ける
トリガー Amazon S3,
Amazon DynamoDB,
Amazon Kinesis Data Streams,
Amazon Simple Notification Service,
Amazon Simple Email Service,
Amazon Cognito,
AWS CloudFormation,
Amazon CloudWatch Logs,
Amazon CloudWatch Events,
AWS CodeCommit,
スケジュールされたイベント (Amazon CloudWatch Events を使用),
AWS Config,
Amazon Alexa,
Amazon Lex,
Amazon API Gateway,
AWS IoT ボタン,
Amazon CloudFront,
Amazon Kinesis Data
Blob Storage,
Cosmos DB,
Event Hubs,
HTTP,
Microsoft Graph Events(2.Xのみ),
Queue storage,
Service Bus,
Timer,
Webhooks(1.Xのみ)
HTTP,
Cloud Storage,
Cloud Pub/Sub

*試験段階
**プレビュー
***ベータ

2. 対応言語の比較

言語の種類は試験段階とプレビューを含めればAzureが一番多いのですが、正式リリースされたものに限定すればAWSの方が種類が多いです。
一方GCPは機能自体がベータリリースなので、まだこれからといった感じでしょうか。

AzureはBashにも対応しているのが特徴です。運用系のシェルスクリプトをFaaS化すれば、スクリプト用のサーバが不要になりますね。

3. 最大実行時間

最大実行時間はAzureの10分(要host.jsonのfunctionTimeoutプロパティ変更)、GCPの9分に対しAWS Lamdbaは5分と約半分です。実際にAWS Lambdaを利用していると5分の壁を結構感じます。この点は他クラウドが羨ましいですね。
2017年のRe:InventでAWSはFargateというコンテナのサービスをリリースしましたが、このサービスがlambdaが5分以上実行できないことに対するAWSからの回答のように感じます。

4. 直接HTTPアクセスを受け付けるか

AWS lambdaだけ直接HTTPアクセスを受け付けることができません。HTTPアクセスを受け付けるには、API Gatewayと連携する必要がありますが、多機能な分やや設定が面倒な印象です。(但しAPI経由でLambdaを起動することは可能)

まとめ

AWS Lambdaのリリース後、Azure・GCP・Bluemix(現IBM Cloud)は超特急で追従しました。AWS LambdaがIT業界に与えたインパクトはとても大きかったと思います。
現在は「FaaS無ければばクラウドにあらず」といったところでしょうか。

また、AWS GreengrassやAzure IoT Edge**というエッジにデプロイするサービスも出てきています。
将来AWS LambdaがiPhoneやApple Watchにデプロイできるようにならないかなーと妄想中です。

**プレビュー

続きを読む

Athenaで入れ子のjsonにクエリを投げる方法が分かりづらかったので整理する

Kinesis FirehoseでS3に置かれた圧縮したjsonファイルを、それに対してクエリを投げる、というのを検証してたのですが、Hive素人なのでスキーマの作り方もクエリの投げ方も正直あんまり良くわかってませんでした。

そこで下記を参照しながらスキーマの作成とクエリ投入をやってみて、最終的にうまくいきました。

日本語記事
https://aws.amazon.com/jp/blogs/news/create-tables-in-amazon-athena-from-nested-json-and-mappings-using-jsonserde/

元記事
https://aws.amazon.com/jp/blogs/big-data/create-tables-in-amazon-athena-from-nested-json-and-mappings-using-jsonserde/

ずーっと日本語記事を読みながらやっていたのですが、これがめちゃくちゃわかりづらい!!!
※理解度には個人差があります

多分知っている人が見たら何となくわかるんでしょうが、恐らくこれを見るのは自分みたいにあまり良く知らないので参考にしながら実際にやってみている、という層だと思います。
最終的に上手く行ってから思ったのは、前提知識がないと読むのがしんどい、ということですね…。
ただもう少し書いといてくれるだけで十分なのに…。
原文も軽く見ましたが、そっちにも書いてないのでそもそも記述されてません。

調べてもまだ中々情報が出てこない上に、クエリ投入時にエラーが出た場合もエラーメッセージが淡白すぎてどこが問題でエラーになってるのかさっぱりわからなくて悪戦苦闘してました。

そんなわけで、今後同じところで困る人が一人でも減るように、自分用メモも兼ねてハマったところについて補足をしておきたいと思います。

概要

リンク先で書いてあることの流れは大まかに下記のとおりです。

  1. FirehoseでSESの送信イベントログをS3に保存する
    送信イベントログはjson形式で、それをFirehoseでS3に保存しています。
  2. Athenaのテーブルを作成して、クエリを投げる
    • ただテーブル作成して投げる場合
    • 入れ子になっているjsonに対してテーブル作成してクエリを投げる場合
    • 禁止文字を含んでいるものに対してテーブルを作成してクエリを投げる場合
      わかりづらいですが、禁止文字を含む項目をマッピングする項目とクエリを投げる項目が分かれています。)
  3. hive-json-schemaの紹介
    jsonからテーブル作成のためのクエリを生成するツールっぽいのですが、紹介してるわりにちっとも使い方が書いてません…。
    使い方の解説をどなたか…。

ハマったところ

入れ子になったjsonに対するテーブル作成について

ハマったところといいつつ、自分はこの辺は割とスムーズに行ったのですが、ちょっとわかりづらいかもしれないので念のため。
サンプルにもありますが、jsonの中にまたjsonとか配列とかが入っている、みたいなケースは多くあります。
そういった場合、内部にあるjsonに対してstruct型を使って、その下の項目について型を定義してやればOKです。
その中にさらにjsonがある場合はさらにその中にstruct型で定義をすればOK。
例にあるものだと、内部にmail{~}とjsonがあり、その中にさらにいくつかのjsonがあるので、それぞれに対してstruct型で定義をしています。
以下引用(全文は貼っていないので、元はリンク先を見てください。)
※一部バッククオート(`)で囲われている項目がありますが、予約語として使われている言葉をそのまま使用するとエラーになるそうです。
そのため、バッククオートで囲うことによってエスケープしてるようです。

抜粋した入れ子の部分
 mail struct<`timestamp`:string,
              source:string,
              sourceArn:string,
              sendingAccountId:string,
              messageId:string,
              destination:string,
              headersTruncated:boolean,
              headers:array<struct<name:string,value:string>>,
              commonHeaders:struct<`from`:array<string>,to:array<string>,messageId:string,subject:string>
              > 

禁止文字そのものについて

まず、禁止文字が色々あることを最初大して理解してませんでした。
項目名(↑の例だと、timestampとかsourceとかのところ)の定義に使用できない文字があります。
記事中だと「:」(コロン)が禁止文字列なので、それがクエリ中の該当箇所に入っているとエラーになります。
あとは「-」(ハイフン)なんかも禁止文字のようです。
例えばHTTPリクエストのログを見たとき、ヘッダとかはハイフンを使った項目がいくつもあったりするので困りますよね。
一応記事中の例では両方「_」(アンダースコア)に変換しています。(コロンにしか触れてませんが…。)
最初は禁止文字があると知らず、なぜエラーになっているかわからずにハマってました。
この辺どっかにまとまってるのかな…?
どうやって回避するかというと、それがWITH SERDEPROPERTIESの部分です。

禁止文字を含む場合のマッピングの仕方について

最初見た時はなんでこんなことをするのかわかりませんでしたが、上記の通り項目名を定義するときに禁止文字が入っているとエラーになります。
なので、WITH SERDEPROPERTIESの項目で、禁止文字列を含んだ項目名を、禁止文字列のない文字列にマッピングし、元のjsonのkeyでは禁止文字列を含んでいたものに対し、テーブル上ではカラム名として別の文字列をあてがうことができます。
記事中では、コロンやハイフンをアンダースコアに変換した文字列にマッピングしています。
式の左側がカラム名に使いたい文字列で、それに対して右側がデータの元の実際の名前です。
"mapping.カラム名に使いたい文字列"="実際の名前" みたいに記述してます。

マッピングの仕方

WITH SERDEPROPERTIES (
  "mapping.ses_configurationset"="ses:configuration-set",
  "mapping.ses_source_ip"="ses:source-ip", 
  "mapping.ses_from_domain"="ses:from-domain", 
  "mapping.ses_caller_identity"="ses:caller-identity"
  )

クエリの投げ方

これもまあおまけで書いておくと、ここまでしっかりと下の項目までテーブルを定義しておくと、下の項目までクエリで引っ張ることが出来ます。
記事中では下記のような例が出ています。

元記事にある例
SELECT eventtype as Event,
         mail.timestamp as Timestamp,
         mail.tags.ses_source_ip as SourceIP,
         mail.tags.ses_caller_identity as AuthenticatedBy,
         mail.commonHeaders."from" as FromAddress,
         mail.commonHeaders.to as ToAddress
FROM sesblog2
WHERE eventtype = 'Bounce'

mail{〜}の下の項目を参照する時は上記のようにドットをつけて該当項目の名前を指定しています。
さらにその下の項目を参照する時はその後ろにさらにドットをつけています。
この辺は直感的にわかりやすいかもしれません。

おまけとかtipsとか

Firehoseで配置されたフォルダ構成ではパーティションを自動で切ってもらえない

hiveではフォルダが/bucketname/path/to/log/year=YY/month=MM/day=dd/foo
みたいな構成だと自動でパーティション設定してくれるらしいのですが、FirehoseでS3にデータ配置すると/bucketname/path/to/log/YYYY/MM/DD/fooみたいになるので、自分でパーティションを作成する必要があります。
パーティションがない状態でクエリを投げても1件も引っかかりません。
これを作るには下記のようなクエリを投げる必要があります。

elbログを対象としたテーブルにパーティションを作成する場合
ALTER TABLE database_name.table_name
ADD PARTITION (year='2016',month='08',day='28')
location 's3://elb-access-log/AWSLogs/00000000000000/elasticloadbalancing/ap-northeast-1/2016/08/28/';

※参考
https://qiita.com/r4-keisuke/items/d3d339b76d4368b6b30a

上記の例だと1日ずつパーティションを設定する必要があるのですが、
パーティション数には上限があるらしい(1テーブル20000まで)ので、1日ずつとか、1時間ずつとかフォルダ分けしている場合はちょっと注意が必要かもしれないです。
※パーティションの上限については下記
https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html#limits_glue
さすがに対象が多すぎとなるとしんどいので、シェルスクリプトとかで回すといいと思います。
ただ、シェルスクリプト自体も1つ1つの処理実行だとそこそこ時間かかるのと、パーティションを設定するためのクエリでクエリ履歴が埋め尽くされるのが難点です。

データ元にない項目を定義しても値がnullになるだけで問題はない

jsonの出力が一定じゃなくて、いくつかの似たような型のjsonが混ざっていたり、ものによって存在しない項目があったりしても、それらのキーを全て網羅するようにまとめて定義しちゃって問題ないみたいです。
定義したけどデータ元に項目がない場合はnullが入るだけのようで。
逆に元データにある項目を全部定義する必要はないので、元データにあっても使わないような項目はテーブル作成の段階で定義しないようにしてもいいみたいですね。

ざっと書いたので、わかりづらいとか、もっとこうすればみたいな指摘があればいただけると嬉しいです。

続きを読む

AWS CLIに複数のAWSアカウントを登録する方法

複数のAWSを利用するプロジェクトに携わっている場合、複数のAWSアカウントをCLIで操作する可能性が出てきます。
Secret Keyは作成時しか見えませんので、毎回AWSにログインしてSecret Keyを作り直すこともナンセンスです。
本記事では、AWS CLIに複数のAWSアカウントを登録し、再度configする手間を省く方法をまとめます。

AWS CLIのインストール

AWSの公式ドキュメントを参考にinstallを行います。
https://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html

初期設定

defaultで利用するアカウントを登録します。

$ aws configure
AWS Access Key ID [None]: ${Your Default ID}
AWS Secret Access Key [None]: ${Your Default Secret Key}
Default region name [None]: ${Region}
Default output format [None]: json

AWS CLIに複数のアカウントを登録する

AWS CLIは–profileオプションを利用することで、複数のアカウントを登録することが可能です

$ aws configure --profile xxxx
AWS Access Key ID [None]: ${Your ID}
AWS Secret Access Key [None]: ${Your Secret Key}
Default region name [None]: ${Region}
Default output format [None]: json

では、どのようにcredentialなどは登録されているのでしょうか。
AWS CLIのconfig、およびcredentialを保存しているfileを確認してみましょう。

~/.aws
$ tree ~/.aws
.aws
├── config
└── credentials

まずはconfigから確認してみましょう。

~/.aws/config
[default]
output = json
region = ap-northeast-1
[profile xxxx]
output = json
region = ${Region}

[profile xxxx]といった項目が追加され、先ほど入力した情報と同様の情報が格納されていることが確認できます。
credentialsの方も確認してみましょう。

~/.aws/credentials
[default]
aws_access_key_id = ${Your Default ID}
aws_secret_access_key = ${Your Default Secret Key}
[xxxx]
aws_access_key_id = ${Your ID}
aws_secret_access_key = ${Your Secret Key}

こちらも先ほど入力した情報と同様の情報が格納されていることが確認できました。

AWS CLIの利用方法

–profileオプションを利用することによって、~/.aws以下に保存されている情報から、–profileの引数と同様の項目からkeyなどの情報を参照して利用します。
以下の例は、s3バケットの一覧をアカウントを変えて表示させています。
アカウントが変わることで、s3のバケットが変更されるのがわかると思います。

s3バケットの一覧が変更されていることを確認
$ aws s3 ls
$ aws s3 ls --profile xxxx

まとめ

今回はAWS CLIに複数のAWSアカウントを登録する方法をまとめました。
最近はAWS CLIだけではなく、Serverless frameworkやterraformを利用した構築方法もありますので、そちらの方も随時まとめていけたらと思います。

続きを読む

Cognitoの説明に使われている言葉を整理する

はじめに

Cognitoを使ってみようと思って色々読んだけど、認証周りは全くど素人なのでわからない言葉を調べてみたメモです。

Cognitoとは何か

AWSのAmazon Cognito とはに書いてある通り。この中で

  • Amazon Cognito とは
  • Amazon Cognito の機能

に書いてある言葉でわからなかったものを整理する。こちらも参考にさせていただきました。

ユーザディレクトリとは何か

大きめな会社でWindowsを使ったりしていると「Active Directory」という名前を聞いたことがあるかもしれないが、似たようなもの、と理解した。前述のAWSのAmazon Cognito とはにもあるが、ユーザディレクトリは以下の機能を提供、管理する。

  • ユーザの追加方法を提供する(サインアップ)
  • サインアップに必要な情報、ステップを定義できる
  • ユーザの認証方法を定義できる(サインイン)
  • サインアップ/サインイン処理の代替をさせるCognito以外のサービスを設定できる(外部IDプロバイダー)

Amazon Cognito User Poolとは何か

ユーザディレクトリを実現するための機能の名称。Connection Poolとかと同じ、ユーザをpoolする。コンソールでUserPoolを作ってみるとわかるが、作成時に上記のユーザディレクトリで提供、管理するパラメタの設定を行う。あとから編集も可能。

外部IDプロバイダとは何か

これも前述のCognitoの説明ページにある通り、FacebookやTwitterやAmazonなどのCognitoの外部にあるアカウント情報を提供するサービスをAWSの説明ではこう呼んでいる様子。自社システムですでにアカウント管理を実装済みの場合、それも「Cognitoからみたら外」になるので外部IDプロバイダになるが、SAMLに対応していないと外部IDプロバイダーとして登録できない。

移行したいときどうするんだろう?要調査。

注意

CognitoコンソールでUser Poolの設定画面に「フェデレーション」メニューと「IDプロバイダー」という項目があるが、後述の「Amazon Cognito フェデレーテッドアイデンティティ」とは別もの。「外部IDプロバイダー」を設定するだけであり、フェデレーテッドアイデンティティ側の設定には何も影響しない。(はず)

スクリーンショット 2018-01-03 13.06.22.png

Amazon Cognito フェデレーテッドアイデンティティとは何か

ふぇでれーてっどって何??ということでアルクで調べた。

federation 【名】
連邦[連合・連盟]化[加入]◆【用法】不可算名詞
連邦、連合、連盟◆国家や組合などが独自の組織を維持しながら構成する連合体。
federated 【形】
連合[連盟]した、連邦制になった

ふむ。JAFのFやFIFAの最初のFの「Federation」の形容詞か。

で、これはCognito UserPoolまたは外部のアカウント情報を提供するサービス(FBやTwitterなど)の認証情報を使い、一意なIDを割り当てる&そのID任意のアクセス権限(=IAMロール)を付与することができる機能の様子。認証前と後で異なるアクセス権限を割り当てることができる。
Federated Identityの1つ1つを管理する器を「ID Pool」と呼んでおり、ID pool単位で以下を提供、管理する。

  • 認証前後に与えるロールの設定
  • 「認証済/未済」をどの「認証プロバイダー」に提供してもらうかの設定
  • 「プッシュ型」データ同期の要否(未対応言語あり。注意。)
  • Kinesisストリームとの連携(Cognitoストリーム。よくわかってない)
  • Sync Trigger時のLambdaの呼び出し設定

注意

Federated IDの認証プロバイダーはUser Poolの外部IDプロバイダーよりも選択肢が広い。こちらの場合、自社サービスの認証情報を流用するにあたってSAMLなどに対応する必要はない。(「カスタム」認証プロバイダーでは、クライアントアプリ側の実装で責任を持ってtoken発行を行うのでSAML対応などは不要になる)

Amazon Cognito Syncとは何か

Federated IDに紐づいた データの同期を行える機能。UserPoolのユーザ単位ではない。AWSのCognito Syncの説明ではFederated ID=Cognito IDとして書かれているので注意! :(

key-value型のデータセットを同期させることができ、1セット1MB, 20個まで1つのFederated IDに紐づけることができる。AWSのCognitoサービスをマスターとし、インターネットに繋がっているクライアント同士でデータ同期することができる。同期トリガーは同期メソッドを各クライアントから呼び出す。AWS側からプッシュするパターンの同期もID Poolの設定によっては可能だが、対応していない言語があるので注意。オフライン時のデータ更新も考慮されている。

よもやま

名前分かりにくいなぁ

名前 意味
外部IDプロバイダー Cognito User Pool においてCognito以外で認証機能を提供するサービス
Federated Identity (Federated ID) 前述の機能名、またはそれで発行したID1つ1つ
ID pool Federated IDを管理、設定するPool
認証プロバイダー Federated IDの付与に使われる「認証済/未済」を提供するサービス

続きを読む

AWS SAMとServerless Frameworkを比較してみた

この記事はServerless Advent Calendar 2017 23日目の記事です。

最近Serverless Frameworkを使っていたのですが、先輩に「今の時代はAWS SAMだぞ」と言われ、気になったので比べてみました。

Serveless Frameworkの特徴

デプロイしやすい・速い

まずこれが一番の特徴ですね。
下記の例みたいにたったコマンド2つですぐ動かせるサーバーレスアプリケーションが出来上がります。

$ serverless create --template hello-world
$ serverless deploy

もし↑と同じことSAMでやろうとした場合:

  • リリースステージ用のバケットの作成
  • Lambda関数のコーディング
  • 設定ファイルを書く
  • Lambda関数のzip化
  • Cloudformationによるパッケージング

これらの作業を全て自分でやらなければなりません。
Serverless Frameworkを使うとこういったデプロイ前の準備作業をよしなにやってくれますね。

まぁスクリプトやらCIでそこは解決できるとは思いますが、そもそもそこに時間や手間をかけずに自分のアプリケーションだけに集中したい人であれば、Serverless Frameworkの方が圧倒的に使い勝手が良いのではないでしょうか。

連携可能なサービスが豊富

Serverless FrameworkはAWSだけでなく、Azure FunctionsやGoogle Cloud Functionsなど他社のクラウドサービスでも利用できます。
もちろんそれぞれのサービスの仕様や特性をある程度把握した上で利用するべきですが、Serverless Frameworkから利用する部分に関してはほぼ変わりません。
特にデプロイはどのサービスも同じコマンドでできます。

$ serverless deploy

様々なプラグインが利用できる

Serverless Frameworkは使い勝手がとても良いのですが、もちろんまだ足りない部分や痒い所に手が届かないときもあったりします。そういう時はプラグインで補ったりすることができます。
例えば、デプロイしたファンクション毎にDead letter queueをserverless-plugin-lambda-dead-letterで設定できたり、Serverless Frameworkの定義ファイル内でStep Functionsの設定を可能にするserverless-step-functionsなどがあります。
Serverless Frameworkのコミュニティ自体が大きいので、様々なプラグインが多数みつかるのも良い点だと思います。

AWS Serverless Application Modelの特徴

AWS関連サービスとの親和性が高い

Cloud Formationを拡張したサービスなので当たり前かもしれませんが、AWSリソースとの連携がしやすい印象でした。
もしすでにCloud Formationを使ってきた方であればあまり不自由なくSAM利用できるでしょう。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  PutFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs6.10

このように通常のCloudFormationのテンプレートに Transform: AWS::Serverless-2016-10-31 と1行追加すれば、SAMのテンプレートフォーマットを利用することができます。

ローカル環境でのテストが可能

事前にDockerのインストールが必要になりますが、AWS SAM Localをインストールすればローカル環境でのファンクションのテストが可能になります。

$ npm install -g aws-sam-local

以下のように実行したいファンクション名と渡したいリクエストのボディをjsonで指定するとテストが可能になります。

$ sam local invoke "FunctionName" -e event.json

また、Lambdaを起動するイベントのペイロードもエミュレートできます、以下が対象サービスです:

  • S3
  • Kinesis
  • DynamoDB
  • Cloudwatch Scheduled Event
  • Cloudtrail
  • API Gateway

生成したイベントのペイロードをローカルで起動するファンクションに以下のようにパイプラインで渡すことができます。

$ sam local generate-event s3 --bucket bucket-name --key xxxxx | sam local invoke "FunctionName" 

※ Serveless Frameworkもserverless-dynamodb-localserverless-offlineというプラグインをインストールすればローカルでのテストも可能ですが、独自の設定が必要な上Node.js限定という欠点があります。

まとめ

すこしサクッとさわってみて比べた印象ですが、今後他のクラウドサービスに切り替えたいかもしれない時やとにかくスピード重視でアプリケーションを動かしたいのであればServerless Frameworkがいいと思います。
もしアプリケーションをAWSのサービス中心で構成し、それなりに長く運用していくのであればAWS SAMが適しているかもしれません。
ただ、「アプリケーションを素早く本番運用できる状態にし、またサーバーやそれに関連するサービスの運用にかける時間をアプリケーションのコーディングに割り当てることを可能とし、ユーザーにより価値のあるサービスを提供する」といったサーバレスの思想に一番近いのはServerless Frameworkではないでしょうか。

続きを読む