5
7

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 5 years have passed since last update.

AWS Lambda(Python3 boto3)をローカル環境で構築してからアップしよう

Last updated at Posted at 2017-11-29

#はじめに
AWS Lambda(Python3)を構築する際、直接Lambda関数の画面で作業してもいいのですが、デバッグしづらいし、エディタは使いづらい。
その為、ローカル環境で一度作成してから、AWS Lambdaへアップする方法を記載します。

→2017/12/02追記
AWSアップデートされCould9なんてものが追加されたし、AWS Lambdaエディタ機能も追加されたので、今後はブラウザ上だけで充分かもね(´・ω・`)


##環境
各インストール方法はぐぐってね。
OSはWindows10 Proにて確認。

事前にAWS AMIアカウントから「アクセスキー」、「シークレットアクセスキー」を発行後
コマンドプロンプト「aws configure」で登録してね。

$ aws configure
aws_access_key_id = アクセスキー
aws_secret_access_key = シークレットアクセスキー
region = ap-northeast-1
output = json

###ATOMアドオン

  • atom-beautify スクリプト整形用※
  • atom-runner Python実行用★必須
  • autocomplete-python Python補完用※
  • file-icons アイコンが変わるよ
  • highlight-selected 選択文字列ハイライト表示※
  • japanese-menu ATOM日本語化※
  • minimap  スクロールバー※
  • python-autopep8 Python補完用
  • show-ideographic-space 全角スペース表示用※
  • symbols-tree-view 関数、変数一覧表示
  • web-search ATOMからWeb検索用

atom-runnerはATOM上でPythonを実行するのに必須。※印はお勧めアドオンです。


##動作確認(Python3コード)
以下コードをコピーし、適当なファイル名+拡張子(.py)で作成後、「ALT+R」でPythonを実行。
稼働中のEC2インスタンスIDとTag名(サーバー名)を取得します。

import boto3
import json

ec2c = boto3.client('ec2')

##############################################
#起動しているインスタンスID取得
##############################################
def func_GetInstanceId():

    instanceid_List = []
    retec2c = ec2c.describe_instances(
        Filters=[
            {'Name':'instance-state-name','Values': ['running']}
        ]
    )
    for reservation in retec2c['Reservations']:
      for instanceid in reservation['Instances']:
        instanceid_List.append(instanceid['InstanceId'])

    return instanceid_List
##############################################
#インスタンスIDからタグ名取得
#引数:インスタンスID(i-1234567890ABCDEFG) 
#戻り値:タグ名 Win2016_SV、未設定の場合は「サーバー名未設定」
##############################################
def func_RET_ServerTagName(SET_InstanceId):

    TagName = ec2c.describe_tags(
        Filters=[
        {'Name': 'resource-id', 'Values': [SET_InstanceId]}
        ,{'Name': 'tag-key', 'Values': ['Name']}
        ])
    try:
        RET_ServerTagName=TagName['Tags'][0]['Value']
    except Exception as e:
        RET_ServerTagName="サーバー名未設定"
    return RET_ServerTagName

################################
# MAIN
################################
#def lambda_handler(event, context):
if __name__ == "__main__":

    #起動中のEC2インスタンスIDを取得
    insid_list=func_GetInstanceId()

    for insid in insid_list:
        #インスタンスIDからTag名(サーバー名)を取得    
        ins_name=func_RET_ServerTagName(insid)
        print(ins_name + "(" + insid + ")")

##出力例
以下インスタンスIDは適当に書き換えています

Win2016SV1(i-123456789ABCDEFG)
サーバー名未設定(i-123456789)
Windows2012SV2(i-0123456789abcd)

##AWS Lambdaにアップする際に修正する箇所

if __name__ == "__main__":

をコメントアウトし

def lambda_handler(event, context):

を有効にしましょう。

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

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

あとはAWS Lambdaにコピペして動作を確認。

#時刻取得その1
時刻を取得する際、ローカル環境ではOSの時刻を取得する為、JSTで取得できますが
Lambda上はGMTで取得する為、+9時間する必要がありますよ。

import datetime

#Lambda上で実行する場合
#def lambda_handler(event, context):

#ローカルで実行する場合
if __name__ == "__main__":

    #ローカルで実行する場合
    d = datetime.datetime.now()

    #Lambda上で実行する場合
    #d = datetime.datetime.now() + datetime.timedelta(hours=9)

    print("d時間:" + str(d))

#時刻取得その2
もしくは環境変数キー名「TZ」値「Asia/Tokyo」を追加すればJSTで取得する為、上記の様に+9時間しなくても大丈夫。

##グローバル変数で時刻を取得すると・・・だれかが死ぬ
日付時刻を取得する際、関数内で取得せず、グローバル変数として取得した場合、
AWS Lambda上2回目の動作以降に同じ時間を取得するはめになりますので注意。

※障害例
時刻取得処理をトリガーにて9:00開始、10分毎に実行した際、
9:00に実行した場合は、初回に実行する為「9:00」と正確に取得しますが、次回9:10に実行した際にも「9:00」と取得される。9:20以降もずーっと「9:00」で取得されてしまう。

またこれがLambdaテスト実行時には再利用されないため障害は発生せず、トリガーで定期的に実行すると発生するやっかいなヤツ。

・2回目以降のLambdaを再利用している為発生する模様。
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-introduction.html

#時刻取得(正)

import datetime

def lambda_handler(event, context):
    d = datetime.datetime.now() + datetime.timedelta(hours=9) # ◎関数内の為毎回取得します。
    print("d時間:" + str(d))

#時刻取得(誤)

import datetime

d = datetime.datetime.now() + datetime.timedelta(hours=9) # ×グローバル変数で取得しちゃダメ

def lambda_handler(event, context):
    print("d時間:" + str(d))

以上

5
7
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
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?