yyp٩( 'ω' )و

色々触って遊んでます

GitHubにpushされたらLambdaのテストを自動で実行したい(願望)

背景・目標

前回の続き、Lambda関数の中身を作成しているのですが、
ローカルで編集→GitHubにpush→Lambdaコンソールにコピペしてテストという流れが結構面倒です。
Lambdaコンソールでテストしながらコードの修正をしてもいいのですが、そうすると自分がどこで間違ったのか残らないのでまた同じところで詰まりそうです。

なので、タイトルの通りGitHubにpushされたらLambdaのテストを自動で実行する仕組みを作りたいと思って試行錯誤中です。
この記事の結末としては、まだ実行環境は作れていないです。
解決方法を求めてここに辿り着いた方がもしいたら申し訳ありません。

環境

以前AWS上でのCI/CDハンズオンの勉強会に行ったことを思い出し、AWS CodePipelineで出来るような気がするので、一旦CodePipelineを使う方法で進めます。

Pipelineの作成

早速Pipelineを作っていきます。
CodePipeline > パイプライン > パイプラインを作成する で作成画面に移ります。

Step1 パイプラインの設定を選択する

この画面ではパイプラインの名前と、IAMロールを設定します。
パイプライン名はわかりやすい名前をつけて、ロールについてはパイプライン用のロールがまだないので、"New Service Role"を選んで新しく作ります。
こんな感じ↓
f:id:mizukichi3:20190429111120p:plain

Step2 ソースステージを追加する

この画面ではコードのソースを設定します。
今回はGitHubにpushされたらテストが動くように設定したいので、「ソースプロバイダー」はGitHubを選択します。
リポジトリ名とブランチ名はテストしたいリポジトリとブランチを選択します。
検出オプションはGitHubウェブフックを選択します。
GitHubウェブフックの説明文の「GitHub でウェブフックを使用して、変更が発生したときにパイプラインを自動的に開始」が今回やりたいことなので。
こんな感じです↓
f:id:mizukichi3:20190429112210p:plain

Step3 ビルドステージを追加する

この画面ではビルドする環境を追加します。
「プロバイダーを構築する」ではAWS CodeBuildとJenkinsが選択できるようになっています。
今回はAWS CodeBuildを使ってみたいと思います。
リージョンはTokyoを選択し、「プロジェクトを作成する」をクリックすると、ビルド環境の作成ページに移ります。
f:id:mizukichi3:20190429112814p:plain

ビルド環境の作成

この画面では実行環境を作成していきます。
Project configurationではProject nameにわかりやすい名前をつけます。
EnvironmentではManaged imageを選択し、各パラメータを↓のように設定します。
f:id:mizukichi3:20190429113902p:plain すぐ下にある「追加設定」と"Buildspec"はデフォルトのままにしています。
"Logs"はCloudWatch logsにチェックを入れます。
ここまで設定したら、"Continue to CodePipeline"をクリックしてからCodePipelineの作成ページに戻ります。
↓のように正常に作成されたメッセージが表示されていればOKです。
f:id:mizukichi3:20190429114846p:plain

Step4 デプロイステージを追加する

この画面ではデプロイ先を設定します。
今回はCodeDeployを使ってLambdaにデプロイしたいと思います。

CodeDeployでアプリケーションを作成する

まずCodeDeployでデプロイするアプリケーションの設定をします。
一旦CodeDeployの画面を別タブで開き、「アプリケーションの作成」をクリックして作成画面に移ります。
アプリケーション名にわかりやすい名前をつけて、「コンピューティングプラットフォーム」でAWS Lambdaを選択します。
f:id:mizukichi3:20190429115535p:plain 次にデプロイグループを作成します。
デプロイグループ名はわかりやすい名前をつけます。
サービスロールは"AWSCodeDeployForLambda"のポリシーを付与したロールをIAMコンソールで作成して選択します。
デプロイ設定は一旦デフォルトのままにします。
下の方にある「詳細」もデフォルトのままにします。
これでCodeDeploy側の設定は完了したので、デプロイステージの追加画面に戻ります。
アプリケーション名とデプロイグループで先ほど作ったものを選択します。

Step5 レビュー

設定内容を確認して、「パイプラインを作成する」で完了です。
作成後すぐにパイプラインが動きますが、初回だからということだと思います。
今後はpushしたら動く感じになるはずです…!

CodePipelineを動かしてみる

とりあえずHelloWorldでpushしてみます。
コードはLambdaを作成した時に最初に書いてあるものを使いました。

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

pushするとパイプラインが動き始めましたが、Buildの段階で失敗してしまいました。
詳細をみてみると、 YAML_FILE_ERROR: YAML file does not existというエラーが出ています。
buildspec.ymlを作ってGitHubに置かないといけないっぽいですね。

buildspec.ymlを作成

とりあえずこんな感じで作ってみました。
参考: docs.aws.amazon.com

version: 0.2

phases:
  install:
    commands:
      - pip install boto3
artifacts: 
  files:
    - '**/*'

今度はビルドは成功しましたが、デプロイに失敗しました。
詳細をみてみると、BundleType must be either YAML or JSONというメッセージが出ています。
調べてみると、appspec.ymlというファイルが必要みたいです。

appspec.ymlを作成

こちらを参考にappspec.ymlを作成してみました。

docs.aws.amazon.com

作成したappspec.ymlはこちら。

version: 0.0
resources:
  - name-of-function-to-deploy:
    type: "AWS::Lambda::Function"
    properties:
      name: HelloWorld
      alias: HelloWorld
      currentversion: "1"
      targetversion: "1"
hooks:
  - BeforeAllowTraffic: "LambdaFunctionToValidateBeforeTrafficShift"
  - AfterAllowTraffic: "LambdaFunctionToValidateAfterTrafficShift"

こちらのファイルをpushしてみましたが、また同様のBundleType must be either YAML or JSONというメッセージが出てしまいました。
どうにも原因がわからないので、CodeDeployから手動でデプロイしてみます。
するともう少し詳し目のエラーメッセージが出ました。

The deployment failed because the AppSpec file that specifies the AWS Lambda deployment configuration is missing or has an invalid configuration. The input AppSpec file is a not well-formed yaml. The template cannot be parsed.

ymlファイルがどこか間違っているみたいです。
ここからはymlファイルを直しても全然進むことができなかったため、一旦保留にしたいと思います。
本当にやりたいのはLambdaを動かすことで、こちらの環境構築をやっているとLambdaの方が進まなくなっちゃいそうなので…

こちらの記事は自分用の手順書として残しておくことにします…
前回の記事のLambdaが作り終わったらこちらを再開してみようかなと思います。