echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【Serverless Framework】Serverless Frameworkのダッシュボード上でCI/CDを実現する方法(各種設定など)

はじめに

前回の記事で、Serverless FrameworkのダッシュボードからGitHubレポジトリ/ブランチと連携して、CI/CDを実現する方法を記載しました。

今回は、前回書ききれなかった詳細設定などについて記載したいと思います。

※Serverless Framework公式サイト www.serverless.com

記載内容

  • プロフィール設定
  • デプロイ結果(を含む各種通知)設定
  • CI/CDでのデプロイ前後の挙動設定(任意処理実行)
  • モニタリングについて
  • まとめ

プロフィール設定

プロフィールは「org settings」(右上のアカウント名をクリックすると表示される)から、「deployment profiles」を選択することで行えます。(なお、デフォルトで「dafault」プロフィールが設定されています))

f:id:Makky12:20200607084951p:plain

プロフィールには下記項目を設定する必要があります。

項目名 説明 備考
settings プロフィールの名前設定&削除 新規作成する場合、まず名前を保存しないと、他の設定が行えない
AWS Account 接続するAWSアカウントの設定 [connect aws]ボタンから、実際に該当のAWSアカウントにログインするか、IAMロールのARNを設定する
safeguards デプロイ時のルール、及び違反した際の挙動(警告orエラー)を設定する 詳細項目については下記「「safeguards」の設定について」参照
parameters serverless.ymlファイルで参照できる環境変数を設定する serverless.ymlに「${param:<variable-key>}」形式で記載すると、ここで設定した環境変数の値を使用できる。(下記「「parameters」について」参照)
「safeguards」の設定について
項目名 説明 備考
name your policy 設定するsafeguard policyの名前
choose a safeguard 設定する項目の種類 詳細は下記「「choose a safeguard」の設定について」参照
Modify the default description and configuration 「choose a safeguard」で設定した項目の説明&ルール 詳細項目については下図参照
Choose an enforcement level 「choose a safeguard」で設定した項目が「Modify the default description and configuration」のルールに違反した際の挙動 下記から選択
・error(デプロイを中止する)
・warning(デプロイは継続するが、警告を表示する)
「choose a safeguard」の設定について

※一部間違いがあるかもしれませんが、だいたいこんな感じだと思います

項目名 説明 備考
allowed-function-namaes 「functions」セクションに定義するLambda関数の名前の規則
allowed-regions デプロイを許可するAWSリージョン
allowed-runtimes デプロイを許可するデプロイ先のLambdaランタイム node12.x、Python3.x等
allowed-stages デプロイを許可するデプロイ先のAPI Gatewayステージ dev, prod等
forbid-s3-http-access 安全でないhttpプロトコルからのデプロイ(先s3バケットへのアクセス)を禁止する これを設定した場合、禁止する
framework-version デプロイを許可するServerless Frameworkのバージョン 範囲指定可能
javascript デプロイ前に、JavaScriptでのテスト&テスト通過を必須にする これを設定した場合、必須にする
no-secret-env-vars Lambda関数に設定する環境変数の値に、AWS Credential形式の値を禁止する ・これを設定した場合、AWS Credential形式の環境変数の値を禁止する
AWS Credentialとは、アクセスキーやシークレットアクセスキー(の値)など
no-wild-iam-role-statement IAM Roleのアクション、リソース等の設定にワイルドカード(*)使用を禁止する これを設定した場合、IAM Roleのアクション、リソース等の設定にワイルドカードの使用を禁止する
require-cfn-role デプロイ時にCloudFormation専用(と想定される)Role(やポリシー)を必須とする(?)
require-description すべてのfunction項目に、description(説明)を必須とする 実際には、descriptionの文字数の範囲(最小/最大)を設定する
require-dlg リストアップしたイベント(http等)で実行されるすべてのfunctionのDLQへのアタッチを必須とする
require-global-vpc すべてのfunctionのVPCへのアタッチを必須とする(?) 実際には、最低限アタッチが必要なサブネットの数を指定
require-stack-tags stackTagオプションに特定のタグ名が含まれることを必須とする 実際には、タグ名だけでなく、その値もチェック可能(正規表現で)
restricted-deploy-times デプロイをしない(禁止する)時間を設ける 実際には、基準日・期間・チェックするインターバルを設定する(下図参照)

f:id:Makky12:20200607090130p:plain

「parameters」について

たとえば、こんな感じで設定した場合...

f:id:Makky12:20200607081113p:plain

serverless.ymlで、下記のように記載します。

# serverless.yml内で組織とアプリを「org」「app」キーで紐づけて...
org: my-org-name
app: my-app-name  
  
# (中略)  
  
# 例えばトップ階層のenvironmentに下記設定を行うと、全Lambda関数にキー「hogehoge」、値「fuga」という環境変数が追加される。  
# ※もちろんserverless.yml内のどのキーの値にも設定できる。
environment:  
  hogehoge: ${param:hoge}

デプロイ結果(を含む各種通知)設定

登録したアプリをデプロイを実施した際に(CI/CD、CLIからのデプロイ共に)、デプロイについての通知を設定できます。
ダッシュボードの「apps」から該当のアプリをクリックした後で、「app settings」-「notifications」を選択すると設定できます。

f:id:Makky12:20200607090417p:plain

設定項目は下記のとおりです。(デプロイに関係ないものは除外)

項目名 説明 備考
Select notification type 通知方法(Email/Slack/SNS/WebHookから選択) 選択後、項目毎に通知先を設定します。(メールアドレス、SNSのARNなど)
stages デプロイを通知するステージ 全部or特定のステージ([app settings]-[stages]で作成したステージ、複数選択可)
services デプロイを通知するサービス 選択したアプリ内の全サービスor特定のサービス(複数選択可)
alerts 通知するデプロイのイベント(開始/成功/失敗) 複数選択可

※実際には、下記のようなデプロイ以外の通知にもこの設定は適用されます。

CI/CDでのデプロイ前後の挙動設定(任意処理実行)

Serverless FrameworkダッシュボードでのCI/CDデプロイ時には、内部的に

  • npm install
  • npm test
  • serverless deploy

の3コマンドを順に実施します。

そして、これらのコマンドの実施前後に独自の処理を実施することができます。

【参考】:Serverless Dashboard - CI/CD Custom Scripts

npm install/npm testの前後に処理を挟む

npm install、またはnpm testコマンドの前後に独自処理を挟む場合、package.jsonの「scripts」内に下記コマンドを追加します。

{  
  "name": "xxxx",  
  "version": "1.0.0",  
  "scripts": {  
  
     // preinstall: npm install実行前に実行される処理
    "preinstall": "echo \"preinstall command executed\""  
  
    // postinstall: npm install実行後に実行される処理  
    "postinstall": "echo \"postinstall command executed\""  
  
    // pretest: npm test実行前に実行される処理    
    "pretest": "echo \"pretest command executed\""  
  
    // posttest: npm test実行後に実行される処理    
    "posttest": "echo \"posttest command executed\""
  }
}

ちなみに前回の記事で、「「node_modules」フォルダ(=npmモジュール群)をgit管理下に含めないと、Lambda実行時に「cannnot find module」エラーが出る」件について、

ここはうまい方法があるかもしれないので(それこそCodeBuildの「buildspec」ファイルみたいな機能を使うとか)、そのあたりも調べて、別記事で書きたいです。

ということを書きましたが、「postinstall」コマンドを使う事で解決できます。

例えば、ルート直下の「lambda」フォルダ内でLambda関数&使用するnpmモジュールを管理している場合、下記定義をpackage.jsonに追加すればOKです。
(ルートフォルダは最初のnpm installでインストールできるので問題ない)

{  
  "name": "xxxx",  
  "version": "1.0.0",  
  "scripts": {  
    // これを追加  
    "postinstall": "cd lambda && npm i && cd ../ && exit 0"
  }
}
serverless deployの前後に処理を挟む

serverless deployコマンドの前後に処理を挟むことは、package.jsonの設定では実行できません。

これは「serverless-plugin-scripts」というプラグインをインストール後、serverless.ymlに下記定義を行うことで実現できます。(つまりCLIからのserverless deployコマンドでも可能)

www.serverless.com

# pluginsに「serverless-plugin-scripts」を定義する。
plugins:  
  - serverless-plugin-scripts    
  
# (中略)  
  
# 「custom」に「scripts.hooks」キーを定義し、その中でServerless Frameworkのライフサイクルイベント&処理内容を定義する。  
# ライフサイクルイベントは配列形式で記載可能。  
  
# (例)デプロイ前イベント(before:deploy:deploy)とデプロイ後イベント(deploy:finalize)を定義  
custom:
  scripts:
    hooks:
      - ‘before:deploy:deploy': <before deploy script>  
      - ‘deploy:finalize’: <deploy finalize script>  
    

※Serverless Frameworkのライフサイクルイベントについては、下記ページに詳しく載っています。

Serverless Lifecycle Cheat Sheet · GitHub

例えば、package.jsonとserverless.ymlに下記定義を行った場合、

{    
  // 「scripts」以外は省略
  "scripts": {
    "preinstall": "echo \"preinstall command executed\" && exit 0",
    "postinstall": "cd lambda && npm i && cd ../ && exit 0"
  }
}
plugins:  
  - serverless-plugin-scripts    
  
# (中略)  
  
custom:
  scripts:
    hooks:
      - 'before:deploy:deploy': ${file(./beforedeploy.js):beforeDeploy}
      - 'deploy:finalize': ${file(./finalizedeploy.js):finalizeDeploy}
    
// beforedeploy.jsの内容。(ただログを出力するだけ)  
// return 0してるのは、何か値を返さないとデプロイ時にエラーになるため。(voidではNG)  
// なおfinalizedeploy.jsの内容は、「beforeDeploy」が「finalizeDeploy」になっている以外は全く同じ
module.exports.beforeDeploy = () => {
    console.log("beforeDeploy Executed");
    return 0;
}  

デプロイログは、下記の通りになります。(ちゃんと定義したイベントが走っています)

f:id:Makky12:20200607090702p:plain
f:id:Makky12:20200607090834p:plain

モニタリングについて

CI/CDとは直接関係でないですが、アプリを選択後「service」から該当のサービスを選択すると、そのサービスのモニタリングを行えます。

モニタリングでは、例えば以下の事を確認できます。

  • API呼び出し回数&実行時間
  • 各Lambda関数の実行回数&実行時間
  • エラー情報
  • メモリ使用量 など

f:id:Makky12:20200607091229p:plain
f:id:Makky12:20200607091242p:plain
f:id:Makky12:20200607091254p:plain

まとめ

以上が、ダッシュボードでCI/CDを行う際の、大まかな設定になります。

必須項目/任意項目色々ありますが、これらの設定をうまく使う事で、例えば

  • safeguardで「no-wild-iam-role-statement」を設定することで、不要なリソースへのアクセスやアクションの実行を禁止し、想定外の事態を避ける
  • alertsの「deployment」のチェックをONにすることで、
    • デプロイ失敗時にそれを検知し、素早く対処する(≒迅速に新機能を提供できるようにする)
    • 意図しないデプロイが発生した際、なぜ起こったのかを素早く調査する(セキュリティインシデントの可能性もあるので)
  • モニタリングを使用して、Cloudwatch Eventsの日時バッチ的な処理が失敗した際、素早く調査する

のようなことも可能になり、運用面でも大いに有効活用できると思います。

ぜひこれらの設定を有効活用していきたい&業務を楽にしたいですね。

ちなみに、Serverless FrameworkでのCI/CDについては、Serverless Framework公式Youtubeチャンネルにも動画があるので、そちらも参考にしてください。

https://www.youtube.com/watch?v=mB0owYlJgKs&t=506s


CI/CD with Serverless Framework

それでは、今回はこの辺で。