tag:crieit.net,2005:https://crieit.net/tags/CloudFormation/feed
「CloudFormation」の記事 - Crieit
Crieitでタグ「CloudFormation」に投稿された最近の記事
2021-05-13T23:16:42+09:00
https://crieit.net/tags/CloudFormation/feed
tag:crieit.net,2005:PublicArticle/17118
2021-05-13T23:16:42+09:00
2021-05-13T23:16:42+09:00
https://crieit.net/posts/Lambda-DeadLetterQueue-DLQ
Lambda関数でDeadLetterQueue(DLQ)を試す
<p>AWSのLambda関数をイベントで起動した時、複数回エラーを起こしたら、DeadLetterQueue、すなわちDLQを飛ばしたい。DLQを試すもの。Cloudformation使う。DLQはSNSとSQSが指定できるが、今回はSNSを使う。</p>
<h2 id="系"><a href="#%E7%B3%BB">系</a></h2>
<p>以下の系を試す。</p>
<p>CloudWatch -> Lambda -(error)-> SNS -> Email</p>
<h2 id="やってみる"><a href="#%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">やってみる</a></h2>
<p>CloudWatchで1分ごとにLambda関数を起動するようなものを、Cloudformationwと使って用意する。SNS Topicについては、コンソールから作成する。</p>
<h3 id="SNS Topicを作る"><a href="#SNS+Topic%E3%82%92%E4%BD%9C%E3%82%8B">SNS Topicを作る</a></h3>
<p>コンソールからSNS Topicを作成する。名前は仮に DeadLetterQueueTopicとする。とりあえずEメールに飛ばすようにしておくと、確認しやすいと思う。</p>
<h3 id="ディレクトリ構成"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E6%A7%8B%E6%88%90">ディレクトリ構成</a></h3>
<p>ディレクトリ構成は以下。__init__.pyは空。</p>
<p>.<br />
├── __init__.py<br />
├── hello_world_function<br />
│ ├── __init__.py<br />
│ ├── hello_world<br />
│ │ ├── __init__.py<br />
│ │ └── app.py<br />
│ └── requirements.txt<br />
├── samconfig.toml<br />
└── template.yaml</p>
<p>という構成でやってみる。</p>
<h3 id="template.yaml"><a href="#template.yaml">template.yaml</a></h3>
<p>TargetArn に SNS Topic のARNを入れる。</p>
<pre><code>AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world_function
Handler: hello_world/app.lambda_handler
Runtime: python3.8
Policies:
- AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
Events:
HelloWorld:
Type: Schedule
Properties:
Schedule: rate(1 minute)
DeadLetterQueue:
Type: SNS
TargetArn: arn:aws:sns:xxxxxxxxxxxxxxxxxx:DeadLetterQueueTopic
</code></pre>
<h3 id="samconfig.toml"><a href="#samconfig.toml">samconfig.toml</a></h3>
<p>sam build –use-container の後に sam deploy –guided で作るとよい。以下のようになる。</p>
<pre><code>version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-app"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1miie23rwqpqg"
s3_prefix = "sam-app"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
</code></pre>
<h3 id="requirement.txt"><a href="#requirement.txt">requirement.txt</a></h3>
<p>空でもいいけど。</p>
<pre><code>requests
six
regex
</code></pre>
<h3 id="hello_world/app.py"><a href="#hello%26%2395%3Bworld%2Fapp.py">hello_world/app.py</a></h3>
<pre><code>def lambda_handler(event, context):
return True
</code></pre>
<h3 id="DLQ"><a href="#DLQ">DLQ</a></h3>
<pre><code>sam build --use-container
sam deploy
</code></pre>
<p>デプロイすると、1分間にLambda関数が起動する。で、このままだと正常に終了してDLQが飛ばないので、わざとエラーを起こす。そのためには、上記コードの raise Exception のエラーを外してデプロイする。しばらく待っていたら、DLQがSNSに飛ぶ。SNSのSubscriberにEmailを用意しておけば、すぐに確認できる。</p>
<h3 id="後片付け"><a href="#%E5%BE%8C%E7%89%87%E4%BB%98%E3%81%91">後片付け</a></h3>
<p>SNSのトピックは手動で作成したので、手動で消す。</p>
<p>忘れずにスタックを消す。消し忘れると延々とLambda関数が起動し続けることになってしまうので注意。<br />
<code>aws cloudformation delete-stack --stack-name sam-app</code></p>
<h2 id="DLQ -> SNS -> Lambdaにした時のproperty"><a href="#DLQ+-%26gt%3B+SNS+-%26gt%3B+Lambda%E3%81%AB%E3%81%97%E3%81%9F%E6%99%82%E3%81%AEproperty">DLQ -> SNS -> Lambdaにした時のproperty</a></h2>
<p>Slackとかに飛ばしたい時は、DLQのSNS経由でLambda関数に飛ばすことになる。Lambda関数のeventのpropertyをメモしておく。</p>
<pre><code>{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "xxxxx",
"Sns": {
"Type": "Notification",
"MessageId": "xxxx",
"TopicArn": "xxxx"
"Subject": None,
"Message": "xxxxxxx",
"Timestamp": "2021-05-13T03:02:52.129Z",
"SignatureVersion": "1",
"Signature": "xxxx",
"SigningCertUrl": "xxxx",
"UnsubscribeUrl": "xxxx",
"MessageAttributes": {
"RequestID": {
"Type": "String",
"Value": "xxxx",
},
"ErrorCode": {
"Type": "String",
"Value": "200"
}
}
}
}
]
}
</code></pre>
<p>気になるのは event.Sns.Message だが、これはシリアライズされたJSON。json.loads()でデシリアライズすると以下のようになる。</p>
<pre><code>{
"version": "0",
"id": "xxxx",
"detail-type": "Scheduled Event",
"source": "aws.events",
"account": "xxxx",
"time": "2021-05-13T02:47:42Z",
"region": "xxxx",
"resources": [
"xxxx",
],
"detail": {}
}
</code></pre>
<p>resourcesとidから、エラーを起こした元のLambda関数を辿ることができる。</p>
<h2 id="参考URL"><a href="#%E5%8F%82%E8%80%83URL">参考URL</a></h2>
<p>ありがとうございました。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-scheduledevents-example-use-app-spec.html">CloudWatch イベント アプリケーションの AWS SAM テンプレート – AWS Lambda</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-deadletterqueue.html">DeadLetterQueue – AWS Serverless Application Model</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-policies">AWS::Serverless::Function – AWS Serverless Application Model</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/articles/eventbridge-supports-dead-letter-queue/">[アップデート]EventBridgeのデッドレターキュー(DLQ)を使ってみた | DevelopersIO</a></li>
</ul>
<p>関連コンテンツ</p>
<h2 id="関連記事"><a href="#%E9%96%A2%E9%80%A3%E8%A8%98%E4%BA%8B">関連記事</a></h2>
<p>スポンサーリンク</p>
tama