1. はじめに
クラウドインテグレーション部の千葉です。
Python が好きなので、Lambda を使った開発の際は Serverless Framework に aws-python3
のテンプレートを当てて使っています。
ただ、Serverless Framework 自体が Node.js で動いているので、ちょっとしたタスクをやらせるダケなのにファイルや README.md の内容が増えちゃってウンザリしちゃうんです。
そんなワケで『基本は Serverless Framework』としつつ『定期的にSalesforceのレコード検索して結果をSlackに投稿する』的な、ちょっとしたモノは Python のみでサクっと作っちゃいたい。と思い、 aws / serverless-application-model(以下、SAM) をつかった開発の流れを整理しておくことにしました。
例として、2人のチームで 毎週金曜日の 10:00(JST) に OpenWeatherMap で任意の場所の天気を Lambda のログに出力する って処理を実装するイメージで解説していきます。
(Salesforceのレコード検索して結果をSlackに投稿 だと、コードの説明が長くなっちゃいそうなので簡易的なものにしました)
以下、2人の参加者を便宜的にリーダー / メンバーと表現します。
2. リーダーの作業
2-1. Python 3.8.6 環境に pipenv / aws-sam-cli をインストール
$ pyenv install 3.8.6 $ cd /tmp $ pyenv local 3.8.6 $ pyenv install pipenv $ pyenv install aws-sam-cli
2-2. SAM プロジェクトの作成・移動
$ sam init --runtime python3.8 --app-template hello-world --output-dir ~/Developments --name owm-example $ cd ~/Developments/owm-example
2-3. pipenv 仮想環境の構築
$ pyenv local 3.8.6 $ pipenv --python 3.8.6 $ pipenv shell
2-4. パッケージのインストール
次のコマンドで --dev
オプションが付いているものは、開発環境にのみ必要なものとなります。
$ pipenv install aws-sam-cli --dev $ pipenv install flake8 --dev $ pipenv install python-dotenv --dev $ pipenv install pyowm
2-5. ディレクトリ構造、ファイル名の変更
SAM の hello-world
テンプレートの状態から、ディレクトリ構造・ファイル名の変更を実施します。
# 変更前の状態 . |-- Pipfile |-- Pipfile.lock |-- README.md |-- __init__.py -------------> 削除 |-- events ------------------> ディレクトリごと削除 | `-- event.json |-- hello_world -------------> src に変更 | |-- __init__.py ---------> 削除 | |-- app.py --------------> handler.py に変更 | `-- requirements.txt |-- template.yaml `-- tests -------------------> ディレクトリごと削除 |-- __init__.py `-- unit |-- __init__.py `-- test_handler.py # コマンドの実行 $ rm -rf events $ rm -rf tests $ mv hello_world src $ mv src/app.py src/handler.py $ rm __init__.py $ rm src/__init__.py
2-6. template.yaml の編集
SAM の hello-world
テンプレート用の状態から、以下の内容に書き換えます。
2-7. コード解析ツールの設定ファイルを作成
flake8 の設定ファイル (.flake8
)を以下の内容で作成します。
- 1行の長さが79文字以下の制限を無効
.aws-sam
以下を解析対象から除外
2-8. サンプル環境変数ファイル、開発用の環境変数ファイルの作成
開発時に必要になる環境変数のサンプルファイルを、以下の内容で作成します。
作成した sample.env を元に開発環境用の環境変数ファイルを作成します。
$ cp sample.env .env $ vim .env
OpenWeatherMap の自アカウントの API Key と、自分は住んでいるエリアに書き換えます。
2-9. バージョン管理除外ファイルの追記
Git リポジトリで管理したくないファイルを .gitignore
に追記します。
$ echo ".env" >> .gitignore $ echo ".aws-sam/" >> .gitignore $ echo "src/requirements.txt" >> .gitignore $ echo "samconfig.toml" >> .gitignore
2-10. メインのコード実装
src/handler.py
を、以下の内容で書き換えます。
ローカル環境での動作確認
$ python src/handler.py Yokohama,Jp - Current Weather: Clouds
2-11. ビルド、Docker環境での動作確認
以下のとおり、ビルドコマンドを実行して Build Succeeded が返ってくることを確認してください。
$ pipenv lock -r > src/requirements.txt; sam build Building codeuri: src/ runtime: python3.8 metadata: {} functions: ['WeeklyTask'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
Docker環境での動作確認
$ sam local invoke --parameter-overrides ApiKey=#{開発用のAPI Key} Place=Yokohama,Jp
2-12. 自分のAWS環境へのデプロイ
デプロイの実行(コマンド実行後のガイダンスに答えるかたちで進みます)
ApiKey と Place の値には、開発環境用の値を指定してください。
$ sam deploy --guided --parameter-overrides ApiKey=#{開発用のAPI Key} Place=Yokohama,Jp --stack-name WeeklyTaskDev
2-13. Git リポジトリへ Push
コード解析の実行
$ flake8
特にヘンなコードも無いようなので、GitHub や CodeCommit 等の適当な場所にリポジトリを作成して master
ブランチに Push します。
$ git init $ git remote add origin ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/owm-example $ git add . $ git commit -m "first commit" $ git push origin master
2-14. 本番AWS環境へのデプロイ
デプロイの実行(コマンド実行後のガイダンスに答えるかたちで進みます)
ApiKey
と Place
の値には、本番環境用の値を指定してください。
$ sam deploy --guided --parameter-overrides ApiKey=#{本番用のAPI Key} Place=Tokyo,Jp --stack-name WeeklyTaskProd --profile prod
3. メンバーの作業
3-1. Git リポジトリのクローン、移動
$ git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/owm-example ~/Developments/owm-example $ cd ~/Developments/owm-example
3-2. Python 3.8.6 の仮想環境構築、パッケージのインストール
$ pyenv install 3.8.6 $ pyenv local 3.8.6 $ pip install pipenv $ pipenv --python 3.8.6 $ pipenv shell $ pipenv sync --dev
3-3. 開発環境用の環境変数ファイルの作成
sample.env を元に開発環境用の環境変数ファイルを作成します。
$ cp sample.env .env $ vim .env
OpenWeatherMap の自アカウントの API Key と、自分は住んでいるエリアに書き換えます。
3-4. コードの改修
フィーチャーブランチの作成
$ git branch feature/add-datetime $ git checkout feature/add-datetime
src/handler.py
を編集して、現在のシステム日時を出力するようにしました。
ローカル環境での動作確認(末尾に日時が出力されるようになりました)
$ python src/handler.py Chiba,Jp - Current Weather: Clouds (2020-12-16 23:13:00.868971)
3-5. ビルド、Docker環境での動作確認
以下のとおり、ビルドコマンドを実行して Build Succeeded が返ってくることを確認してください。
$ pipenv lock -r > src/requirements.txt; sam build Building codeuri: src/ runtime: python3.8 metadata: {} functions: ['WeeklyTask'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
Docker環境での動作確認
$ sam local invoke --parameter-overrides ApiKey=#{開発用のAPI Key} Place=Chiba,Jp
3-6. Commit、Push、PullRequest の作成
コード解析の実行
$ flake8
特にヘンなコードも無いようなので、リモートリポジトリに Push します。
$ git add src/handler.py $ git commit -m "システム日時を出力するようにしました" $ git push origin feature/add-datetime
feature/add-datetime
ブランチ → master
ブランチへの PullRequest を作成。(GitHub Flow を想定)
3-7. 自分のAWS環境へのデプロイ
デプロイの実行(コマンド実行後のガイダンスに答えるかたちで進みます)
ApiKey と Place の値には、開発環境用の値を指定してください。
$ sam deploy --guided --parameter-overrides ApiKey=#{開発用のAPI Key} Place=Chiba,Jp --stack-name WeeklyTaskDev
3-8. 本番AWS環境へのデプロイ
デプロイの実行(コマンド実行後のガイダンスに答えるかたちで進みます)
ApiKey
と Place
の値には、本番環境用の値を指定してください。
$ git checkout master $ git pull origin $ sam deploy --guided --parameter-overrides ApiKey=#{本番用のAPI Key} Place=Tokyo,Jp --stack-name WeeklyTaskProd --profile prod
4. まとめ
なんだか長くなっちゃいましたが、ちょっとしたモノを Python のみでサクっと作りたいときの手順を整理してみました。
最終的なファイル構成は以下のとおりです。
. |-- .env --------------------> Git リポジトリ管理外 |-- .flake8 |-- .gitignore |-- Pipfile |-- Pipfile.lock |-- README.md |-- samconfig.toml ----------> Git リポジトリ管理外 |-- sample.env |-- src | |-- handler.py | `-- requirements.txt ----> Git リポジトリ管理外 `-- template.yaml
以上、おつかれさまでした。