本日はSAMを使い、Cloudwatchアラームが発生した場合Slackにメッセージが送信されるサーバレスアーキテクチャーを構築します。
AWS Serverless Application Model (AWS SAM) は、AWS でサーバーレスアプリケーションを構築するために使用できるオープンソースのフレームワークです。Lambdaだけでなく、SNS,S3、SES、Cloudwatchを使用したサーバレスなシステム構築を簡単に行うことができます。
SAMコマンドを使用し、Cloudformationのスタックのデプロイを行うことでシステムが簡単に構築されます。
環境についてはCloud9を使用してPythonで開発を行います。Cloud9を使用しない場合は、Python、SAMコマンドのインストールが必要です。Cloud9は必要なものが入っているので、私はこちらで開発を行っていきます。
- Cloud9の環境作成
- SAM initで構築を開始する
- SARからコードを持ってくる
- SAMコマンドでデプロイ
- Cloudformation確認
- 作成されたシステムを確認・テスト
はじめに
今回の開発作業ですが、SAR(レポジトリ)からpythonコードなどを持ってきたのですが、プログラムが古くテストの際にエラーが発生してしまいました。不完全な記事になってしまい申し訳ありません。
ですが、リソースの展開まではうまくいきましたので、SAMコマンドの使い方、SAMの仕組み、SAMを利用したCloudformationスタックの作成、リソースの展開までの流れは紹介できたと思います。
以上のことを踏まえたうえで記事を読んでいただければ幸いです。
本記事に関してですが、時間があればコードを書き直して、もう一度挑戦しようと思います。その際は記事を更新します。
1.Cloud9の環境作成
Cloud9の環境は以下の流れで作成できます。
1.Cloud9のサービスコンソールへ移動
2.[Create environment]を選択
3.環境名、パラメータをを設定する
4.[create]をクリック
立ち上がるまで少し時間がかかります。立ち上がってきたら[Open in Cloud9]で開発環境に入りましょう。
2.SAM initで構築を開始する
さっそく下記コマンドを打ってSAMを開始していきましょう。
「Choose an AWS Quick Start application template」の選択肢ですが後で編集するのでとりあえず「hello_world」を選択している。
ec2-user:~/environment $ sam init
SAM CLI now collects telemetry to better understand customer needs.
You can OPT OUT and disable telemetry collection by setting the
environment variable SAM_CLI_TELEMETRY=0 in your shell.
Thanks for your help!
Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Multi-step workflow
3 - Serverless API
4 - Scheduled task
5 - Standalone function
6 - Data processing
7 - Infrastructure event management
8 - Lambda EFS example
9 - Machine Learning
Template: 1
Use the most popular runtime and package type? (Python and zip) [y/N]: y
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details
Project name [sam-app]: Cloudwatch-alarm-slack
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)
-----------------------
Generating application:
-----------------------
Name: s3-trigger-sns
Runtime: python3.9
Architectures: x86_64
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./s3-trigger-sns/README.md
Commands you can use next
=========================
[*] Create pipeline: cd s3-trigger-sns && sam pipeline init --bootstrap
[*] Validate SAM template: sam validate
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
SAM CLI update available (1.74.0); (1.57.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
ec2-user:~/environment $
完了すると下記のようにフォルダが作成されます。
これで準備は完了です。
events・・・テストの際に使うイベント
hello_world・・・Lambdaのコード(Choose an AWS Quick Start application templateでhello_worldを選択したのでこの名前になっている)
test・・・テストで使用するもの一式が入っている
template.yaml・・・SAMテンプレートファイル
今回はhello_worldの関数とSAMテンプレートを今回の目的のものに変更してCloudformationをデプロイします。
どのように変更するのかは次の章で記述していきます。
3.SARからコードを持ってくる
AWS Serverless Application Repository(SAR) は、サーバーレスアプリケーション用のマネージド型リポジトリです。
pythonコードやテンプレートファイルを入手できます。
目的のものを検索していきます。
「cloudwatch-alarm-to-slack-python3」を選択します。選択するとLambdaのページへ移動します。
下記のテンプレートにyamlファイル用のコードが記述されてあります。これをCloud9のtemplate.yamlへ記述します。
次はpythonのコードですが、上の画像の[ソースコードURL]からソースコードが格納されてあるgithubのページに移動できます。
下記の[Lambda_function.py]を選択して[Raw]をクリックしURLをコピーします。
Rawをコピーしてwgetコマンドでファイルをプルしていきます。コマンドを実行するとファイルが作成されます。app.py(とりあえず作成したhello_world用のpythonファイル)はいらないので削除します。次はデプロイをしていくのですが、template.yamlのlambdaのHandlerが実行するファイルの関数を指していることを確認します。
Resources:
cloudwatchalarmtoslackpython3:
Type: AWS::Serverless::Function
Properties:
Handler: lambda_function.lambda_handler
Runtime: python3.9
4.SAMコマンドでデプロイ
まずはビルドを行ってきます。
ec2-user:~/environment/s3-trigger-sns $ sam build --use-container
Starting Build inside a container
The resource AWS::Serverless::Function 'cloudwatchalarmtoslackpython3' has specified S3 location for CodeUri. It will not be built and SAM CLI does not support invoking it locally.
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided
ec2-user:~/environment/s3-trigger-sns $
そしてデプロイを行っていきます。
SARからとってきた今回のtemplate.yamlのコードは下記のパラメータを入力する必要があり、
deployする前に事前に作成して準備をしておいてください。
・KeyIdParameter(KMSのKeyID)
・slackChannelParameter(Slackのチャンネルの名前)
・kmsEncryptedHookUrlParameter(HookUrl/すぐ作成できますがサイトから作成しておく必要があります。)
ec2-user:~/environment/Cloudwatch-alarm-slack $ sam deploy --guided --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name []: dev-sam-cloudwatch-slack
AWS Region [ap-northeast-1]:
Parameter KeyIdParameter []:
Parameter slackChannelParameter []:
Parameter kmsEncryptedHookUrlParameter []:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]: y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [Y/n]: y
Save arguments to configuration file [Y/n]: y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Creating the required resources...
Successfully created!
5.Cloudformation確認
CloudformationおよびLambda、SNSが展開されていることが確認できました。
6.作成されたシステムを確認・テスト
それでは、Cloudwatchアラームが発生したらSlackに通知が届くのかテストを行っていきます。
今回は適当にCloud9のインスタンスのCPU使用率が80%を超えた場合にアラーム状態になるアラームを作成しました。アラームのSNS設定は今回作成したLambdaを呼び出すSNSトピックを設定します。
下記コマンドを実行し、アラーム状態にします。
aws cloudwatch set-alarm-state --alarm-name "dev-sam-Cloud9instance-CPUUtilization > 80" --state-value ALARM --state-reason "alarmtest"
Slackに通知がいかず、Lambdaのログを確認したところ下記のエラーが発生しました。
解決方法を探しましたが見つからず以下のサイトによると今回使用したSARのプログラムが古かったため、うまくいかなかったようです。
[ERROR] InvalidCiphertextException: An error occurred (InvalidCiphertextException) when calling the Decrypt operation:
Traceback (most recent call last):
File "/var/lang/lib/python3.9/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 850, in exec_module
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "/var/task/lambda_function.py", line 62, in <module>
HOOK_URL = "https://" + boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext'].decode('utf-8')
File "/var/runtime/botocore/client.py", line 391, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 719, in _make_api_call
raise error_class(parsed_response, operation_name)
解決策が見つからなかったため本記事は以上にしようと思います。
時間があればLambdaのコードとテンプレートファイルのコードを書き換えて、再度デプロイしようと思います。
最後はうまくいきませんでしたが、リソースの展開までうまくいきましたのでSAMを利用した開発の流れは紹介できたと思います。
本記事は以上になります。ありがとうございました。