CloudFormationを使用して、Lambda Insightを有効化する
AWS DVAの出題範囲の1つでもある、モニタリング・トラブルシューティングに関する内容です。
LambdaおよびCloudWatchが提供する機能の1つにLambda Insightsがあります。
CloudWatch Lambda Insights は、 で実行されているサーバーレスアプリケーション用のモニタリングおよびトラブルシューティングソリューションですAWS Lambda このソリューションでは、CPU 時間、メモリ、ディスク、ネットワーク使用率などのシステムレベルのメトリクスが収集、集約、要約されます。
Amazon CloudWatch での Lambda Insights の使用
本ページでは、以下のページを参考に、CloudFormationを使用して、Lambda Insightsを有効化したLambda関数を作成する方法を確認します。
構築する環境
3つのLambda関数を作成します。
各関数にLambdaレイヤーを関連付けます。
これはLambda Insightsを有効化するために必要な手順です。
同様に、各関数にIAMロールを関連付けます。
こちらもLambda Insightsを動作させるために必要です。
Lambda Insightsによって収集されたメトリクスは、CloudWatchに保存されます。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-dva/tree/main/05/004
テンプレートファイルのポイント解説
Lambda
関数1
Resources:
Function1:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Code:
ZipFile: |
import datetime
def lambda_handler(event, context):
print('awstut!')
return {
'statusCode': 200,
'body': str(datetime.datetime.now())
}
FunctionName: !Sub "${Prefix}-function1"
Handler: !Ref Handler
Layers:
- !Ref LambdaInsightsLayer
MemorySize: !Ref MemorySize
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole.Arn
Timeout: !Ref Timeout
FunctionUrl:
Type: AWS::Lambda::Url
Properties:
AuthType: NONE
TargetFunctionArn: !GetAtt Function1.Arn
FunctionUrlPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunctionUrl
FunctionName: !GetAtt Function1.Arn
FunctionUrlAuthType: NONE
Principal: "*"
Code language: YAML (yaml)
Lambda Insightsを有効化する上でのポイントは、Lambdaレイヤーです。
Lambda Insights は、Lambda レイヤーとして提供される新しい CloudWatch Lambda 拡張機能を使用します。この拡張機能を、サポートされているランタイムで、Lambda 関数で有効にすると、システムレベルのメトリクスが収集され、その Lambda 関数の呼び出しごとに 1 つのパフォーマンスログイベントが発生します。
Lambda Insights によるサーバーレスアプリケーションのモニタリング方法
Lambda Insightsを有効化するために使用するべきLambdaレイヤーは、関数をデプロイするリージョンおよびアーキテクチャに依存します。
詳細は以下のページをご確認いただきたいのですが、例えば本環境(東京リージョン、ARM64)ですと、以下を選択します。
arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension-Arm64:2
上記の文字列をLayersプロパティに指定します。
Lambda関数で実行するコードをインライン表記で定義します。
詳細につきましては、以下のページをご確認ください。
コードの内容ですが、関数を実行した日時を返します。
またprint関数を使って、文字列を出力させます。
これは後述のテキストログに出力先を確認するためです。
本関数はFunction URLを有効化します。
本機能を有効化すると、HTTPSエンドポイントが生成され、URLにアクセスすると、本関数が実行できます。
Function URLに関する詳細は、以下のページをご確認ください。
関数2
Resources:
Function2:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Environment:
Variables:
FUNCTION_URL: !GetAtt FunctionUrl.FunctionUrl
Code:
ZipFile: |
import json
import os
import urllib.request
function_url = os.environ['FUNCTION_URL']
limit = 5
def lambda_handler(event, context):
responses = [urllib.request.urlopen(function_url).read().decode("utf-8") for i in range(limit)]
return {
'statusCode': 200,
'body': json.dumps(responses, indent=2)
}
FunctionName: !Sub "${Prefix}-function2"
Handler: !Ref Handler
Layers:
- !Ref LambdaInsightsLayer
MemorySize: !Ref MemorySize
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole.Arn
Timeout: !Ref Timeout
Code language: YAML (yaml)
先述の関数1を5回呼び出す内容です。
Lambda Insightsを有効化するために、先述のLambdaレイヤーを使用するように設定します。
関数3
Resources:
Function3:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Code:
ZipFile: |
def lambda_handler(event, context):
while True:
pass
FunctionName: !Sub "${Prefix}-function3"
Handler: !Ref Handler
Layers:
- !Ref LambdaInsightsLayer
MemorySize: !Ref MemorySize
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole.Arn
Timeout: !Ref Timeout
Code language: YAML (yaml)
while文で空のループを繰り返す内容です。
タイムアウトを過ぎるまで繰り返し、関数の実行に失敗して終了します。
Lambda Insightsを有効化するために、先述のLambdaレイヤーを使用するように設定します。
IAMロール
Resources:
FunctionRole:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy
Code language: YAML (yaml)
Lambda Insightsを有効化する上で、もう1つのポイントは、IAMロールです。
CloudWatchLambdaInsightsExecutionRolePolicy IAM ポリシーを関数実行ロールに追加します。
既存の Lambda 関数で Lambda Insights を有効にするために AWS CloudFormation を使用する
加えて、AWS管理ポリシーAWSLambdaBasicExecutionRoleをアタッチします。
これはCloudWatch Logsにテキストログを配信するために必要な権限を与えるものです。
EventBridge
Resources:
Rule1:
Type: AWS::Events::Rule
Properties:
Name: !Sub "${Prefix}-EventsRule-01"
ScheduleExpression: rate(1 minute)
State: ENABLED
Targets:
- Arn: !Ref FunctionArn1
Id: !Ref Function1
EventsRulePermission1:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Function1
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt Rule1.Arn
Code language: YAML (yaml)
関数1を取り上げます。
関数2および関数3も同様の設定です。
EventBridgeルールを定義して、関数を定期的に実行します。
詳細につきましては、以下のページをご確認ください。
今回は各関数を1分おきに実行するように設定します。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- Lambda関数1:dva-05-004-function1
- Lambda関数2:dva-05-004-function2
- Lambda関数3:dva-05-004-function3
AWS Management ConsoleからもLambda関数を確認します。
3つの関数が正常に作成されています。
EventBridgeルールを確認します。
3つのルールが作成されています。
それぞれ1分ごとに3関数を呼び出す内容です。
動作確認
準備が整いましたので、Lambda Insightsのコンソール画面を確認します。
3つの関数に関する様々なメトリクスがグラフ化されています。
特徴的なグラフを確認します。
DurationやErrorsは関数3が高い数値を出しています。
これはwhile文でループを繰り返しているため、タイムアウトまで待機し、最終的に関数の実行に失敗しているためです。
Invocationsは関数1が高い数値を出しています。
これはEventBridgeルールで1分ごとに実行されていることに加えて、関数2から頻繁に呼び出されていることが原因です。
Network Usageは関数2が高い数値を出しています。
これは先述の通り、Function URLを通じて、関数1を頻繁に呼び出しているためです。
関数を指定してグラフを描画することもできます。
上記は、関数1に注目した画像です。
Lambda Insights用の各種メトリクスは、以下のCloudWatch Logsに配信されたログデータが使用されます。
サンプルとして、関数1用のロググループを確認します。
確かに各種メトリクスのデータが保存されています。
ちなみに本ロググループには、テキストログは配信されません。
上記は関数1の内容ですが、今回はデフォルトのロググループ/aws/lamba/dva-04-003-function1に格納されました。
まとめ
CloudFormationを使用して、Lambda Insightsを有効化したLambda関数を作成する方法を確認しました。