エンジニアレポート

AWS LambdaをCodePipelineでデプロイする

2020年07月31日 PythonAWSLambdaCodePipeline

こんにちは、フットボール事業部の猪ノ口です。

最近AWS Lambda上でPythonを動かすことがあったのですが、pandasなどの外部ライブラリを使用するため、ローカルでライブラリをZipにしてアップロードする必要がありました。ライブラリによってはWindowsでデプロイパッケージを作成するとLambdaではエラーが発生したりと、やや手間に感じていました。そこでリポジトリにプッシュすると、外部ライブラリも含め自動でデプロイされるようなパイプラインを作成してみました。クライアントがWindowsでもMacでも、手順は同じです。

構成図は以下の通りです。

1. CodeCommitリポジトリの作成

まずはCodeCommitでソースコードを管理するリポジトリを作成します。このリポジトリへプッシュすると、自動でLambdaへデプロイされることになります。

コンソールのCodeCommitから、「リポジトリを作成」を選んで任意の名前で作成すればOKです。

作成が完了するとこのような画面が表示されます。合わせて「接続のステップ」が表示されるので、それに沿ってリポジトリをクローンします。

詳細は割愛しますが、おおまかには

  1. 事前にAWS CLIとGitのインストールを行う
  2. AWS CLIで使用するIAMユーザにて、「HTTPS Git credentials for AWS CodeCommit」から認証情報を取得する
  3. ローカルの任意のディレクトリでGit cloneを実行する

となります。

2. ソースコード、ビルド仕様、デプロイ仕様の作成

次に、ソースコード、ビルド・デプロイ仕様(後に使用)を記述したファイルを作成します。以下のフォルダ構成と内容で、作成してください。

・lambda_function.py
Lambdaにデプロイするソースコードです。複数のファイルに分かれていても問題ありません。イベントハンドラとしてlambda_handlerを定義しています。また外部ライブラリも含めてデプロイできているか確認するため、pandasを適当に使用します。

・requirements.txt
依存ライブラリを定義します。今回はpandasだけ記述します。

・buildspec.yml
CodeBuildでのビルド仕様を定義します。ランタイムを指定し、デプロイパッケージを作成するためのコマンドを記述しています。

ビルドにはサーバーレスアプリケーションのビルド、パッケージを行うSAM CLIを使用します。

sam build、sam packageコマンドで依存ライブラリを含めたデプロイパッケージを作成し、指定のS3バケットに配置します。また後述のtemplate.ymlを元に、デプロイパッケージの配置先(指定したS3バケット内のパス)を定義したoutputtemplate.ymlを作成します。実際にローカルディレクトリでsamコマンドを実行すると挙動が分かりやすいと思います。 ここでバケット名やファイル名を誤るとビルドでエラーになるので、気を付けてください。


・template.yml
サーバーレスアプリケーションを構築するSAMテンプレートです。構成はLambda関数のみで、最低限の内容としています。もちろん他のリソースを追加で指定しても問題ありません。 CodeUriでソースコードのディレクトリを指定していますが、buildspec.ymlで定義した通り、sam packageコマンドでoutputtemplate.ymlが生成され、CodeUriはデプロイパッケージが生成されたS3のパスに変更されます。

以上のファイルを、先ほどクローンしたローカルリポジトリに保存し、以下のgitコマンドでプッシュします。

3. CodeBuildプロジェクトの作成

CodeBuildコンソールから新規プロジェクトを作成します。 ソースには先ほど作成したCodeCommitリポジトリを指定し、ブランチはmasterを選択します。コミットIDは不要です。

環境は以下の通り設定します。ビルド仕様には先ほど作成したbuildspec.ymlを読み込むよう設定します。

ビルドプロジェクトの作成が完了したら、合わせて作成されたIAMロールに、ポリシー”S3FullAccess”をアタッチします。buildspec.ymlに定義した通り、デプロイパッケージをS3に配置するためです。

4. CloudFormation用IAMロールの作成

デプロイにはCloudFormationを使用します。スタックを事前に作成する必要はありませんが、CloudFormation用のIAMロールを用意します。

以下のポリシーをアタッチしておきます。

・AWSLambdaFullAccess(Lambda関数の作成)

・IAMFullAccess(Lambda関数IAMロールの作成)

・AmazonS3ReadOnlyAccess(デプロイパッケージの取得)

・AWSCloudFormationFullAccess(変更セットの作成・置換・実行)

例えばAPI GatewayやS3を作成するなど、CloudFormationテンプレートによっては他のポリシーが必要になりますので、適宜追加してください。

5. CodePipelineの作成

最後に、CodePipelineコンソールでデプロイパイプラインを作成します。 ソースステージには先ほど作成したCodeCommitリポジトリを指定してください。

ビルドステージには先ほど作成したCodeBuildプロジェクトを指定してください。

デプロイステージではデプロイプロバイダーにCloudFormationを選択します。

アクションモードは、変更内容をスタックに反映するため「変更セットを作成または交換する」を選択します。スタック名、変更セット名は任意の名前で、現時点では存在しないもので問題ありません。

テンプレートはbuildspec.ymlで定義したoutputtemplate.ymlを指定します。

能力には、CAPABILITY_IAMとCAPABILITY_AUTO_EXPANDを指定します。CAPABILITY_IAMはLambda関数と合わせてIAMロールを作成するため、CAPABILITY_AUTO_EXPANDは、NestedApplicationsを作成する場合に必要とのことで、今回は不要ですが追加しておきます。

ロールは先ほど作成したものを指定します。

パイプラインを作成すると自動でリリースが始まります。しかし以上の設定だけでは変更セットが作成されるだけで、変更セットが既存リソースに反映されません。そのため変更セットの作成を追加します。新しいアクションとして、変更セットの実行をデプロイステージに追加します。

パイプラインの編集から、デプロイステージを編集します。

アクションプロバイダーにCloudFormationを設定し、アクションモードを「変更セットの実行」にします。スタック名と変更セット名は先ほどのものと同じにしましょう。

デプロイステージはこのようになります。

これでパイプラインの設定は完了です。「変更をリリースする」を押してみましょう。成功すればこのようになります。

ビルドで失敗した場合、S3バケットが存在するか、IAMロールでS3へのアクセスが許可されているか確認しましょう。デプロイで失敗した場合、IAMロールのポリシーが不足している可能性が高いです。buildspec.ymlやtemplate.ymlの中身もよく確認してください。私はスペルミスに気付かず、ずっと悩んでいました…

6. Lambdaの実行確認

早速、Lambdaをテスト実行してみます。pandasのdataframeがprintされていますね。以上でCodeCommitにプッシュすると、自動でLambdaがデプロイされるようになりました。

7. パイプライン実行後の確認

少し内部の動きを見てみましょう。

まずはCloudFormationからスタックのテンプレートを確認します。template.ymlではディレクトリを参照していたCodeUriが、S3のパスに変わっていることが分かります。

実際にS3のバケットを見てみると、デプロイアーティファクトができていました。buildspec.ymlでzipと指定したので、ここはzipファイルができると思っていたのですが、どうやら違うようです。

以上でパイプラインの設定は終了です。ローカルで開発しながら、そのままデプロイできるようになり、非常に簡便になりました。

参考資料

AWS CodePipeline を使用して Lambda アプリケーションの継続的な配信パイプラインを構築する:

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/build-pipeline.html

エンジニア募集中

データスタジアムでは一緒に働いていただけるエンジニアを絶賛募集中です!

野球、サッカー、バスケをはじめとして色々なスポーツの仕事があります。

AWSやAzure、動画やAIなど技術的にもチャレンジできる職場です。

テクノロジーの力で、日本のスポーツを一緒に発展させていきましょう!

<募集中のポジション(2020年8月1日現在)>

開発エンジニア(速報サービス)

開発エンジニア(スポーツチーム向けサービス)

インフラエンジニア

最新記事

エンジニアトップ エンジニアインタビュー エンジニアレポート

  • 採用情報
  • おしらせ
  • 掲載事例

ページトップヘ