0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS Lambda のデプロイ(コンソール)

Last updated at Posted at 2023-05-31
  • AWS コンソールを使った VPC、RDS、S3、Lambda、サブスクリプションフィルタの作成をまとめました。
  • AWS CLI を使った作成はこちら
  • システムの構成
    Lambda と RSD はVPC、セキュリティグループどちらも同じものに所属させています。
    image.png

VPCの作成
セキュリティグループの作成
データベースの作成
Lambdaの作成
実行

VPCの作成

  • VPC「myproject-vpc」の作成をします。
  • 「VPCなど」を選択する事でサブネットなども一緒に作成する事が出来ます。
    image.png
    image.png

セキュリティグループの作成

  • セキュリティグループ「my-security-group」を作成します。
  • インバウンドルール、アウトバウンドルールは一旦無しのまま作成します。
    image.png

インバウンドルールを設定します。

  • 自分自身を許可しました。
    image.png

アウトバウンドルールを設定します。

  • こちらも自分自身を許可しました。
    image.png

データベースの作成

  • RDS から MySQL を選択・作成します。
  • 「無料利用枠」を選ぶと無料枠内で利用可能なオプションが選択出来ます。
  • 今回は「db.t2.micro」を選択しました。
  • 「VPC」「セキュリティグループ」は先ほど作成した「myproject-vpc」「my-security-group」を選択します。
  • 初期 DB として「testmysql」を作成しました。
    image.png
  • 作成した RDS のエンドポイントが接続時に必要になるのでメモします。
    image.png

S3 の作成

  • S3 を作成します。
  • 「バケット名」は Lambda から S3 へアクセスする際に必要になるのでメモをします。
    image.png

Lambdaの作成

レイヤーの作成

  • ライブラリをレイヤーに含めます。
  • ローカル環境でライブラリを zip 化して、レイヤーに登録します。
    https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
    image.png
    • ローカル環境で MySQL, boto3 ライブラリを zip にまとめます。
    • 今回はそれぞれ zip 化しました。
      image.png
    • 先ほど作成した zip 化した mysql.zip, boto3.zip をそれぞれアップロードして、レイヤーを作成します。
      image.png
      image.png
    • 作成したレイヤーのバージョン情報は Lambda 関数にレイヤーを登録する際に必要になるのでメモします。
      image.png

Lambda 実行ロールの作成

  • S3 へのアクセス、CloudWatch のログ書き込み、VPC の設定で EC2 権限が必要だったので、以下の権限を付与しました。
    • AmazonS3FullAccess
    • AWSLambdaBasicExecutionRole
    • AmazonEC2FullAccess
      image.png

Lambda 関数①の作成

image.png

  • コードを編集します。
    RDS へ接続して時刻を取得してログを出します。
    image.png
    import mysql.connector
    import json
    import os
    import logging
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    host = os.environ['RDS_HOST_NAME']
    user = os.environ['USER_NAME']
    password = os.environ['PASSWORD']
    db = os.environ['DB_NAME']
    
    def lambda_handler(event, context):
        conn = None
        date_time = None
        message = None
        try:
            # MySQL の接続
            conn = mysql.connector.connect(
                user=user,
                password=password,
                database=db,
                host=host
            )
            cur = conn.cursor()
            # 日時の取得
            cur.execute(f"SELECT NOW();")
            results = cur.fetchall()
            message = f"{results[0][0]}"
            logger.info("取得した時刻:" + message)
            status_code = 200
        except Exception as e:
            logger.info(f"Error Occurred: {e}")
            status_code = 500
            message = "error"
        finally:
            if conn is not None and conn.is_connected():
                conn.close()
        return {
            "statusCode": status_code,
            "body": json.dumps({
                "res": message,
                "event": event
                })
        }
    

Lambda 関数①の設定

  • 環境変数を設定します。
    image.png
  • VPC を設定します。
    image.png
    • 先ほど作成した「myproject-vpc」「適当なサブネット」「my-security-group」を設定します。
      image.png
  • Lambda 関数にレイヤーを追加します。
    image.png
    • 先ほど作成した mysql レイヤーのバージョン情報を ARN に設定します。
      image.png

Lambda 関数①の実行

  • 「Test」から実行します。
  • RDS へアクセスして時刻が取得できる事を確認出来ます。
    image.png

Lambda 関数①の CloudWatch のログの確認

  • Lambda の実行ログが保存されています。
    image.png
  • 中を確認すると実行時のログが確認出来ます。
    image.png

Lambda 関数②の作成

  • CloudWatch から受け取ったイベントの内容を S3 に保存します。
  • bucket_name = "xxx" は作成したS3のバケット名を入力します。
    image.png
import json
import base64
import gzip
import re
import boto3
import tempfile
import os
import glob
from datetime import datetime, timedelta, timezone
from boto3.session import Session

import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

JST = timezone(timedelta(hours=+9), 'JST')

def lambda_handler(event, context):
    try:
        # base64 デコード
        decoded_data = base64.b64decode(event["awslogs"]["data"])
        # gzip 解凍
        decompressed_data = gzip.decompress(decoded_data)
        json_data = json.loads(decompressed_data)
        logger.info(json_data)
        
        # 「取得した時刻:」が書かれているログの一部を抜き出します。
        for logEvent in json_data["logEvents"]:
            log = re.search(r"取得した時刻:.*", logEvent["message"])
            if log != None:
                message = log.group()
                logger.info("イベントメッセージ:{0}".format(message))
                break
        # 一時ファイルへの書き込み
        with tempfile.TemporaryDirectory() as tmpdir_name:
            tmpfile_name = "temp.txt"
            tmpfile_path = os.path.join(tmpdir_name, tmpfile_name)
            # 一時ファイルの作成
            with open(tmpfile_path, "w", encoding='UTF-8') as f:
                f.write(message)
            logger.info("一時ファイル:{0}".format(glob.glob(tmpfile_path, recursive=True)))
            # 一時ファイルの中身を確認
            with open(tmpfile_path, encoding='UTF-8') as f:
                logger.info("一時ファイルの中身:{0}".format(f.read()))

            # 一時ファイルを S3 へアップロード
            bucket_name = "xxx"
            s3 = boto3.resource("s3")
            bucket = s3.Bucket(bucket_name)
            date_time = datetime.now(JST).strftime('%Y%m%d_%H%M%S_%f')
            logger.info("現在時刻:{0}".format(date_time))
            s3file_path = os.path.join(date_time, tmpfile_name)
            bucket.upload_file(tmpfile_path, s3file_path)

        # 一時ファイルの削除を確認
        logger.info("削除後の一時ファイル:{0}".format(glob.glob(tmpfile_path, recursive=True)))
        # s3ファイルの確認
        for obj in bucket.objects.all():
            logger.info("S3削除対象:{0}".format(obj.key))
            # s3ファイルの削除
            res = bucket.objects.filter(Prefix=obj.key).delete()
            logger.info("削除したS3ファイル:HTTPStatusCode:{0}, Deleted:{1}".format(res[0]["ResponseMetadata"]["HTTPStatusCode"], res[0]["Deleted"][0]["Key"]))
    except Exception as e:
        logger.info(f"Error Occurred: {e}")
    return {
        "statusCode": 200,
        "body": json.dumps({
            "res": "S3TEST",
            "event": event
            }),
    }

Lambda 関数②の設定

  • 環境変数、VPC 設定は不要です。
  • Lambda 関数にレイヤーを追加します。
    image.png
    • 先ほど作成した boto3 レイヤーのバージョン情報を ARN に設定します。
      image.png

サブスクリプションフィルタの作成

  • CloudWatch の Lambda 関数①のロググループにサブスクリプションフィルタを作成します。
  • 上記ロググループに「取得した時刻:」が出現したら、Lambda 関数②を実行します。
    image.png
    image.png

Lambda 関数①の実行

  • Lambda 関数①を実行してサブスクリプションフィルタで Lambda 関数②が実行される事を確認します。
    image.png
    image.png
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?