🌟

AWS Support - Troubleshooting in the cloud Workshopをやってみた①

2023/12/28に公開

AWS Support - Troubleshooting in the cloudとは

AWSが提供するWorkshopの一つで、現在(2023/12)は英語版が提供されています。(フィードバックが多ければ日本語化も対応したいとのこと)
クラウドへの移行が進む中でアプリケーションの複雑性も増しています。このワークショップでは様々なワークロードに対応できるトラブルシューティングを学ぶことが出来ます。AWSだけでなく一般的なトラブルシューティングにも繋がる知識が得られるため、非常にためになるWorkshopかと思います。また、セクションごとに分かれているので、興味のある分野だけ実施するということも可能です。

https://catalog.us-east-1.prod.workshops.aws/workshops/fdf5673a-d606-4876-ab14-9a1d25545895/en-US/introduction

学習できるコンテンツ・コンセプトとしては、CI/CD、IaC、Serverless、コンテナ、Network、Database等のシステムに関わる全てのレイヤが網羅されているので、ぜひ一度チャレンジしてみてください。

ここからは各大セクションごとに記事にまとめていきますので、興味のあるセクションにとんでください。
なお、すべてのセクションの前提作業は、Self-Paced Labのタブから必要なリソースのデプロイなどをしてください。

別の章の記事は末尾に追記していきますので、気になる章はリンクから飛んでいただければと思います。

DevOps and Serverless Troubleshooting

このコースではDevOpsとServerlessに関するトラブルシューティングを行います。
CI/CDパイプラインでのデプロイエラーやServerlessアプリケーションの稼働状況確認など、開発からリリースまでをスコープに対応していきます。

CloudFormationテンプレートが提供されているので、ダウンロードしてデプロイしている状態からスタートします。CodePipelineのリソースが構成されているかと思います。

概要

CloudFormationで構築したパイプラインには、以下のリソースが含まれています。

ステージ リソース
source Code Commit
build Code Build
deploy Code Deploy

このパイプラインの中でAPI GatewayからLambda・DynamoDB等をSAM[1]を使ってデプロイしています。

各問題に共通して、トラブルシューティングのプロセスが定義されています。これを意識しながら問題解決できるようにしましょう。

  • パイプラインは何をしますか?なぜ失敗したのですか? (問題を定義する)
  • 問題が特定のパイプラインの段階またはアクションにあるのかどうかを特定できますか? (消去の過程)
  • ステージが失敗する理由を確認する方法はありますか? (可観測性)
  • 特定の一連のイベントから問題の根本原因を絞り込むことはできますか? (タイムラインの構築)

Issue 1

PipeLineが失敗しているので、解決していきたいと思います。

まずはエラーメッセージの確認です。コンソールのSourceActionのメッセージを見てみます。

The action failed because no branch named mainline was found in the selected AWS CodeCommit repository SampleRepo. Make sure you are using the correct branch name, and then try again. Error: null

つまり、CodeCommitに指定したブランチが見つからないと言われています。今回はCfnテンプレートの中でパイプラインの定義自体も行っているので、ここを更新していきます。
ApplicationPipelineリソースの中のStages > Actions > Configurationの中のBranchNameを正しい値に修正しましょう。

- BranchName: mainline
+ BranchName: main

この状態でCfnスタックのテンプレートを置換更新します。
完了するとコンソールのパイプラインステージのiアイコンから情報を参照すると、更新されていることが分かります。

画面右上の「変更をリリース」を押下すると、パイプラインが実行され正常終了することが確認できます。

これでIssue1は完了です。

Issue 2

Issue1で実行したパイプラインが失敗しているので、内容を確認していきます。何はともあれログの確認からです。

以下のようになっているので、serverless-guard-checkで指定されたLambdaハンドラプロパティを確認します。

serverless-guard-check/aws_serverless_function       FAIL
・・・
 Error            = Check was not compliant as property [/Resources/putItemFunction/Properties/Handler[L:86,C:15]] was not present in [(resolved, Path=[L:0,C:0] Value=["src/get-by-id.getByIdHandler","src/get-all-items.getAllItemsHandler","src/put-item.putItemHandler"])]

SAMテンプレートを更新しますが、これはCloud9にコピーされているリポジトリに格納されています。
putItemFunction のHandlerプロパティを putItemHandler に変更します。
そのうえでGitリポジトリに反映させてみます。

再度パイプラインが起動し、うまくBuildされれば完了です。

Issue2は完了です。

Issue 3

続いてはDeployステージが失敗しているので、確認していきます。

ログを確認すると、S3Bucketというパラメータに問題がありそうです。

Parameters: [S3Bucket] must have values (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: 2169c3c0-28db-48e4-82bc-ed67f3ec1221; Proxy: null)

定義の仕方にもよりますが、今回はCfnでパイプラインを定義していて、各パイプラインステージにおけるパラメータの連携がうまくできていないことが原因になっていました。
Cfnテンプレートの中でParameterOverrides プロパティを使用すると、動的に値を渡すことが出来るようになるのでCfnテンプレートを更新します。

Capabilities: 'CAPABILITY_IAM,CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND'
+ ParameterOverrides: !Sub '{"S3Bucket": "${pipelineArtifactStore}"}' 
RoleArn: !GetAtt

更新後再度Cfnスタックを更新し、「変更をリリース」を実行すると上手くパイプラインが完了するかと思います。

これにてデプロイパイプラインに関しての問題は解消しましたので、デプロイされたAPIについてトラブルシューティングをしていきます。

Issue 4

まずは手順通りリクエストを実行してエラーが起きることを確認します。
Getリクエストで値が取得できないことが確認できたので、呼び出されているLambdaのログを確認してみます。しかし、GetItem関数のログに手掛かりになりそうなメッセージは出ていないです。

実は、このWorkshopではX-Rayに統合されているので、CloudWatchの画面からX-Rayのリソースマップを見てみましょう。

Getメソッド側に障害・エラーになっているのが見えるかと思います。その上で各項目をクリックしてみると詳細が見えるので、トレースログなどを見てみます。

DynamoDBでエラーが起きてそうなので、クリックしてエラーメッセージを見てみます。すると、AccessDeniedExceptionが出ているので、何か権限回りでエラーになっていそうです。

対象のLambdaのIAM権限を確認すると、DynamoDBへのポリシーがアタッチされていないことが分かりましたので、こちらを更新していきます。手順はWorkshopに記載の通りなので割愛します。
手順を実行すると、アプリケーションが再デプロイされるので、完了後に再度APIを呼び出してレスポンスを確認しましょう。正常に値が取得出来ていれば完了です。

Issue 5

前回の課題に引き続き、APIに関してのトラブルシューティングをしていきます。さらに、このセクションではCodeWisperer[2]を利用する事になっています!このあたりAWSの最新ツールを使わせるシナリオになっているのが素晴らしいですね。

全ての項目を取得するAPIだけエラーになることが確認できたので、先ほどと同様Lambdaのログ、X-Rayコンソールを確認してみましょう。

DynamoDBへのアクセスが発生していないように見えますので、Lambdaのコードを確認すると、DynamoDBをスキャンするためのコードスニペットがないため、コードを追加します。ここでCodeWispererの出番です。ぜひ使ってみてコード生成を体験してみてください。(私の環境では、かなりの精度で返ってきました。)

コードを更新し、再度デプロイしてみます。APIを実行して全件取得がうまく動作すればこのセクションは完了です。

Issue 6

このセクションではLocustを用いて負荷試験を行います。負荷試験には15分かかるのでご注意ください。
テスト結果はこちらです。

シナリオにある通り、GETメソッドのみエラー率と時間がかかっていることが分かります。

CloudWatchのインフラストラクチャモニタリングから、Lambda Insightsの画面を確認します。

この画像から読み取れるのは、メモリ使用率がすべての関数で最大に近くなっているにも関わらず、GETメソッドのみ所要時間がかかっているという点です。また、Lambdaのエラーとしては1件も出ていませんが、テスト結果にはFailuresがカウントされているため、関数内部でエラーを返しているため関数自体がエラーになっていないことが分かります。

画面下部には各関数ごとのサマリがあり、関数名を選択すると関数ごとの各リクエストの詳細を見ることが出来ます。さらに、トレースが表示されている行については選択すると、X-Rayトレースの画面が表示されます。

このトレースからはDynamoDBにおいてエラーが出ていますが、こちらもDynamoDBを選択すると詳細が確認できます。

メッセージとしては、スループットが足りていないためプロビジョニングのレベルを上げるよう言われています。ただ、これは関数でのスキャン量を減らすなどでも対応できる項目ですので、DevOps Guru[3]を使ってコードの検証をしていくことになります。
DevOps Guruを有効化すると事後的インサイトととして先ほどのアプリケーションの以上が検知されています。さらにエラー率などがグラフ化されていたり、推奨事項の提示等をしてくれています。かなり分かりやすいです。

より詳細なメトリクスやダッシュボードについては、かなり長くなってしまったので、別記事にまとめてみたいと思います。

最後に

これにてこの章は終了になります。
この章を通してCI/CDパイプライン自体のトラブルシューティングとAPIの負荷テストまで実施することができました。また、使ったことのなかったDevOps Guruを使ってみることが出来たのでとてもいい経験になりました。

Workshop全体としてはまだまだセクションもありますので、別の記事でそれぞれ検証していきたいと思います。

リンク

DevOps Guruについて

https://zenn.dev/nnydtmg/articles/aws-devopsguru-workshop

脚注
  1. AWS Serverless Application Model ↩︎

  2. CodeWisperer ↩︎

  3. DevOps Guru ↩︎

GitHubで編集を提案

Discussion