AWS Lambdaのアプリケーション作成を使ってCI/CDパイプラインを一気に構築

Source-Build-Deploy

AWS Lambdaのアプリケーション作成とは

AWS Lambdaのアプリケーション作成機能を利用してLambda関数を作成すると、Lambda関数自体の他に

  • Lambda関数のソースコード等を管理するGitリポジトリとしてCodeCommit
  • CodeCommitのmasterブランチの更新を契機にLambda関数へのデプロイを行うCodePipeline

等々、CI/CDパイプライン実現のためのAWSリソースが同時に作成されます。

Lambda関数自体は手軽に作ったものの、次のステップとしてCI/CD環境を構築するのは腰が重く、ソースの更新はマネジメントコンソール上で実施している・・・といったケースを改善するアプローチとして、このようなCI/CD環境をセットで構築する機能がリリースされたそうです。

Lambdaのマネジメントコンソール画面では、これらAWSリソースをアプリケーションという単位で取り扱います。

(実際には、CloudFormation(以下、CFn)によって作成されており、CFnの画面からも作成されたスタックが確認できます)

なお、利用可能なランタイムは現時点ではNode.js 10.xに限定されており、GoやPython等は使えません。

実際に使ってみる

本記事では、このアプリケーション作成機能を使い、Lambda関数とCI/CDパイプラインを構築します。

そしてLambda関数に対して、簡単な機能(今回はオウム返しLINE Botとします)を、CI/CDパイプラインを通じてデプロイしてみます。

アプリケーションの作成へ進む

マネジメントコンソールのLambdaの画面から、アプリケーションの作成を押します。

Lambda画面

サンプルアプリケーションを選択するか、一から作る

すると、いくつかのサンプルアプリケーションが表示されます。

サンプルアプリケーションの選択画面

例えば、一番左上のServerless API Backendの場合、API Gateway + Lambda * 3 + Dynamo DBで構成されるサンプルアプリケーションとなります。

今回は、Lambda + API Gatewayのシンプルな構成を作成したかったので、一番右下にある一から作成を選択しました。

一から作成

アプリケーションの設定

続いて、アプリケーションの設定を行います。

今回は、LineBotを作成しようと思うので、アプリケーション名はnodejs-linebotにします。

ランタイムは、Node.js 10.xしか選択できないので、これを選択します。

アプリケーションの詳細と関数の設定

また、ソース管理を行うGitリポジトリをCodeCommitとGitHubから選択します。

今回はシンプルにAWSで完結可能となるよう、GitHubではなくCodeCommitを選択しました。

リポジトリ名入力後、最後にアクセス権限に関するチェックボックスにチェックを入れて、作成を押します。

Lambdaアプリケーション作成のための操作としては、たったこれだけです。

アプリケーションの作成開始

作成を押した後は、作成中のアプリケーション画面へ遷移します。

裏では、CFnにより各リソースが作成されています。

作成完了まで数分かかるので、その間はEric Johnsonさんの解説動画を見るなどして完了を待ちましょう。

アプリケーションの作成完了

CFnによる各リソースの作成が完了すると、Lambdaアプリケーション画面の下の方に作成されたAWSリソースが表示されます。

Lambdaアプリケーションでは、リソースとインフラストラクチャという2つのカテゴリに分けてAWSリソースが作成されています。

一方、CFnの画面を見ると、2つのスタックが作成されています。

  • 前述のリソースは、Lambdaアプリケーション名そのままのnodejs-linebotスタック
  • 前述のインフラストラクチャは、もうひとつのserverlessrepo-nodejs-linebot-toolchainスタック

によって作成されたものとなります。

Lambda関数を確認する

Lambda関数も画面から確認してみます。

ディレクトリ、ファイル構成は以下の通りとなっています。

サンプルのJavaScriptのhello-from-lambda.jsのほか、CodeBuildに必要なbuildspec.ymlなどが作られていることがわかります。

.
├── LICENSE
├── README.md
├── __tests__
│   └── unit
│       └── handlers
│           └── hello-from-lambda.test.js
├── buildspec.yml
├── package.json
├── src
│   └── handlers
│       └── hello-from-lambda.js
└── template.yml

Lambda関数名については、

  • nodejs-linebot-helloFromLambdaFunction-…

といった具合に、サンプルソースのhello-from-lambda.jsを引きずった名前になりました。

CodePipelineを通してデプロイする

では、このLambda関数にLINE Botの機能をデプロイしてみます。

LINE Botを動かすための準備

LINE Botを動かすための準備を先に行います。

デプロイそのものとは関係が無いので、折りたたみセクション化しておきます。API Gatewayの作成 〜 LINEチャネルの作成 〜 Lambda関数の環境変数設定

CodeCommitのリポジトリをローカルにgit cloneする

今回、CodeCommitにはSSHで接続して、git cloneすることにします。

SSH接続のための準備は以下を参照してください。こちらもデプロイそのものとは関係無いので、折りたたみセクション化しておきます。git cloneするまでのSSH接続の準備

git cloneする

ソースコードを編集するため、CodeCommitのリポジトリをローカルにgit cloneします。

$ cd (ローカルでソース管理するディレクトリ)
$ git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/nodejs-linebot

ローカルで必要なライブラリをインストールしてソースを編集する

Line BotのSDKをインストールし、オウム返しを行うindex.jsを作成します。

$ cd nodejs-linebot
$ npm install @line/bot-sdk

nodejs-linebot/index.js

const crypto = require('crypto');
const line = require('@line/bot-sdk');
const client = new line.Client({
  channelAccessToken: process.env.ACCESS_TOKEN,
  channelSecret: process.env.CHANNEL_SECRET,
});

exports.handler = function (event, context, callback) {

  // 署名の検証
  const signature = crypto.createHmac('sha256', process.env.CHANNEL_SECRET).update(event.body).digest('base64');
  if (signature !== event.headers['X-Line-Signature']) {
    callback(
      null,
      {
        statusCode:404,
        body: '{"Error": "Invalid Signature"}'
      },
    );
    return;
  }

  // オウム返し
  const body = JSON.parse(event.body);
  client.replyMessage(
    body.events[0].replyToken,
    {
      type: 'text',
      text: body.events[0].message.text,
    },
  );
};

CodeCommitにpushしてCI/CDパイプラインを開始する

$ git add .
$ git commit -m "feature/Line Bot"
$ git push

CodePipelineの画面を確認すると、CodeCommitの更新、CodeBuildによるビルドが順次完了していくことが確認できます。

さらに、しばらく待つとデプロイも完了しました。

Lambda関数を確認する

Lambda関数を見ると、index.jsを含むファイルがデプロイされていることが確認できます。

ハンドラをindex.handlerに変更して、保存を押します。

Lambda関数を確認する

LINE Botの動作確認を行う

LINE Botにメッセージを送ります。無事、オウム返しでメッセージが返ってきました!

LINE Botの動作確認を行う

最後に

非常に簡単にLambda関数とセットでCI/CDパイプラインが構築できてしまいました。

今回は取り扱いませんでしたが、GitHubでソースは管理し、CircleCI経由でCodePipelineに連携してデプロイする、といったパイプラインも構築できるかと思います。

今後、Node.js以外にも対応してくれることを期待したいと思います。

補足:Lambdaアプリケーションを削除するには

さて、このLambdaアプリケーションを削除する場合はどうするかというと、少しクセがあります。

マネジメントコンソールのLambdaアプリケーション画面から、該当のアプリケーションを選択、削除すればCFnのように関連する全てのAWSリソースを削除してくれる・・・というわけではありません。

Lambdaアプリケーション画面

削除を選択すると、以下のダイアログが表示されます。

Lambdaアプリケーションを削除

これによると、以下の手順でAWSリソースを削除する必要があります。

  1. アプリケーションスタックを削除する
  2. デプロイパッケージを保存しているS3バケットを削除する
  3. 1の削除完了後にツールチェーンスタックを削除する(先に3を実施すると1を実施できなくなる)

アプリケーションスタックというのは、今回の記事で言うと、CFnの画面に表示されていたnodejs-linebotスタックのことで、ツールチェーンスタックはもうひとつのserverlessrepo-nodejs-linebot-toolchainスタックのことになります。

アプリケーションの削除については、このような制約事項があるので注意してください。