CodePipelineを使ってLambdaに自動デプロイ


概要

Lambdaの関数が増えてくると修正のたびにコンソールで修正したり、ローカルのPCで修正したソースをzipに固めてコンソールでアップする作業って結構大変ですよね!!
ってことでCodePipelineを使ってgitにpush(merge)されたタイミングでLmabdaにデプロイしたときの話を書いていきます。

処理の流れ

  1. Lambdaに関数を登録(Hello World)
  2. GithubにLambda用のコードをpush
  3. CodePipelineのSourceでソースの取得
  4. CodePipelineのBuildでテストの実行など(今回はテストの実行はしない)
  5. CodePipelineのDeployでLambdaにデプロイ

Lambdaに関数を登録

LambdaにHello Worldの関数を登録

関数の作成ボタンから関数の作成

今回はpython3.8

こんな感じ

Githubにリポジトリを作成とソースのpush

Githubに適当なリポジトリを作成しHello Worldを登録

先ほど作ったLambdaのコードをどうにかしてGitに登録

CodePipelineのSourceでソースの取得

CodePipelineでパイプラインを作成する

パイプライン名を入力しあとはデフォルト

次にソースの追加
Githubを選んで接続後、リポジトリとブランチを選択

次はビルド
CodeBuildを選択、ビルド用のプロジェクトを作ってないので「プロジェクトの作成」をクリック

ポップアップが開くので、色々入力

完了すると、プロジェクト名のところに勝手に入力される

最後デプロイですが、アプリケーションを作ってないので、一旦スキップする

パイプラインが実行される

Gitにbuildspec.ymlをあげてないので、Buildは失敗する、改めてbuildspec.ymlを作ってGitにpushする

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - ls
artifacts:
  files:
    - "**/*"

ビルドも成功しました。コードテストも実行したいが今回は割愛

CodePipelineのDeployでLambdaにデプロイ

CodeDeployでアプリケーションを設定する
アプリケーションの作成をクリック

コンピューティングプラットフォームを「Lambda」にする

先ほど作ったアプリケーションでデプロイグループを作成する今回は「dev」としています

今後はパイプラインに戻ってステージを追加する

デプロイ用のアクションお追加を行う、アプリケーション名とデプロイグループのところはCodeDeployで作った物を選択する

appspec.ymlを追加する、ビルド時に動的に生成するため{{xxxx}}のように記載します

appspec.yml
version: 0.0
Resources:
  - HelloWorld:
      Type: AWS::Lambda::Function
      Properties:
        Name: "HelloWorld"
        Alias: "dev"
        CurrentVersion: "{{CurrentVersion}}"
        TargetVersion: "{{TargetVersion}}"

参照:https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-example.html#appspec-file-example-lambda

buildspec.ymlの変更を行う

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - CurrentVersion=$(echo $(aws lambda get-alias --function-name HelloWorld --name dev | grep FunctionVersion | tail -1 |tr -cd "[0-9]"))
  post_build:
    commands:
      - ls
      - aws lambda publish-version --function-name HelloWorld
      - TargetVersion=$(echo $(aws lambda list-versions-by-function --function-name HelloWorld | grep Version | tail -1 | tr -cd "[0-9]"))
      - echo $CurrentVersion
      - echo $TargetVersion
      - sed -i -e "s/{{CurrentVersion}}/$CurrentVersion/g" appspec.yml
      - sed -i -e "s/{{TargetVersion}}/$TargetVersion/g" appspec.yml

artifacts:
  files:
    - "**/*"

buildspec.yml内でaws lambdaコマンドを実行するので、CodeBuildで使うロールにポリシーを追加する

iam
"lambda:PublishVersion"
"lambda:GetAlias"

Lambdaのaliasを作る


変更をリリースするをクリックしてパイプラインを実行する

実行結果

失敗!!!!

BundleType must be either yaml or json????

artifactの中にあるし、色々試したけど解決せずサポートに問い合わせると、artifactで保存されるファイルはzipで圧縮されるので、そうするとappspec.ymlが参照できないらしい
って無理じゃん!!!
現時点ではデプロイでCloudFormationを使うしかないということです、無駄足でした。

最後に

ここまでみて頂いた方ありがとうございます
ただデプロイしたいだけで、3日も溶かしてしまった、どうしてもこのやり方でやりたい方は
https://github.com/aws-samples/aws-serverless-workshop-greater-china-region/tree/master/Lab8A-CICD-CodePipeline
ここを参考にどうぞ、デプロイはCodeDeployじゃなくてLambdaを実行しているけどね・・・