【初学者向け】サーバーレスを学ぶための実践演習2

9月 14, 2020AWS,CloudWatch,Lambda

演習2: Lambda + CloudWatch Event

 

はじめに

  • Lambdaは、AWSが提供するサーバーレスのコンピューティングサービスです。前回に引き続き、Lambda を基礎から学習するための演習を発信します。Lambdaを初めて使う方は、演習1からお読みください。
  • 今回の演習は、Lambda のトリガにCloudWatch Event を使用します。今回のゴールは、よくあるパターンであるCloudWatch EventをトリガとしたをLambda のサービスを構築できることです。
  • 実際にやってみないとなかなか理解できません。一度読んだ後に、実際に手を動かしながら確認してみてくださいね。
 

演習2 Lambda+CloudWatch Eventのパターン1

概要

  • パターン1は、time baseで定期的なスケジュール(Unixのcronと同じ)をルールとしたトリガです。演習では、平日10:00にEC2 インスタンスを起動するLambda 関数を構築します。
  • コスト削減のため毎日インスタンスを停止、起動させるケース、OSのクリーンアップのため定時に再起動させたいケースなどに適用可能なアーキテクチャですね。
  • 前提条件として、事前にLambdaの実行ロールを準備します。ロールには、下記のポリシーをアタッチします。
    • AWSLambdaBasicExecutionRole
    • EC2FullAccess
 

システム構成

  • 本演習のシステム構成は、下記の通りです。あらかじめ、EC2を準備しておきます(OSは問いません)。
     

構築してみる

Lambdaを作る

  • Lambdaのコンソールを開き、一から作成します。関数名を入力、ランタイム(今回はPython 3.8とします)、実行ロールを選択します。
  • 前述の通り、実行ロールにはEC2FullAccess ポリシーを割り当てておきます。
   
  • Lambda関数が作成されました。続いて、下記AWSの記事に記載されているコードを利用します。
  • サンプルのコードから、regionをap-northeast-1に変更、instances の指定を今回使用するインスタンスのid に変更します。
  • EC2インスタンスを起動するスクリプトサンプル

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))
 
  • EC2インスタンスを停止するスクリプトサンプル

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))
 
  • コードができたら、[Save]を押します。
  • 次に、トリガを設定しましょう。[+ Add trigger]を押します。
   
  • Trigger configurationが開きます。先ず、Triggerから、[CloudWatch Events]を選択します。
  • [Create a new rule]を押し、ルールを入力していきます。
    • Rule name
    • Rule description
    • Rule type ← 今回はSchedule expression(スケジュール式)を選択します。
    • Schedule expression ← スケジュールをCron式あるいはRate式で入力します。
  • 今回Cron式のスケジュールは下記とします。左から分、時、日、月、週、年となります(Minutes Hours Day-of-month Month Day-of-week Year)。
    • 例:cron(0 1 ? * MON-FRI *)
  • rate式の場合は、rate(5 minutes)、rate(1 hour)、rate(7 days)などと入力します。
  • Enable triggerがチェックされていることを確認して、[Add]を押します。
     
  • Lambda関数にトリガが設定されました。
 
  • [Test]ボタンの左より、[Configure test events]を選択します。今回のケースでは、Handlerに渡すevent の値はダミーで構いません。
     
  • テストの結果より、関数は正常に実行されました。
   

テストしてみる

  • トリガのルールに設定したスケジュール(am10:00)に、EC2インスタンスが起動したことを確認します。
 
  • EC2インスタンスを停止するスクリプトを使用した場合は、下記となります。
     

演習2 Lambda+CloudWatch Eventのパターン2

概要

  • パターン2は、event baseで、特定のアラートをルールとしたトリガです。演習では、EC2 インスタンスがstoppedステータスに変化したアラートを受け、Eメールを送信するLambda関数を構築します。
  • 前提条件として、事前にLambdaの実行ロールを準備します。ロールには、下記のポリシーをアタッチします。
    • AWSLambdaBasicExecutionRole
    • AmazonSESFullAccess
 

システム構成

  • 本演習のシステム構成は、下記の通りです。あらかじめ、EC2を準備しておきます(OSは問いません)。
  • 新たなサービスとして、SES(Simple Email Service)を使います。
     

構築してみる

SESを準備する

  • SES(Simple Email Service)のコンソールを開きます。リージョンは、バージニア北部を選択します。 日本リージョンでは、SESがサポートされていないためです。
     
  • SESは、あらかじめ登録した宛先にのみメールの送信ができます。事前にメールアドレスの検証を行います。(SESでは、個別にメールアドレスを検証する以外にドメイン全体の検証も可能です。詳細はこちら。)
  • メールアドレスの検証には、[Email Addresses] → [Verify a New Email Address]を押します。
   
  • メールアドレスを入力して、[Verify This Email Address]を押します。
   
  • メールが送信されました。メールの受信を確認し、メール本文に記載されているメールアドレスの確認のためのURL をクリックします。
 
  • メールアドレスの確認が完了すると、下記の画面に遷移します。これで、メールアドレスの検証に成功しました。
   
  • ステータスがverifiedになれば、そのメールアドレスが使用可能です。
  • 次に、テストメールを送信します。[Send a Test Email]を押します。
   
  • 送信先のアドレス、件名、本文を入力して、[Send Test Email]を押します。
   
  • 無事テストメールを送ることができました。
   

Lambdaを作る

  • 次にLambda関数を作ります。Lambdaのコンソールを開き、一から作成します。関数名を入力、ランタイム(今回はPython 3.8とします)、実行ロールを選択します。
  • 前述の通り、実行ロールにはAmazonSESFullAccess ポリシーを割り当てておきます。
   
  • 今回の演習では、下記のコードを使用します。コードができたら、[Save]を押します。

import json
import boto3
MAIL_FROM = 'user1@test-domain.jp'
MAIL_TO = 'user2@test-domain.jp'
MAIL_SUBJECT = 'Mail Alert'
MAIL_BODY = 'Status change alert for your instance'
REGION = 'us-east-1'
def send_mail(to, subject, body):
    client = boto3.client('ses', region_name=REGION)
    response = client.send_email(
        Source = MAIL_FROM,
        Destination = {
            'ToAddresses' : [
                to
            ]
        },
        Message = {
            'Subject': {
                'Data': subject,
                'Charset': 'UTF-8'
            },
            'Body': {
                'Text': {
                    'Data': body,
                    'Charset': 'UTF-8'
                }
            }
        }
    )
def lambda_handler(event, context):
    send_mail(MAIL_TO, MAIL_SUBJECT, MAIL_BODY)
   
  • トリガを設定しましょう。[+ Add trigger]を押します。
  • Trigger configurationが開きます。先ず、Triggerから、[CloudWatch Events]を選択します。
 
  • [Create a new rule]を押し、ルールを入力していきます。
    • Rule name
    • Rule description
    • Rule type →Event patternを選択します。
    • Event →EC2およびEC2 instance state-change notification を選択します。
    • Detail →Instances, State を選択し、対象となるインスタンスID、ステータスを設定します。
  • Enable triggerがチェックされていることを確認して、[Add]を押します。
   
  • Lambda関数にトリガが設定されました。
 

テストしてみる

  • テストのため、対象となるインスタンスを停止させます。
     
  • 正しく、インスタンス停止のイベントをトリガとして、メールが送信されました。
   

おさらい

  • 今回構築したのは、とても小さな機能のシステムですが、よくあるパターンであるスケジュールをトリガとしたLambda、イベント発生をトリガとしたLambdaを使って構築ができました。CloudWatch だけでなく、他のAWSサービスと組み合わせることで、色々な機能を実現することができます。
  • 次回は、S3 を使ったLambda に挑戦です。以下バックナンバー。

バックナンバー

   

参考資料