俺のアウトプット

調べたこと、試したことを書きます

AWS Cloud9上で作成したLambda関数で環境変数を利用する

Lambdaコード内で、設定値を切り替えたい場合があります。

例えば、本番環境と検証環境で接続先を変えたい、などです。

このような場合、環境変数に値を設定して、コード内から環境変数を参照します。

特定の言語に依存せず参照できますし、コードから定数が消えるので、セキュリティ的にもGoodです。

AWS Serverless Application Model

しかし .bash_profile に環境変数を追加しても、Lambda関数内から取得はできません。

AWS Cloud9 EC2環境には、AWS Serverless Application Model (SAM) がデフォルトでインストールされています。

$ sam --version
A newer version of the AWS SAM CLI is available!
Your version:   0.2.11
Latest version: 0.6.0
See https://github.com/awslabs/aws-sam-local for upgrade instructions

sam version 0.2.11

実は、AWS Cloud9上で作成したLambda関数は、このSAMを利用しており、Lambda関数内から環境変数を利用する場合は、SAM用のテンプレート template.yaml に追記する必要があります。

ローカル上にLambda関数を作成

環境変数を定義して、コードから参照できるか試してみましょう。

まずはLambda関数を作成します。

右側サイドバーにある、[AWS Resources] を選択して [AWSリソース] ウィンドウを開き、[λ+] ボタンをクリックします。

  • 関数名
    • checkSite
  • アプリケーション名
    • CheckSite
  • ランタイム
    • Python 3.6
  • 設計図
    • lambda-canary-python3
      • 指定したサイトを定期的にチェック、テスト失敗時にエラー
  • 関数トリガー
    • none
  • メモリ
    • 128MB
  • ロール
    • 自動生成(Automatically generate role)

AWS Cloud9上に、CheckSiteディレクトリが作成されます。

Lambda関数

作成されたLambda関数です。

デフォルトの状態で、環境変数を参照しています。 このまま利用します。

lambda_function.py

import os
from datetime import datetime
from urllib.request import urlopen

SITE = os.environ['site']  # URL of the site to check, stored in the site environment variable
EXPECTED = os.environ['expected']  # String expected to be on the page, stored in the expected environment variable


def validate(res):
    '''Return False to trigger the canary

    Currently this simply checks whether the EXPECTED string is present.
    However, you could modify this to perform any number of arbitrary
    checks on the contents of SITE.
    '''
    return EXPECTED in res


def lambda_handler(event, context):
    print('Checking {} at {}...'.format(SITE, event['time']))
    try:
        if not validate(str(urlopen(SITE).read())):
            raise Exception('Validation failed')
    except:
        print('Check failed!')
        raise
    else:
        print('Check passed!')
        return event['time']
    finally:
        print('Check complete at {}'.format(str(datetime.now())))
  • 環境変数 siteexpected から値を取得
    • site: チェックするサイトのURL
    • expected: HTMLに含むチェックするキーワード
  • 入力値
    • time: チェックする日時を指定

template.yaml

[環境] ウィンドウから、CheckSiteディレクトリ直下の template.yaml をダブルクリックして、SAM用のテンプレートを [タブ] ウィンドウに表示します。

Propertiesに Environment / Variables キーに、環境変数を追記して保存します。

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
  checkSite:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: checkSite/lambda_function.lambda_handler
      Runtime: python3.6
      Description: ''
      MemorySize: 128
      Timeout: 15
      CodeUri: .debug/
      Environment:
        Variables:
          site: 'https://oreout.hatenablog.com'
          expected: '2018-09-29'

f:id:kitsugi:20180930170054p:plain

ローカル上のLambda関数を実行

正しく動作するか、ローカル上で確認をします。

  1. [Local Functions] 内のLambda関数checkSiteを右クリックしてメニュー表示
  2. [Run] - [Run Local] を選択
  3. [Payload] ペインに入力値を設定して [Run] ボタンをクリック

ブログトップに指定した日付のエントリがあるかどうかを確認します。

見つかった場合

環境変数 expected にトップページに存在するキーワードを設定

Payload

{
    "time": "2018/09/30 17:00"
}

Response

"2018/09/30 17:00"

f:id:kitsugi:20180930170112p:plain

見つからなかった場合

環境変数 expected にトップページに存在しないキーワードを設定

Payload

{
    "time": "2018/09/30 17:00"
}

Response

{
    "errorMessage": "Validation failed",
    "errorType": "Exception",
    "stackTrace": [
        [
            "/var/task/checkSite/lambda_function.py",
            24,
            "lambda_handler",
            "raise Exception('Validation failed')"
        ]
    ]
}

f:id:kitsugi:20180930170127p:plain

意図した通りに実行されました。

AWS上でLambda関数を実行

ローカル上のLambda関数をAWS上にデプロイして実行します。

デプロイ

  1. [Local Functions] 内のLambda関数checkSiteを右クリックしてメニュー表示
  2. [Deploy] を選択

Lambda関数のリモート実行

  1. [Local Functions] 内のLambda関数checkSiteを右クリックしてメニュー表示
  2. [Run] - [Run Remote] を選択

AWS Lambdaコンソール画面上で、環境変数が設定されていることが確認できます。

f:id:kitsugi:20180930170141p:plain

参考