目次

Lambda関数URL

Lambdaの関数URLをちょっと触ってみた。

目的

外出先で簡易に状況確認できないかなって・・・
・CloudWatchのアラーム状態
・インスタンス落としたか?…など

課題

・Lambda関数URLにブラウザアクセスすると2回実行される(curlコマンドだと1回なのに何故だ?faviconか??)
 →faviconだったのでコードを少し修正したらブラウザからリクエストしても1回の通知になりました。(Lambdaは2回実行されちゃうけどね!)

Lambda関数サンプル

ポイント

・外出先からを想定して、認証タイプはNONEにしています。
・最低限の認証として、クエリパラメータに入れた値とLambda関数の環境変数の一致で挙動を変えています。
・知らない人にリクエストされていないか確認を兼ねて、NGの場合でも結果をSNSからも通知しています。
・認証をNONEにしていますが、画面上のレスポンスはAWS_IAMと同様に疑似的に{“Message”:“Forbidden”}と返しています。←パッと見認証失敗したかのように!
・下記URLの形式でリクエストすると結果が返ってきます。
https://xxxxx.lambda-url.ap-northeast-1.on.aws/?AuthId=xxxxxxxxxx

コード①

import os
import boto3

client = boto3.client('sns')
TARGET_ARN = 'arn:aws:sns:ap-northeast-1:12345678910:[SNSTopic名]'
HTTP_RES = {"Message":"Forbidden"}

def lambda_handler(event, context):
    try:
        token = event['queryStringParameters']['AuthId']
    except:
        token = None
 
    try:
        env = os.environ['AuthId']
    except:
        env = 'NotSet'
 
    if token == env:
        message = 'OK'
        subject = '簡易監視' + message
 
        request = {
            'PhoneNumber': TARGET_ARN,
            'Message': message,
            'Subject': subject
        }
 
    else:
        message = 'NG'
        subject = '簡易監視' + message
 
        request = {
            'PhoneNumber': TARGET_ARN,
            'Message': message,
            'Subject': subject
        }
 
    response = client.publish(**request)
    return HTTP_RES
 
if __name__ == '__main__':
    lambda_handler("event", "context")

コード②rawPathが「/」だったら実行する版

import os
import boto3

client = boto3.client('sns')
TARGET_ARN = 'arn:aws:sns:ap-northeast-1:12345678910:[SNSTopic名]'
HTTP_RES = {"Message":"Forbidden"}

def lambda_handler(event, context):
    try:
        path = event['rawPath']
    except:
        path = None

    if  path == '/':
        try:
            token = event['queryStringParameters']['AuthId']
        except:
            token = None
      
        try:
            env = os.environ['AuthId']
        except:
            env = 'NotSet'
            
        if token == env:
            message = 'OK'
            subject = '簡易監視' + message
      
            request = {
                'PhoneNumber': TARGET_ARN,
                'Message': message,
                'Subject': subject
            }
      
        else:
            message = 'NG'
            subject = '簡易監視' + message
      
            request = {
                'PhoneNumber': TARGET_ARN,
                'Message': message,
                'Subject': subject
            }
            
        response = client.publish(**request)

    else:
        pass
    
    return HTTP_RES

if __name__ == '__main__':
    lambda_handler("event", "context")