概要
Serverless Frameworkを使用する時、ローカルからデプロイするだけで特にCIを回していなかったのでGithub Actionで開発フローを組もうと思い調べてみたので設定手順をまとめておきたいと思います。
この記事でセットアップする開発フローは、Github Pushトリガーによって、Serverless Serviceをデプロイするアクションを起動する非常にシンプルなものです。
目次
- 構成
- 運用フロー
- 準備
- 設定
- Serverless Framework
- Github Action
- 動作確認
- 参考URL
構成
Lambdaのトリガーとして設定するAPI Gatewayには、開発用(dev)・本番用(prod)の2つのステージを用意し、Functionを起動した際はそれぞれのステージのLambdaが実行されるようにします。
開発用Lambda(dev)
Latestバージョンを常に参照します。LatestバージョンはAWSによって、デプロイ毎にデフォルトで割り当てられる最新のバージョンの事です。
本番用Lambda(prod)
指定したバージョンを切り替える事で、本番用にバージョニング設定する事が出来ます。
運用フロー
GithubのマスターブランチへのPushをトリガーに、Serverless Serviceをデプロイするアクションが実行されるようにします。
トリガー
1.開発環境(開発用Lambda)へのデプロイ
GithubのマスターブランチへのPushをトリガーとします。
2.本番環境(本番用Lambda)へのデプロイ
Githubのマスターブランチへタグ付きのPushをトリガーとします。
準備
- Serverless Frameworkのインストール
npm install -g serverless
- プロバイダーセットアップ
今回はAWSアプリケーションを作成するので、Serverless FrameworkのプロバイダーとしてAWSを設定します。Serverless Frameworkに、AWSの機能権限を与えたIAMユーザーを割り当てるために下記を実行する必要があります。
1.AWSでServerless用のIAMユーザを発行。
2.IAMユーザにAdministratorAccessの管理ポリシーを与える。
設定
Serverless Framwork
1.サービス(Serverless Frameworkにおける実行環境の単位)の作成
serverless create --template aws-nodejs --name greeting-service --path greeting-service
2.環境変数の設定(env.yml)
prod:
appName: "Serverless App"
default:
appName: "DEV Serverless APP"
3.サービス全体の設定(serviceless.yml)
今回はLambdaとAPI Gatewayで構成するアプリケーションです。serverless.ymlに諸々のAWSに関する設定を記述していきます。
- サービス内のLambdaファンクション群
Getリクエストで、挨拶を返すHiファンクションの定義。
- Lambdaファンクションごとのトリガーとなるイベントの定義
Functionのトリガーとして、Getリクエストを定義。
- 環境変数の定義
serverless.yml内で使用する変数を定義。
Function内で使用する変数を定義。
- providerの設定
AWSの地域設定。
変数の中身は、GithubのPushトリガーで設定出来るように定義します。この変数がServerlessのデプロイ先をルーティングする役割を担当します。
service: greeting-service
frameworkVersion: '2'
//自身で定義した変数 => serviceless.ymlで参照
custom:
defaultStage: dev
// 開発環境へのデプロイ → prod.appName変数が参照される。
// 本番環境へのデプロイ → default.appName変数が参照される。
environment: ${file(env.yml):${self:provider.stage}, file(env.yml):default}
provider:
name: aws
runtime: nodejs12.x
lambdaHashingVersion: 20201221
stage: ${opt:stage, self:custom.defaultStage}
// lambdaで使用する変数
environment:
appName: ${self:custom.environment.appName}
// 地域の指定
region: ap-northeast-1
functions:
greeting:
handler: handler.greeting
events:
- http:
path: /
method: get
4.Lambda functionの設定
'use strict';
module.exports.greeting = async (event) => {
console.log(process.env.appName);
console.log(event.requestContext.stage);
let html = `
<p>Hi!</p>
`;
return {
statusCode: 200,
headers: {
'Content-Type':'text/html'
},
body: html
};
};
Github Action
1.AWSのシークレットキーと環境変数をGithubで設定する。
2.workflowの設定
- dev workflow
マスターPushをトリガーにしたワークフローを記述します。このワークフローが走ることで、1.開発環境(開発用Lambda)へのデプロイが実行されます。
name: Deploy Dev Lambda Function by Serverless Framework
on:
push:
branches:
- master
jobs:
deploy-dev:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: Install Serverless Framework
run: npm install -g serverless
- name: Serverless AWS authentication
run: sls config credentials --provider aws --key ${{ secrets.AWS_KEY }} --secret ${{ secrets.AWS_SECRET }}
- name: Create env file
run: |
cat > env.yml << EOF
${{ secrets.ENV }}
EOF
- name: Install NPM dependencies
run: npm install
- name: Deploy Lambda functions
// ステージを開発環境に指定し、デプロイ
run: sls deploy -s dev
- prod workflow
タグ付きのマスターPushをトリガーにしたワークフローを記述。このワークフローが走ることで、2.本番環境(本番用Lambda)へのデプロイが実行されます。
name: Deploy Production Lambda Function by Serverless Framework
on:
push:
tags: # Deploy tag (e.g. v1.0) to production
- 'v**'
jobs:
deploy-prod:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: Install Serverless Framework
run: npm install -g serverless
- name: Serverless AWS authentication
run: sls config credentials --provider aws --key ${{ secrets.AWS_KEY }} --secret ${{ secrets.AWS_SECRET }}
- name: Create env file
run: |
cat > env.yml << EOF
${{ secrets.ENV }}
EOF
- name: Install NPM dependencies
run: npm install
// ステージを本番環境に指定し、デプロイ
- name: Deploy Lambda functions
run: sls deploy -s prod
動作確認
設定したGithub Actionで、Serverless Applicationのデプロイが実行されるか確認したいと思います。まずは開発環境にデプロイします。
git push origin master
Actions画面で確認してみると、開発ステージにデプロイされた事が確認出来ます。
curlコマンドでも確認してみます。
開発環境(https://***.execute-api.***.amazonaws.com/dev)
curl https://***.execute-api.***.amazonaws.com/dev/
<p>Hi!</p>
開発環境にアプリケーションがデプロイされている事が確認出来ました。
続いて、タグを切って本番環境にデプロイしてみます。差分を確認するために、Function関数を変更します。
'use strict';
module.exports.greeting = async (event) => {
console.log(process.env.appName);
console.log(event.requestContext.stage);
let html = `
<p>Chao!</p>
`;
return {
statusCode: 200,
headers: {
'Content-Type':'text/html'
},
body: html
};
};
git push origin Tag<version>
こちらもcurlコマンドでも確認してみます。
本番環境(https://***.execute-api.***.amazonaws.com/prod)
curl https://***.execute-api.***.amazonaws.com/prod/
<p>Chao!</p>
本番環境にアプリケーションがデプロイされている事が確認出来ました。
まとめ
Serverless Frameworkを使えば、AWSアプリケーションの構築管理が便利に出来ますが環境の切り替えをActionに任せる事でよりサービスの運用が楽になる事が分かりました。
今回の運用フローでは、AWS Lambda関数を、開発用と本番用の2つに分けていますが、エイリアスでバージョニングを行えば1つの関数で環境をスイッチング出来るみたいなのでそちらの方法も試してみたいと思います。
参考URL
Serverless Frameworkの使い方まとめ
How to deploy Serverless applications using Github Actions
APIGateway+Lambdaによるアプリサーバをバージョン管理する