pyenv, python3, lambda-uploader で AWS Lambda にアップロードする。

AWS Lambdaの開発環境が必要になったので整備する。

Lambda が Python3に対応したため、Python3 環境で。

下記記事を参考にしました。

LambdaでAWSの料金を毎日Slackに通知する(Python3)

AWS側準備

IAMユーザのロールに以下ポリシーをアタッチしておく。

  • CloudWatchReadOnlyAccess

ローカルPC

pyenvとpyenv-virtualenvを使います。

$ brew install pyenv pyenv-virtualenv

以下のディレクトリ内で全て行います。

$ mkdir aws
$ cd aws

必要な Pythonのバージョンをインストールしておきます。

$ pyenv install 3.6.1
$ pyenv install 2.7.13

一旦3.6.1に切り替えます。

$ pyenv local 3.6.1
$ pyenv rehash

lambda用の Python仮想環境を作成します。

$ pyenv virtualenv --python ~/.pyenv/versions/3.6.1/bin/python3.6 lambda

2つ作成されていますが、lambdaは 3.6.1/envs/lambda のシンボリックリンクなので、実質ひとつです。

$ pyenv versions
* system
2.7.13
3.6.1
3.6.1/envs/lambda
lambda

この1つめ lambda が デフォルトの python コマンドに設定されます、この場合だと python3.6.1になります

$ pyenv local lambda 2.7.13

$ python --version
 Python 3.6.1

必要なライブラリをインストール。

pip install lambda-uploader awscli

aws用の設定を行います。
下記コマンド実行後、アクセスキーやシークレットキーを入力します。
※IAMユーザより取得してください

aws configure

アップロードするプログラムは、下記のをほぼそのまま流用しました。。

LambdaでAWSの料金を毎日Slackに通知する(Python3)

ファイルを配置したディレクトリ内で以下のコマンドを実行。

$ lambda-uploader
λ Building Package
λ Uploading Package
λ Fin

AWS側設定

Lambda

Lambda 関数に、アップしたプログラムが作成されていることを確認します。

ランタイムが Python2.7 になっているため Python3 に修正する。
※lambda.jsonで設定可能

作成した関数を選択→設定→ランタイム

設定したらテストし、Slackに通知が来ていることを確認。

CloudWatch

ルール→ルールの作成から

イベントリソース→スケジュール→クロン→「0 0 ? * * *」(1日1回設定)

ターゲット→Lambda関数→作成した関数名

Exception: virtualenv returned unsuccessfully

パッケージのビルドに失敗。virtualenvの作成に失敗したようです。

$ lambda-uploader
λ Building Package
⁉️ Unexpected error. Please report this traceback.
Uploader: 1.2.0
Botocore: 1.4.5
Boto3: 1.5.95

Traceback (most recent call last):
File "/Users/runble1/work/aws/aws-upload/lib/python3.6/site-packages/lambda_uploader/shell.py", line 193, in main
_execute(args)
File "/Users/runble1/work/aws/aws-upload/lib/python3.6/site-packages/lambda_uploader/shell.py", line 84, in _execute
venv, cfg.ignore, extra_files)
File "/Users/runble1/work/aws/aws-upload/lib/python3.6/site-packages/lambda_uploader/package.py", line 49, in build_package
pkg.build(ignore)
File "/Users/runble1/work/aws/aws-upload/lib/python3.6/site-packages/lambda_uploader/package.py", line 76, in build
self.install_dependencies()
File "/Users/runble1/work/aws/aws-upload/lib/python3.6/site-packages/lambda_uploader/package.py", line 148, in install_dependencies
self._build_new_virtualenv()
File "/Users/runble1/work/aws/aws-upload/lib/python3.6/site-packages/lambda_uploader/package.py", line 181, in _build_new_virtualenv
raise Exception('virtualenv returned unsuccessfully')
Exception: virtualenv returned unsuccessfully

「Exception: virtualenv returned unsuccessfully」でググって以下 issue にたどり着きました。

UTF-8 Error · Issue #47 · rackerlabs/lambda-uploader
Once I had lambda-uploader working I wrote a little utility script to copy my function.py to a '.λ' directory with its lambda.json. Basically, I wanted to be ab...

viertualenv一度手動で試したら?と書いてあったので試す。
→失敗、virtualenv 関係ありませんでした。

$ python -m virtualenv lambda-virtual
$ source lambda-virtual/bin/activate
$ lambda-uploade

デバッグを表示させてみます。
→python2 コマンドがないって怒られてる。

$ lambda-uploade -VV

INFO:lambda_uploader.package:Building new virtualenv and installing requirements
 DEBUG:lambda_uploader.package:Virtualenv stdout: b'Running virtualenv with interpreter /Users/runble1/.pyenv/shims/python2\n'
 DEBUG:lambda_uploader.package:Virtualenv stderr: b"pyenv: python2: command not found\n\nThe `python2' command exists in these Python versions:\n 2.7.13\n\n"

python2 コマンドがないの?

$ python2 --version
pyenv: python2: command not found

The `python2' command exists in these Python versions:
 2.7.13

ないのでいれて、pyenv側でも使うことを明示します。

$ pyenv install 2.7.13

$ pyenv local 3.6.1 2.7.13

$ python --version
Python 3.6.1
$ python3 --version
Python 3.6.1
$ python2 --version
Python 2.7.13

これでエラーは出なくなりました。

参考

LambdaでAWSの料金を毎日Slackに通知する(Python3)

コメント

タイトルとURLをコピーしました