Slide 1

Slide 1 text

PyCon JP 2019 Tutorial Lambda(Python)を使用したサーバーレスのハンズオン 1

Slide 2

Slide 2 text

本日はよろしくお願いいたします 2

Slide 3

Slide 3 text

WiFi こちらのWiFiをお使いください 3

Slide 4

Slide 4 text

講師およびチュータの紹介 ● 阿部 信介 ○ CX事業本部 エンジニアチームオーガナイザー 兼 プロダクトマネージャ ○ メイン講師担当 ● 夏目 祐樹(ゆうた) ○ CX事業本部 サーバーサイドエンジニア ○ チュータ担当 ● 藤井 元貴 ○ CX事業本部 サーバーサイドエンジニア ○ チュータ担当 ● 加藤 諒 ○ CX事業本部 サーバーサイドエンジニア ○ チュータ担当 4

Slide 5

Slide 5 text

クラスメソッドについて Developers.IOを運営している会社です。 5

Slide 6

Slide 6 text

クラスメソッドについて(事業目線) ● AWSに関するあらゆる支援がメインの事業です ○ アカウントリセール ○ オンプレからクラウドへのマイグレーション ○ AWS上でのシステム構築 ○ データ分析基盤の構築 ○ etc ● カフェを運営しています ○ 完全キャッシュレス/ウォークスルー決済 ○ 技術的な実験を行うための店舗 6

Slide 7

Slide 7 text

クラスメソッドについて(働く人目線) ● 働きやすさを支える各種制度があります ○ フレックスタイム ○ リモートワーク ○ 男性社員も積極的にとる育休 ● 技術が好きなエンジニアが集まっています ○ AWSの新サービスを積極的に試してブログにアウトプット ○ 試したことを活用する機会も多数 ○ 技術に関する雑談も活発 ○ フットワーク軽く試せるように AWSのアカウントなど支援あり ● 拠点は採用によって増えます ○ 東京/大阪/札幌/福岡/上越/沖縄/岡山/ベルリン/バンクーバー ○ 3人以上採用できればオフィスができます 7

Slide 8

Slide 8 text

会社説明会を開催しています 9/19(木)CX事業本部フォーカスの会社説明会を行います。 今回のチュートリアルでサーバーレスが気になった方、ぜひご検討ください。 8

Slide 9

Slide 9 text

免責事項 ● 本日のカリキュラムの内容は、現時点でのAWSのサービス仕様 にのっとって構成されています。今後、AWSのサービス仕様が変更になって もこの内容が保証される訳ではありませんのでご注意ください。 ● Pythonの言語仕様に対する深い質問については答えられない可 能性があります。その代わり、今回利用するAWSのサービスとサーバーレスにつ いてはお任せください。 9

Slide 10

Slide 10 text

本日のタイムテーブル ● 13:00〜13:20 はじめに ● 13:20〜14:00 Lambdaについての説明 ● 14:00〜14:10 休憩 ● 14:10〜14:50 Lambdaを始める(ハンズオン1) ● 14:50〜15:00 休憩 ● 15:00〜16:00 サーバーレスアーキテクチャとLambdaの位置付け ● 16:00〜16:10 休憩 ● 16:10〜18:20 サーバーレスアプリケーションを作ってみる(ハンズオン2) ● 18:20〜19:00 クロージング 10

Slide 11

Slide 11 text

本日のチュートリアルのゴール 1. AWS上で構築するサーバーレスアプリケーションの基本構成について知る 2. Lambdaの利用に十分な構成について知る 3. AWSの基本的なマネージドサービスを使って、サーバーレスなAPIを構築する手順を知 る 11

Slide 12

Slide 12 text

Lambdaについての説明 12

Slide 13

Slide 13 text

AWS Lambdaとは ● FaaS(Function as a Service)の一つ ● AWS上のカテゴリーは「コンピューティング」 ● マネージされたコード実行環境を提供 AWS Lambda 13

Slide 14

Slide 14 text

AWS Lambdaの基本的な機能 ● 共有されたステートレスな実行環境 ● AWSの各種サービスとの連携(INPUT/OUTPUT) ● 耐障害性の高いリージョンサービス(VPC Lambdaもあ る) ● 柔軟なスケーリング ● 関数のバージョニング ● CloudWatchによる監視 ● StepFunctionsによる関数間オーケストレーション ● Lambda Layerによる共通コンポーネントの管理 AWS Lambda 14

Slide 15

Slide 15 text

AWS Lambdaで利用可能な言語について ● Python ● Node.js ● Go ● PowerShell ● Java ● C# ● Ruby ● カスタムランタイムで任意の言語も使用することが可能 AWS Lambda 15

Slide 16

Slide 16 text

AWS Lambdaの利点 ● コンピューティングリソースの有効活用 ○ アイドルタイムに課金されない ○ 実行環境はAWSによってメンテナンスされるので、管理コストも 最適化できる ● アプリケーションコードのスケーラビリティ ○ 冪等性は必要 ○ 事前のリソースプロビジョニングが不要になる (基本) ● AWSの各サービスとの親和性 ○ イベントドリブンによる自動化やサーバーレス化に取り組みやす い AWS Lambda 16

Slide 17

Slide 17 text

AWS Lambdaの制約 ● 公式ドキュメント ○ 同時実行数 1000 ○ 関数とレイヤーストレージ 75GB ○ 関数のメモリ 128MB〜3008MB ○ 関数タイムアウト 15分 ○ デプロイパッケージサイズ 50MB ● 実行環境は基本共有されないプログラミングモデル ○ スタンバイしてる環境を引き当てることもある ○ ガチャなので、それを引くことを期待する作りにはしない AWS Lambda 17

Slide 18

Slide 18 text

AWS Lambda Functionの実行ライフサイクル 1. ENIの作成 2. コンテナの作成 3. デプロイパッケージのロード 4. デプロイパッケージの展開 5. ランタイム起動・初期化 6. 関数/メソッドの実行(コンピューティングの課金対象) 7. コンテナの破棄 AWS Lambda 出典:https://www.slideshare.net/AmazonWebServicesJapan/20190402-aws-black-belt-online-seminar-lets-dive-deep-into-aws-lambda-part1-part2 18

Slide 19

Slide 19 text

コールドスタートとウォームスタート ● ライフサイクルの1から全て実施するのがコールドスタート ● コンテナを再利用して実行されるのがウォームスタート ● 利用可能なコンテナがない場合はコールドスタートになる ○ コードや設定を変更した場合もコンテナは利用できなくなる 出典:https://www.slideshare.net/AmazonWebServicesJapan/20190402-aws-black-belt-online-seminar-lets-dive-deep-into-aws-lambda-part1-part2 19

Slide 20

Slide 20 text

AWS Lambda Functionの実行ライフサイクル 1. ENIの作成 2. コンテナの作成 3. デプロイパッケージのロード 4. デプロイパッケージの展開 5. ランタイム起動・初期化 6. 関数/メソッドの実行(コンピューティングの課金対象) 7. コンテナの破棄 AWS Lambda 出典:https://www.slideshare.net/AmazonWebServicesJapan/20190402-aws-black-belt-online-seminar-lets-dive-deep-into-aws-lambda-part1-part2 コールドスタートの場合の実行サイクル 20

Slide 21

Slide 21 text

AWS Lambda Functionの実行ライフサイクル 1. ENIの作成 2. コンテナの作成 3. デプロイパッケージのロード 4. デプロイパッケージの展開 5. ランタイム起動・初期化 6. 関数/メソッドの実行(コンピューティングの課金対象) 7. コンテナの破棄 AWS Lambda 出典:https://www.slideshare.net/AmazonWebServicesJapan/20190402-aws-black-belt-online-seminar-lets-dive-deep-into-aws-lambda-part1-part2 ウォームスタートの場合の実行サイクル 21

Slide 22

Slide 22 text

Lambdaの利用例 (典型的なアーキテクチャ) 22

Slide 23

Slide 23 text

APIサーバーとして ● API Gatewayと組み合わせてAPIサー バーを構成する ● API GatewayからLambdaをトリガーす る ● CloudFront + S3で静的ページ(SPA) からAPIをキックしてサーバーレスで Webページを構成するというのもよくや る CloudFront S3 API Gateway Lambda DynamoDB 23

Slide 24

Slide 24 text

AWSリソース管理の自動化 ● AWSの各サービスからのイベントをトリ ガーにしてAWSリソースを操作する ● Lambdaの実行環境にはAWS SDKが インストールされている ● Lambdaのトリガーに直接なれるものと なれないものもあるが、CloudWatch Eventsなどを経由してイベントを起こす ことは可能 S3 CloudWatch Events Lambda SNS SNS CloudFormation 24

Slide 25

Slide 25 text

IoTサービスのバックエンドとして ● AWS IoT Core(Kinesis Streamの場合 もある)でデバイスサイドからのデータを 受けて、Lambdaをトリガーする Lambda S3 DynamoDB IoT Core 25

Slide 26

Slide 26 text

ストリームデータのバックエンドとして ● 基本的にはIoTのバックエンドの構成と 同じ ● IoTのケースも同じだが、Lambdaをキッ クした後は、データ蓄積からETLへの発 展という形が多い Lambda DynamoDB S3 Kinesis Data Streams 26

Slide 27

Slide 27 text

ETL処理 ● 発生したデータをトリガーにして変換を 行う ● 変換後のデータはBIツールなどのソー スになる ● データ発生がイベントとなることが多く、 常時コンピューティングリソースを必要と しないケースが比較的多いので向いて いる ● データのスケールにも対応しやすい(設 計次第) S3 S3 Lambda DynamoDB Athena 27

Slide 28

Slide 28 text

休憩(10分) 28

Slide 29

Slide 29 text

Lambdaを始める (ハンズオン1) 29

Slide 30

Slide 30 text

ハンズオン前の諸注意 1. 最後に環境の削除をします a. 今日作成したもののダウンロードは削除手順に含めています b. 削除し忘れがあった場合、 Cloud9をホストしているEC2やEBSの利用料がかかるのでご注意ください 2. 質問は適宜チュータにお願いします a. いただいた質問の内容によっては最後に他の参加者と共有します 30

Slide 31

Slide 31 text

Lambdaの開発でよく利用されるツール群 ● 構成管理 ○ SAM(CloudFormation)およびSAM CLI ○ AWS CDK(Cloud Developement Kit) ● AWS SDK ○ boto3(AWS SDK for Python) ● AWSサービスのモックツール ○ LocalStack ○ moto ● API仕様書の記述 ○ OpenAPI(Swagger) 31

Slide 32

Slide 32 text

SAMについて ● AWS Serverless Application Model ● サーバーレスアプリケーション構築のためのフレームワーク ● CloudFormationの拡張として実装されていて、構成管理まで含まれる ○ デプロイ時にはCloudFormationに変換してスタック構築が実施される ● 専用のコマンドラインインターフェイスあり(AWS SAM CLI) 32

Slide 33

Slide 33 text

boto3について ● AWS SDK for Python ● LambdaのPythonランタイムにはインストールされている ○ AWS Lambda 関数を使用する際のベストプラクティス ○ プロダクションコードで採用する場合は、 AWSからアップデートされて挙動が変わる場合も踏まえてバー ジョンを指定してデプロイパッケージに含める運用も考慮する必要がある ● AWSのリソースへのアクセス、APIの実行などを担当する 33

Slide 34

Slide 34 text

ハンズオン1 1. Cloud9環境を用意する 2. SAMで雛形を作る 3. ローカル環境でテストを流す 4. デプロイ 5. Lambdaを動かす 34

Slide 35

Slide 35 text

Cloud9について ● AWSが提供しているクラウド上でのアプリケーション開発環境 ● コードエディタと開発環境がWeb上から使える ○ AWS CLIとAWS SAM CLIはインストール済み ○ 基本的な言語環境もインストール済み ● 作成するとEC2が立ち上がる ○ 本ハンズオン終了後の扱いに注意 ● Lambdaの開発において必須ではないが、今回は環境を揃えるために使用 35

Slide 36

Slide 36 text

Cloud9の環境準備 1. Create Environmentをクリック 2. Nameを入力(例:”My First Lambda”) 3. その他項目はデフォルトでNext Stepをクリック 4. 内容を確認してCreate Environmentをクリック 36

Slide 37

Slide 37 text

Cloud9の環境準備 37

Slide 38

Slide 38 text

Cloud9でPython3系を使う準備をする 1. Cloud9の環境はデフォルトでPython 2.7系にパスが通っています 2. cdを実行 3. .bashrcのalias python=python27をalias python=python36に変更 4. source .bashrcを実行 5. sudo update-alternatives --config pythonを実行して2を選択 6. python --versionとpip --versionを実行してバージョンを確認 38

Slide 39

Slide 39 text

SAMで雛形を作る 1. 画面下部のターミナルでsam init -r python3.6を実行 39

Slide 40

Slide 40 text

SAMのアプリケーション構成 1. hello_world/app.py:Lambda関数 2. test/unit/test_handler.py:Lambda関数のテス トスクリプト 3. template.yaml:SAMの構成ファイル 40

Slide 41

Slide 41 text

各ファイルを見てみましょう(app.py) 1. 6行目:Lambdaのハンドラーになる関数の引数は決まっています a. event:イベントソースになるサービスなどにより構成が異なります。詳細は AWSのドキュメント(他のサービ スで AWS Lambda を使用する)で確認してください。 b. context:Lambdaのランタイムからのコンテキスト情報などがセットされます。 2. 74〜80行目:Lambda内で実行する処理を書きます。boto3は実行環境にインストール されているので使えます。 3. 82〜87行目:Lambda関数が後続の処理に返す処理結果を記載します。どのサービス と連携するかによって戻り値の構成は異なります。 41

Slide 42

Slide 42 text

各ファイルを見てみましょう(test_handler.py) 1. 9〜63行目:テスト用のイベントソースを生成しています 2. 66〜81行目:pytestを利用したLambda関数のテストコードです 3. サンプルコードはAWSリソースに接続していないため、モックなどは必要ありません 42

Slide 43

Slide 43 text

各ファイルを見てみましょう(template.yaml) 1. 16〜30行目:Lambda関数とそのイベントソースに関する設定です a. Type::Serverless::Function:SAMで設定可能なLambda関数のリソースタイプです。他に利用可能な リ ソースタイプはAWSのドキュメント(AWS サーバーレスアプリケーションモデル (AWS SAM) の使用)をご確認ください。 b. CodeUri:Lambdaのコードが展開されているデプロイされたディレクトリのルートです。 c. Handler:Lambda関数のパスです。フォルダ名(複数あってもOK).関数名でセットされます。 d. Events:Lambda関数を実行するイベントソースです。サンプルでは Apiがセットされ、API Gatewayとの 統合が指定されています。 2. 32〜44行目:CloudFormationスタックのアウトプットです。 43

Slide 44

Slide 44 text

テストを実行してみましょう 1. カレントディレクトリを~/environment/sam-appに変更 2. sudo pip install pytest requests pytest-mockを実行 3. python -m pytest tests/ -vを実行 4. テストがパスしていることを確認 44

Slide 45

Slide 45 text

デプロイしてみましょう 1. カレントディレクトリを~/environment/sam-appに変更 2. aws s3 mb s3://皆さんで決めてください --region ap-northeast-1を実行(初回のみ) 3. sam buildを実行 4. sam package --output-template packaged.yaml --s3-bucket 2で決めたバケット 名を実行 5. sam deploy --template-file /home/ec2-user/environment/sam-app/packaged.yaml --capabilities CAPABILITY_IAM --stack-name lambda-tutorial-sample-app --region ap-northeast-1を実行 6. CloudFormationのスタックの状況を確認 45

Slide 46

Slide 46 text

APIを実行してみましょう 1. aws cloudformation describe-stacks --stack-name lambda-tutorial-sample-app --region ap-northeast-1 --query "Stacks[].Outputs" でスタックの出力を確認 2. "OutputKey": "HelloWorldApi"のレコードのOutputValueに記載されているエンドポ イントURLをクリック 3. 結果が表示されることを確認 46

Slide 47

Slide 47 text

休憩(10分) 47

Slide 48

Slide 48 text

サーバーレスアーキテクチャと Lambdaの位置付け 48

Slide 49

Slide 49 text

サーバーレスアーキテクチャとは ● Martin Fowlerブログより ○ Serverless Architecutreは、サードパーティの BaaS(Backend as a Service)を盛り込んで、カスタムコード の実行管理に一時的なコンテナで動く FaaS(Functions as a Service)を含むアプリケーションデザインで ある。 ● 物理サーバやミドルウェアおよびOSレベルでのサーバの管理を行わない(クラウドベン ダーに任せる)アーキテクチャ ● 関数やインフラの実行環境を動いている間だけ利用するアプリケーション実行プラット フォームの構成の仕方に対するワード ● 各クラウドベンダーのマネージドサービスを活用するため、アプリケーションの仕様がベ ンダーロックインしやすい 49

Slide 50

Slide 50 text

サーバーレスアーキテクチャが狙うもの ● リソースのランニングコスト最適化 ● プラットフォーム管理コストの削減 ● (アプリケーション側からの)リソースプランニング、プロビジョニングの簡略化 50

Slide 51

Slide 51 text

AWS上での実現 ● フルマネージドなサービス群を積極活用してサービスを構成する ● 各マネージドサービスが発生させるイベントを介して他のサービスを連動させることに よってサービスが形作られる ● アプリケーションコードが必要な部分はLambda(FaaS)サービスを利用する ○ サーバーレスアプリケーションはコードを書くポイントを局所化する 51

Slide 52

Slide 52 text

サーバーレスアーキテクチャでのLambdaの利用 ● マネージドなコードの実行環境(FaaS)として利用 ● 各サービスのイベント間を埋める処理としてコードを記述 ○ ビジネスロジックでもあり、グルーコードでもある ● 非同期/ステートレスにイベントが実行されるので、冪等性の高い処理を志向する 52

Slide 53

Slide 53 text

Lambdaとともに利用されることが多いサービス ● API Gateway ● DynamoDB ● S3 ● CloudWatch(監視だけではなく、イベントソースとしても) ● CloudFront(SPAでサイトを構築する際の静的ファイルを展開するためのCDN) ● Kinesis Data Stream ● AWS IoT 53

Slide 54

Slide 54 text

APIサーバーとして ● API Gatewayと組み合わせてAPIサー バーを構成する ● API GatewayからLambdaをトリガーす る ● CloudFront + S3で静的ページ(SPA) からAPIをキックしてサーバーレスで Webページを構成するというのもよくや る 54

Slide 55

Slide 55 text

AWSリソース管理の自動化 ● AWSの各サービスからのイベントをトリ ガーにしてAWSリソースを操作する ● Lambdaの実行環境にはAWS SDKが インストールされている ● Lambdaのトリガーに直接なれるものと なれないものもあるが、CloudWatch Eventsなどを経由してイベントを起こす ことは可能 55

Slide 56

Slide 56 text

IoTサービスのバックエンドとして ● AWS IoT Core(Kinesis Streamの場合 もある)でデバイスサイドからのデータを 受けて、Lambdaをトリガーする 56

Slide 57

Slide 57 text

ストリームデータのバックエンドとして ● 基本的にはIoTのバックエンドの構成と 同じ ● IoTのケースも同じだが、Lambdaをキッ クした後は、データ蓄積からETLへの発 展という形が多い 57

Slide 58

Slide 58 text

ETL処理 ● 発生したデータをトリガーにして変換を 行う ● 変換後のデータはBIツールなどのソー スになる ● データ発生がイベントとなることが多く、 常時コンピューティングリソースを必要と しないケースが比較的多いので向いて いる ● データのスケールにも対応しやすい(設 計次第) 58

Slide 59

Slide 59 text

サーバーレスアーキテクチャでの鉄板パターン ● キューイングによる非同期処理 ○ Kinesis Data StreamやSQSなどを利用 ● SPA + APIの構成によるフロントエンドでのステート肩代わり 59

Slide 60

Slide 60 text

RDSが積極的に使われない理由について ● RDSのコネクション数はインスタンスサイズによって決まる ○ コネクションプーリングの仕組みがないため、そのままであればコネクションを各 Lambdaの実行プロセス ごとに作成する ○ 並列に実行されるため、コネクション枯渇問題が発生する可能性がある ● 大規模トランザクションを現実的に使えない ○ Lambdaの実行時間はMAX15分 ○ トランザクションが必要になる処理は別のやり方を検討する必要がある ● VPC Lambdaにはリージョンで使う場合に比べてオーバーヘッドが大きい ○ Lambdaはリージョンサービスで RDSはAZサービス ○ RDSのエンドポイントをVPC外に公開する手もあるが、セキュリティ的に推奨はできない ○ VPC Lambdaのコールドスタート速度改善がアナウンスされた ■ 【速報】もうアンチパターンとは呼ばせない!! VPC Lambdaのコールドスタート改善が正式アナウンスされました!! 60

Slide 61

Slide 61 text

RDSが積極的に使われない理由について ● RDSのコネクション数はインスタンスサイズによって決まる ○ コネクションプーリングの仕組みがないため、そのままであればコネクションを各 Lambdaの実行プロセス ごとに作成する ○ 並列に実行されるため、コネクション枯渇問題が発生する可能性がある ● 大規模トランザクションを現実的に使えない ○ Lambdaの実行時間はMAX15分 ○ トランザクションが必要になる処理は別のやり方を検討する必要がある ● VPC Lambdaにはリージョンで使う場合に比べてオーバーヘッドが大きい ○ Lambdaはリージョンサービスで RDSはAZサービス ○ RDSのエンドポイントをVPC外に公開する手もあるが、セキュリティ的に推奨はできない ○ VPC Lambdaのコールドスタート速度改善がアナウンスされた ■ 【速報】もうアンチパターンとは呼ばせない!! VPC Lambdaのコールドスタート改善が正式アナウンスされました!! これらの事情を踏まえた上で、回避しなければならない問題ではない場合は特に使っても構 わない。 61

Slide 62

Slide 62 text

サーバーレスアプリケーションを 作ってみる (ハンズオン2) 62

Slide 63

Slide 63 text

ハンズオン前の諸注意 1. 休憩は各自で適宜取りましょう 2. 最後に環境の削除をします a. 今日作成したもののダウンロードは削除手順に含めています b. 削除し忘れがあった場合、 Cloud9をホストしているEC2やEBSの利用料がかかるのでご注意ください 3. 質問は適宜チュータにお願いします a. いただいた質問の内容によっては最後に他の参加者と共有します 63

Slide 64

Slide 64 text

ハンズオンで使用する資料 1. pycon-serverless-tutorial.zip a. 今回使用するプロジェクトのスケルトン 2. api_specificatioin.md a. APIの仕様ファイル 3. 後ほどこちらで事前に作成している全コードを共有します 64

Slide 65

Slide 65 text

このハンズオンで作るもの 1. ファイルのアップローダ/ダウンローダAPIを作成 2. アップロードAPI a. APIからアップロード用の S3 Pre-signed URLとメタデータを取得 b. S3 Pre-signed URLを介してアップロード 3. リストアップAPI a. アップロードしたファイルのメタデータ一覧を取得 4. 画像更新用API a. APIからダウンロード用の S3 Pre-signed URLとメタデータを取得 b. S3 Pre-signed URLを介してダウンロード 5. ダウンロード用APIは割愛(自由課題) a. 他のAPIで実施する技術要素の中で対応可能なため 65

Slide 66

Slide 66 text

このハンズオンで作るもの(構成図) 66

Slide 67

Slide 67 text

このハンズオンの流れ 1. DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 2. ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 3. DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成と実 装 4. UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 5. (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 6. (ストレッチ)単体テスト 7. (ストレッチ)画像がアップロードされた際のサムネイル作成 8. (ストレッチ)E2Eテスト 9. (ストレッチ)Metrics FilterとSNS Topicでエラー通知 67

Slide 68

Slide 68 text

準備 1. sudo pip install pipenvを実行する 2. 配布したpycon-serverless-tutorial.zipをCloud9のプロジェクトにアップロードする 3. terminalでunzip pycon-serverless-tutorial.zipを実行する 4. terminalでsudo pip install boto3を実行する 68

Slide 69

Slide 69 text

リソースを作る 1. DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 2. ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 3. DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成と実 装 4. UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 5. (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 6. (ストレッチ)単体テスト 7. (ストレッチ)画像がアップロードされた際のサムネイル作成 8. (ストレッチ)E2Eテスト 9. (ストレッチ)Metrics FilterとSNS Topicでエラー通知 69

Slide 70

Slide 70 text

リソースを作る DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 a. sam.ymlにリソースを追加する b. DataBucket i. リソースタイプ:AWS::S3::Bucket ii. 通知設定:S3にオブジェクトが追加された時に SNSトピックに通知を行う c. DataTable i. リソースタイプ:AWS::Serverless::SimpleTable(SAMリソースでのDynamoDBテーブル) ii. キー項目:名前=>id、型=>string d. PutEventTopic i. リソースタイプ:AWS::SNS::Topic ii. その他設定:特になし e. PutEventPolicy i. リソースタイプ:AWS::SNS::TopicPolicy ii. 対象トピック:PutEventTopic iii. ポリシー設定:S3からPutEventTopicへのPublishを許可する 70

Slide 71

Slide 71 text

デプロイしてみましょう 1. カレントディレクトリを~/environment/pycon-serverless-tutorialに変更 2. pipenv install を実行 3. aws s3 mb s3://皆さんで指定 --region ap-northeast-1を実行(初回のみ) a. S3バケット名は全世界で一意である必要が 4. SAM_ARTIFACT_BUCKET=指定したS3バケット make deployを実行 5. CloudFormationのスタックの状況を確認 6. DynamoDBとS3バケット、SNSトピックが作成されていることを確認 71

Slide 72

Slide 72 text

リソースを作る(ふりかえり) 1. CloudFormationの基本的な書式 a. スタック上のリソース名 b. リソース種別 c. リソースの設定 2. スタック内でのリソースの参照の仕方 a. !Ref関数 3. Makefileの役割 a. ハンズオン1で見てきたように、デプロイまでには SAM -> CloudFormationのパッケージングからデプロイ の流れが必要 b. 毎回手順を繰り返すのは面倒なので、デプロイ手順を Makefileのタスクで実施する 72

Slide 73

Slide 73 text

APIリソースと初めての関数を作る 1. DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 2. ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 3. DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成と実 装 4. UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 5. (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 6. (ストレッチ)単体テスト 7. (ストレッチ)画像がアップロードされた際のサムネイル作成 8. (ストレッチ)E2Eテスト 9. (ストレッチ)Metrics FilterとSNS Topicでエラー通知 73

Slide 74

Slide 74 text

APIリソースと初めての関数を作る ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 a. 関数用のディレクトリを作成 i. src/CreateMetadataFunctionを作成する b. メタデータ作成の関数を作る i. index.py(Lambdaからコールされるハンドラ ) ii. metadata_creator.py(メタデータを作成するビジネスロジック ) iii. logger/get_logger.pyとlogger/json_formatter.py(ログ出力のためのユーティリティ ) c. API連携のリソースを作る i. リソースタイプ:AWS::Serverless::Api(SAMでのAPI Gatewayリソースタイプ) ii. ステージ名:パラメータの StageNameを指定 iii. CORS設定:全メソッド(GET/PUT/POST/DELETE/OPTIONS)に以下のヘッダーを許可 1. 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token' 74

Slide 75

Slide 75 text

APIリソースと初めての関数を作る ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 d. Lambda関数のリソースを作る i. リソースタイプ:AWS::Serverless::Function ii. CodeUri(デプロイされるソースのパス ):src/CreateMetadataFunction iii. Handler(Lambdaがコールするファイルとメソッド名 ):index.handler iv. Policies(Lambda関数が必要とするリソースへのアクセスポリシー ): 1. arn:aws:iam::aws:policy/AmazonS3FullAccess 2. arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess v. Events(Lambda関数のイベントソース ):PostMetadata 1. リソースタイプ:Api 2. Path(Rest APIのURL):/metadata 3. Method(HTTPメソッド):POST 4. RestApiId(どのAPIリソースに対してか):!Ref ApiResource e. ロググループを作る i. リソースタイプ:AWS::Logs::LogGroup ii. ロググループ名:${LambdaLogGroupNamePrefix}/${CreateMetadataFunction} 75

Slide 76

Slide 76 text

デプロイしてみましょう 1. SAM_ARTIFACT_BUCKET=[AWS CLIで作成したS3バケット] make deployを実行 a. 先ほどと同じコマンド(バケット名)で OKです 2. CloudFormationのスタックの状況を確認 3. Lambda関数とAPI GatewayのAPI、リソースと統合が作成されていることを確認 76

Slide 77

Slide 77 text

APIリソースと初めての関数を作る(ふりかえり) 1. APIリソースの書き方、CORS設定 a. スタック上のリソース名 b. リソース種別 c. リソースの設定 2. Lambda関数作成 a. ハンドラーとコアロジックの分離 (ベストプラクティス) b. boto3を使ったAWSリソースのアクセス i. Lambdaの実行環境にインストール済み ii. DynamoDBとS3へのアクセス c. API GatewayのLambdaプロキシ統合でのInput/Outputの取り扱い d. Lambda関数リソースの作成 3. ロググループについての補足 a. CloudFormationで明示的に作成しなくても良い b. CloudWatch LogsのFilter機能などを使ってエラー通知も可能 i. この場合、事前にLogGroupを作成しておく必要がある 77

Slide 78

Slide 78 text

S3バケットのイベントとロググループの設定をする 1. DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 2. ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 3. DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成 と実装 4. UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 5. (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 6. (ストレッチ)単体テスト 7. (ストレッチ)画像がアップロードされた際のサムネイル作成 8. (ストレッチ)E2Eテスト 9. (ストレッチ)Metrics FilterとSNS Topicでエラー通知 78

Slide 79

Slide 79 text

S3バケットのイベントとロググループの設定をする DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成 と実装 a. S3のPutイベントから起動する Lambda Functionを作成 i. src/PutS3EventFunctionを作成 ii. loggerはコピーする iii. src/PutS3EventFunctionをカレントディレクトリにして pip install pillowを実施 iv. index.py(Lambdaからコールされるハンドラ ) v. image_analyzer.py(画像からサイズ/横幅/縦幅を取得してDynamoDBのメタデータを更新する ) b. S3PutEventの設定 i. DataBucketのプロパティに以下を追加 1. NotificationConfiguration:通知設定 a. TopicConfigurations:SNSトピックへの通知 i. Event(S3の対象イベント):s3:ObjectCreated:* ii. Topic(イベント通知先のトピック ):!Ref PutEventTopic 79

Slide 80

Slide 80 text

S3バケットのイベントとロググループの設定をする DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成 と実装 c. Lambda関数のリソースを作る i. リソースタイプ:AWS::Serverless::Function ii. CodeUri(デプロイされるソースのパス ):src/PutS3EventFunction iii. Handler(Lambdaがコールするファイルとメソッド名 ):index.handler iv. MemorySize(Lambda関数に割り当てるメモリサイズ ):1024 v. Timeout(Lambda関数のタイムアウト):300 vi. Policies(Lambda関数が必要とするリソースへのアクセスポリシー ): 1. arn:aws:iam::aws:policy/AmazonS3FullAccess 2. arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess vii. Events(Lambda関数のイベントソース ):PutTopic 1. リソースタイプ:SNS 2. Topic(対象トピック):!Ref PutEventTopic viii. 注意事項:画像を扱うためにメモリサイズとタイムアウト値を調整 80

Slide 81

Slide 81 text

S3バケットのイベントとロググループの設定をする DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成 と実装 d. ロググループを作る i. リソースタイプ:AWS::Logs::LogGroup ii. ロググループ名:${LambdaLogGroupNamePrefix}/${PutS3EventFunction} 81

Slide 82

Slide 82 text

デプロイしてみましょう 1. SAM_ARTIFACT_BUCKET=[AWS CLIで作成した作成したS3バケット] make deployを実行 a. 先ほどと同じコマンド(バケット名)で OKです 2. CloudFormationのスタックの状況を確認 3. Lambda関数が作成されており、イベントソースがSNSになっていることを確認 82

Slide 83

Slide 83 text

S3バケットのイベントとロググループの設定をする(ふりかえり) 1. 依存する外部ライブラリの含め方 a. LambdaランタイムにはAWS SDKなど最低限のライブラリしかインストールされていない b. 依存する外部ライブラリを使用する場合はデプロイパッケージに含める必要がある i. Lambda Layerを使うケースもあり c. 今回のチュートリアルでは、デプロイする LambdaのディレクトリにPipenvを置いて依存関係をもち、 Makefile内でrequirements.txtを生成、デプロイパッケージとしてデプロイしている 2. Lambda関数におけるAPI Gateway以外のイベントソース a. S3の通知イベント設定 b. SNS Topicの使い方 83

Slide 84

Slide 84 text

画像更新用のURL生成APIを作る 1. DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 2. ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 3. DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成と実 装 4. UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 5. (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 6. (ストレッチ)単体テスト 7. (ストレッチ)画像がアップロードされた際のサムネイル作成 8. (ストレッチ)E2Eテスト 9. (ストレッチ)Metrics FilterとSNS Topicでエラー通知 84

Slide 85

Slide 85 text

画像更新用のURL生成APIを作る UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 a. [PUT] /metadata/{id}のAPI仕様を参考に作ってみましょう b. DynamoDBのアイテム更新のヒント i. update_itemメソッドを使用 ii. インプット(dict) 1. Key:テーブルの検索条件の指定 (dict) 2. ExpressionAttributeNames:後述するUpdateExpressionで条件式に使用する項目の代用 テキスト、#代用テキスト名:項目名の形式で指定(dict) 3. ExpressionAttributeValues:後述するUpdateExpressionで条件式に使用する値の代用テ キスト、:代用テキスト名:値の形式で指定(dict) 4. UpdateExpression:更新操作(文字列) a. 更新はSET #項目名=:値,...の形式で記述 5. ConditionExpression:操作対象レコードの条件 (文字列) 6. ReturnValues:update_itemのリターン値の設定 (文字列) a. ALL_NEW(更新後の全項目)を指定 85

Slide 86

Slide 86 text

ストレッチ 1. DataBucket/DataTable/PutEventTopic/PutEventPolicyの作成 2. ApiResource/CreateMetadataFunction/CreateMetadataLogGroupの作成 3. DataBucketにEventの設定とPutS3EventFunction/PutS3EventLogGroupの作成と実 装 4. UpdateMetadataFunction/UpdateMetadataLogGroupの作成と実行 5. (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 6. (ストレッチ)単体テスト 7. (ストレッチ)画像がアップロードされた際のサムネイル作成 8. (ストレッチ)E2Eテスト 9. (ストレッチ)Metrics FilterとSNS Topicでエラー通知 86

Slide 87

Slide 87 text

ストレッチのヒント (ストレッチ)GetMetadataFunction/GetMetadataLogGroupの作成と実行 a. 今までの応用です 87

Slide 88

Slide 88 text

ストレッチのヒント (ストレッチ)単体テスト a. AWSリソースのモックには LocalStackを使う i. MakefileにDockerイメージの操作タスクあり b. DynamoDBは接続先をlocalhost:4569でboto3からリソースを作成して、利用するメソッドを実装するモッ ククラスを作成する i. 利用するAPI(update_itemなど)を実装 ii. データはテキストファイルなどにテスト用に永続化など 88

Slide 89

Slide 89 text

ストレッチのヒント (ストレッチ)画像がアップロードされた際のサムネイル作成 a. 今回はメタデータを取得するだけだったが、他の処理も同じイベントで同時に走らせたいケースもある i. 画像解析やサムネイルの作成 b. SNSのトピックをイベントソースにしておけば全てのサブスクライバーが同時に処理を実行することができ る i. Fanoutパターン 89

Slide 90

Slide 90 text

ストレッチのヒント (ストレッチ)E2Eテスト a. 単体テストでみた通り、サーバーレスはローカル環境でのテスト実施での旨味が減少する b. 実際にデプロイしてAPIを叩いてあげるテストを実施しないと担保が難しくなる c. オーソライザが絡むと APIに限定したE2Eテストが難しくなるケースもあるため、プロジェクト全体でどのよ うにテストを実施するか検討する 90

Slide 91

Slide 91 text

ストレッチのヒント (ストレッチ)Metrics FilterとSNS Topicでエラー通知 a. エラー通知用のSNSトピックを追加(LogAlertTopic) i. リソースタイプ:AWS::SNS::Topic ii. スタックのアウトプットにトピック名を追加 1. トピック名を指定せずに作成するため 2. スタックのリソースから属性を取得するときは !GetAtt リソース名.属性名を使う b. CreateMetadataFunction用のCloudWatch Logs Metric Filter/CloudWatch Alarmを作成 i. CreateMetadataMetricFilter(ログファイルからエラーとなるパターンを読み取ってメトリクスとして通 知) 1. リソースタイプ:AWS::Logs::MetricFilter 2. FilterPattern(抽出パターン):"?\"\\\"levelname\\\": \\\"ERROR\\\"\"" 3. LogGroupName:CreateMetadataFunctionのロググループを参照する 4. MetricTransformations(メトリクスに送る設定 ): a. MetricNameおよびMetricNamespace:自由テキスト b. MetricValue:1 91

Slide 92

Slide 92 text

ストレッチのヒント (ストレッチ)Metrics FilterとSNS Topicでエラー通知 b. CreateMetadataFunction用のCloudWatch Logs Metric Filter/CloudWatch Alarmを作成(続き) i. CreateMetadataAlarm(メトリクスからアラームを SNSトピックにパブリッシュする ) 1. リソースタイプ:AWS::CloudWatch::Alerm 2. AlermName:自由テキスト 3. AlermActions(アラーム時のアクション対象リスト ):LogAlertTopicを参照する 4. ActionEnabled:true 5. MetricName(メトリクス名):MetricFilterで作成するMetricsTransformationsでの名前 6. NameSpace:MetricFilterで作成するMetricsTransformationsでの名前 7. 以下、アラームの諸条件 (60秒間でのメトリクスの数が 1以上ならアラートをだす ) a. Statictic:Sum b. Period(統計を適用する秒数 ):60 c. EvaluationPeriod:1 d. Threshold(条件の閾値):1.0 e. ComparisonOperator(条件式):GreaterThanOrEqualToThreshold(閾値以上の場合) 92

Slide 93

Slide 93 text

ストレッチのヒント (ストレッチ)Metrics FilterとSNS Topicでエラー通知 c. LogAlertTopicからメール通知の設定 i. トピックのサブスクライバを Emailで作成する d. そのほかの関数に対するエラー通知 i. 各関数ごとにMetricFilterとAlarmを作成する ii. NameSpaceとLogAlertTopicは共有 93

Slide 94

Slide 94 text

環境のお掃除 1. Cloud9のFile->Download Projectで今回のファイルのダウンロード 2. ハンズオン1で作成したスタックを削除する a. aws cloudformation delete-stack --stack-name lambda-tutorial-sample-appを実行する b. ハンズオン1で作成したデプロイ用の S3バケットを削除する 3. ハンズオン2で作成したAPIの利用に伴うS3バケットをクリアする a. pycon-serverless-tutorialをカレントディレクトリにする b. STACK_NAME=PyconServerlessTutorial python make_bucket_empty.pyを実行 4. ハンズオン2で作成したスタック、リソースを削除する a. aws cloudformation delete-stack --stack-name PyconServerlessTutorialを実行 b. ハンズオン2で作成したデプロイ用の S3バケットを削除する 5. Cloud9の環境を消す a. 環境を選択してメニューから Delete b. ダイアログにDeleteと入力してDeleteボタンクリック 94

Slide 95

Slide 95 text

クロージング 95

Slide 96

Slide 96 text

本日のチュートリアルのゴール(再確認) 1. AWS上で構築するサーバーレスアプリケーションの基本構成について知る 2. Lambdaの利用に十分な構成について知る 3. AWSの基本的なツールセットを使って、サーバーレスなAPIを構築する手順を知る 96

Slide 97

Slide 97 text

これからの展開と関連するサービス ● アプリケーションを拡張したい ○ S3にアップロードしたファイルが画像ファイルだったら画像解析してメタデータを取りたい ■ S3 PUTイベントからLambdaを呼び出してRekognitionを使う ● サーバーレスアプリケーションを再利用可能なものとして公開したい ○ Serverless Application Repositoryを使う ● 複数のLambdaをオーケストレーションする複雑な処理を書きたい ○ Step Functionsを使う ● CI/CD環境を整えたい ○ CodeCommit/CodeBuild/CodePipelineを使う ○ GitHub/CircleCIを使う ● サーバーレスアプリケーションを監視したい ○ CloudWatchを使う(基本的なメトリクスはデフォルトで採取される ) ○ Lambda アプリケーションのモニタリングとトラブルシューティング ○ 監視面でも運用に集中できる 97

Slide 98

Slide 98 text

Lambdaで開発をするときに役立つリンク ● AWS Lambda イベントソースマッピング ○ Lambdaは連携するイベント次第でコール時のイベント情報が異なるので、利用時には確認しておいた方 がいい ● エラー処理と AWS Lambda での自動再試行 ○ エラーのスローの仕方とエラーを拾った後をどう設計するか ○ デッドレターキューの利用へのリンクもあるので、プロダクションを意識する時には目を通しておきたい ● Lambda 関数で使用できる環境変数 ○ プリセットされている各種環境変数を知る ● AWS Lambda 関数を使用する際のベストプラクティス ○ 依存関係の管理など 98

Slide 99

Slide 99 text

Q&A 99

Slide 100

Slide 100 text

ありがとうございました 100