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

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

【Serverless Framework】Serverless Frameworkのダッシュボード上でCI/CDを実現する方法

はじめに

AWSにしろAzureにしろ、クラウドベースの開発でよく「CI/CD」(継続的インティグレーション/継続的デリバリー)が取り入れられていると思います。

そして、Git連携(=gitの特定リポジトリ/ブランチにpushしたら、連動してデプロイが実施される)を導入するケースも多いです。

実際にAWSなら、「AWS CodeBuild」「AWS CodePipeline」のようなCI/CD支援サービスも提供されています。

今回のブログは、そのCI/CD&Git連携を、Serverless Frameworkのダッシュボードのみで実現する方法です。

www.serverless.com

前提

  • Serverless Frameworkの1.48.0以降のバージョンが必要なので、必要に応じて事前にバージョンアップをしてください。(最新版なら問題なし)
  • 公式ページ(https://serverless.com)から、サインアップを済ませておいてください。(右上の「Sign-Up-Free」から)
  • 事前にGit連携対象のGitHubリポジトリ&ブランチを作成しておいてください。(ブランチは「master」でもOK)

初期設定

初回ログイン時、まずは作成するアプリの設定を行います。
下記3種類から選びます。(今回は「Serverless Framework Existing Project」前提で進めます)

項目 説明 備考
Node.js Rest API Node.jsのRest APIプロジェクトの新規作成
Python Rest API PythonRest APIプロジェクトの新規作成
Serverless Framework Existing Project 既存のServerless Frameworkプロジェクトから選択 新規作成せず、既存のプロジェクトを使用する場合はこちら。(まだAWSにデプロイしていなくてもOK)

f:id:Makky12:20200530195714p:plain

また、初回のみ「GitHub連携」及び「AWSアカウント連携」の設定を行う必要があります。

それぞれ、ボタンをクリックするとGitHub/AWSのログインページが表示されますので、GitHubのレポジトリ連携/AWSサインインを行えば、自動でダッシュボード画面に戻ります。

f:id:Makky12:20200531190750p:plain

アプリを登録する

まず、CI/CD導入対象のアプリを登録する必要があります。 まずダッシュボードにサインインします。

公式ページ右上の「Sign-in」からサインインすると、自分のダッシュボードが表示されます。

※下記CLIコマンドでサインイン画面を開くことができます。(もちろん自分でブラウザを開いても問題なし)

> serverless login

※その他、一度サインインすれば、CLIから下記コマンドでダッシュボードを開くことができます。

> serverless dashboard

ダッシュボードが表示されたら、[apps] - [add app]から、必要項目を設定して、[add app]ボタンをクリックすると、アプリを登録できます。(設定できる項目は以下の通り)

項目 説明 備考
name アプリの名前
profile デプロイに使用するprofile ※1

※1:profileは右上の[アカウント名]-[org settings]-[DEPLOYMENT PROFILES]から設定できます。(細かくは別記事で書きます)
とりあえずは「default」でOK

f:id:Makky12:20200530195849p:plain

その後、登録した[apps]から登録したアプリ名をクリックすると、「Deploy Your Service」項目が表示されますが、まずは先に下記の「デプロイステージの登録」を行います。

デプロイステージの登録

[app settings]-[stage]を選択すると、デプロイ先のステージを登録できます。 デフォルトで「default」が登録されていますが、「dev」「stg」など、明確にステージ名が決まっている場合、ここで事前に登録しておきます。

なお、設定項目は下記2つです。

項目 説明 備考
stage name ステージ名
deployment profile デプロイに使用するプロファイル

f:id:Makky12:20200530200628p:plain

CD/CDの選択

ここまで設定したら、登録した[apps]から登録したアプリ名をクリック後、下記いずれかの方法でCI/CDの設定を行います。

  • 「Deploy Your Service」画面で「Deploy Your GitHub」をクリックする※
  • [ci/cd settings]タブをクリックする

※ちなみに「Deploy From the CLI」を選択すると、CLIから登録したアプリをデプロイする方法が表示されます。

この方法ではGitHubレポジトリ・ブランチ連携デプロイは出来ませんが、登録したアプリのモニタリング&デプロイ履歴の確認などは出来ます。(この辺も別記事で書きます)

※「Deploy From the CLI」の場合、ログイン後、下記コマンドで登録したアプリと表示中のプロジェクトの紐づけを行うことができます。

> serverless --org (アカウント名) --app (登録したアプリ名)
# 例  
> serverless --org makky12 --app my-app  

設定できる項目は、以下の通りです。

項目 説明 備考
connection 連携するGitHubレポジトリ名 GitHubリポジトリを未設定の場合、まずGitHub側でリポジトリ設定が必要(ここで設定可能)
preview deploys テスト&デプロイ対象のブランチ(?) ※1
branch deploys デプロイトリガ元のブランチ&デプロイステージ
region デプロイ先のAWSリージョン ここからは「advanced settings」の項目※2
service デプロイ対象のサービス名 ※3
runtime デプロイ対象のプログラムランタイム 「node.js」「python」など※3
trigger directions デプロイトリガ元のブランチの中で、実際にトリガを起動するフォルダ・ファイル 「Always trigger a deployment」にチェックを入れると、該当ブランチをpushしたらデプロイが実行される。
チェックを入れなかった場合、指定したフォルダ・ファイルの変更がpushされた場合のみデプロイが実行される。
preview deploys プレビュー対象のステージ(?) [app settings]-[stage]で設定したステージ、または「use branch name as stage」を選択。
後者を選んだ場合、ブランチ名がそのままステージ名になる。
また「Destroy stage and resources when branch is deleted」で「ブランチを削除したら、該当ステージ&リソースを削除するかどうか」を設定できる。※1

※1:てか、なんで同じ名前なの...(誤記ではなく、本当に同じ名前)
※2:「advanced settings」とあるけど、リージョンってかなり重要なような...
※3:初期設定で「Serverless Framework(Existing Project)」を選択した場合、設定済&指定不可

f:id:Makky12:20200531191131p:plainf:id:Makky12:20200531191142p:plain

実行

ここまで設定したら、実際に設定したレポジトリ・ブランチに該当プロジェクトをpushしてみます。

設定に問題なければ、pushに連動してデプロイが実行されるはずです。 ※左上の「ci/cd」の隣に青い●マークがつき、クリックすると「実行中」みたいな感じで円がグルグル回っているはずです。

f:id:Makky12:20200531191320p:plain

デプロイ終了すると、結果に応じたアイコンが表示されるので、クリックするとデプロイのレポート・及びログを確認できます。

f:id:Makky12:20200531191451p:plain f:id:Makky12:20200530200424p:plain

あとは実際に動かしてみて、正しくデプロイされている&変更が反映されている事を確認してください。

デプロイ失敗理由(僕の場合)

  • serverless.ymlの変数値の設定に必要なファイルがpushされていなかった
  • node_modulesフォルダがpushされていなかった

しょうもない理由といえばしょうもない理由なんですが、ログを追って原因が分かった時、「あ、そうか、CI/CDだとそうなんだ」と思いました。

というのは、(前者はともかく後者は)今の業務で開発しているプロジェクトだと、node_modulesフォルダ一式はGitの管理対象外にしてたからです。(そうそう自分で直接変更なんてしないし、事前にnpm installすればOKなので)

でもCI/CDだと、当然Gitにpushしないと動かないので(Lambda実行時に「●●のモジュールがない」とエラーが出る)、Gitの管理対象にしないといけないんだ、と分かりました。

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

まとめ

というわけで、Serverless FrameworkのダッシュボードだけでCI/CDを実現する方法でした。

AWS CodeBuildやAWS CodePipeline、及び各種CI/CD用ツールはありますが、Serverless Frameworkのダッシュボードだけでも、簡単なCI/CDを実現できますので、有効に活用していきたいですね。

また、今回記載できなかった

  • プロファイル設定
  • ビルドコマンド設定
  • アプリのモニタリング&各種通知設定

なんかについても、後日別記事で書きたいと思います。

それでは、かなり久々な記事でしたが、今回はこの辺で。

【Serverless Framework】Lambda Destinations機能をServerless Frameworkで実装する

はじめに

昨年11月末にAWSから「Lambda Destinations(Lambda非同期呼び出しの宛先指定)」機能が発表されました。

そしてこの機能について、3月中旬に「Serverless Frameworkが正式サポート」したと公式ブログで発表がありました。
そこで、早速この機能をServerless Frameworkで使ってみました。

serverless.com

前提:「Lambda Destinations(Lambda非同期呼び出しの宛先指定)」って?

概要としては、以下の機能になります。

  • Lambda実行結果に従って、次のアクション(=実行リソース)を指定できる。
    • 正常終了(Success)/異常終了(Failure)で個別に指定可能
  • 指定可能なアクション(=実行リソース)は、以下の通り
    • Simple Queue Service(SQS)
    • Simple Notification Service(SNS)
    • Lambda
    • Event Bridge
  • 非同期実行のLambda(=各種イベントで実行されるLambda)のみ設定可能
    • API Gateway(≒Rest API)経由で実行されるような、同期実行のLambdaでは実行不可(※)

API Gateway経由Lambdaでも、非同期で実施することは可能です。

https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2019/11/25/lambda-destinations1.png

【参考】

実践:Serverless Frameworkで実装してみる

※前提として、前掲のServerless Framework公式ブログに記載の通り、Serverless Frameworkのバージョンを1.66.0以上にしてください。

serverless.ymlの「functions」セクションで、以下のようなLambda関数を定義します。 (今回はSuccess/Failure共に、アクションはLambda関数にしています)

functions:  
  Challange:  
    handler: challange.index  
    events:  
      # API Gatewayは通常は同期実行(Lambda Destination対象外)だけど、テスト用に実装
      - http:  
          path: /challange  
          method: get  
      ## 実際はこんな感じで、何かのイベントで実行するように実装する(元リソースの定義は省略)  
      - schedule: rate(10 minutes)  
    # 「onSuccess」/「onFailure」に成功時/失敗時の定義名を記載する
    destinations:  
      onSuccess: Success  
      onFailure: Failure  
  
  # 成功時のリソースの定義を記載(Lambdaの場合はハンドラを定義)  
  Success:  
    handler: succeeded.index  
  
  # 失敗時のリソースの定義を記載(Lambdaの場合はハンドラを定義)
  Failure:  
    handler: failed.index  

定義としては、以上です。

なお上記関数ですが、下記の内容となります。(シンプルすぎるので内容は省略)

  • challange.index:onSuccess検証時は何もせずにreturnするだけ、onFailure検証時は何かErrorをthrowする。
  • succeeded.index/failed.index:console.log()でログを1行書き出すだけ

invokeでテスト実行する

上記serverless.ymlをデプロイしたら、実際にテストをしてみます。
※デプロイ成功していれば、「Challange」Lambda内に下記の通り「非同期呼び出し」ソースが二つ追加されます。
f:id:Makky12:20200418175220p:plain

デプロイを確認したら「invoke」コマンドでテストを行います。

ここで気を付けるのは、invoke」コマンドを非同期(=イベント)で呼び出すには「--type」オプションに「Event」オプションを指定しないといけない点です。

これを忘れると「--type=RequestResponse」(=同期呼び出し)として実行されるため、Lambda Destinationは正常に機能しません。
(堀家さん、ありがとうございます。)

# test.jsonはchallange.index実行時のevent引数の内容をそのまま指定  
# 「--type Event」を忘れないこと!
> slss invoke --function Challange --path test.json --type Event

正常に実行されると、特に何も表示されずにコマンドが終了しますので、CloudWatch Logを確認します。

CloudWatch Logを確認すると、成功時/エラー発生時共に正しくアクション先Lambdaが実施され、ログが書き出されていることが分かります。

  • 上が成功時、下がエラー発生時
  • 画像は1つにまとめてますが、実際はどちらもchallange.index、及びsucceeded.index(またはfailed.index)のログです。
  • エラー発生時にchallange.indexのログが3つあるのは、2回リトライ処理を実施しているためです。

f:id:Makky12:20200418185809p:plain
f:id:Makky12:20200418185830p:plain

なお、Serverless Framework公式の下記動画でも、Serverless FrameworkによるLambda Destinationsの実装が詳しく紹介されています。 www.youtube.com

まとめ

以上がServerless FrameworkでLambda Destinationsを実装する方法です。

Lambda Destinationsですが、成功時/失敗時の処理を個別に切り出せるので、下記のようなメリットがあると思います。

  • 成功時&エラー時の処理を、同一ソースに書かなくてよい。
  • 上記により、ソースの可視性&保守性の向上につながる
  • リトライ処理を考慮した成功時&エラー時の処理を実装できる

こういう便利な機能は、どんどん活用していきたいですね。

告知

4/24(金)にオンラインで開催される「Infra Study Meetup #1 ~Infrastructure as Code~」に「Infrastructure as Codeを導入して良かった点」という内容でオンライン登壇させて頂きますので、よろしくお願いいたします。(てか4/18(土)時点で、参加者2000人超えそうな勢いなんだけど...)

forkwell.connpass.com

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

【Serverless Framework】メモリ不足でデプロイができない場合の対処方法

概要

Serverless Frameworkでパッケージングやデプロイを行う際に、メモリ不足で失敗することがあります。その場合の対象方法です。

serverless.com

現象

先日、業務で開発したサーバーレスSPAをServerless Frameworkでデプロイしようとしたら、パッケージング時に下記エラーが発生し、デプロイできませんでした。

Ineffective mark-compacts near heap limit Allocation failed - Javascript heap out of memory

アプリやServerless Frameworkの設定を見直したり、「VS Codeが原因かな?」と思い下記記事の内容を色々試しましたが、現象改善しませんでした。

その後、コマンドプロンプトでも同様の現象が発生したので、単純にエラーメッセージの通り、Node.jsのメモリが足りないのが原因と分かりました。
※PCのメモリは十分な容量があったので、そちらはではないと考えました。(てか、そっちならほぼ詰みだった)

対応方法

対応方法ですが、Node.jsのメモリを増やしてあげれば解決します。

下記の通り、環境変数「NODE_OPTIONS」の「max_old_space_size」パラメータにメモリサイズ(MB)を指定することで、Node.jsのメモリを設定可能です。

# Node.jsのメモリサイズを指定する。(MBで)
# 下記だと、メモリサイズを4GBにする。
> set NODE_OPTIONS=--max_old_space_size=4096

なお「node」コマンドならば「max_old_space_size」パラメータの値をコマンド毎に指定できますが、Serverless Frameworkの「serverless(sls/slss)」コマンドではダメでした。(少なくとも僕の環境では)
(余談ですが、「serverless」コマンドのエイリアス、「sls」以外に「slss」でもOKなんですね。最近知りました。これでPowerShellでもエイリアスが使えます。(「Select-String」のエイリアス「sls」とかぶるから、「sls」はPowerShellでは使えない))

  • Node.jsのデフォルトのメモリサイズは1GBです。
  • あまり増やすと、今度は別アプリの動作などに影響がある場合があるので、注意してください。

上記コマンドを実施した後、先述のサーバーレスSPAをServerless Frameworkでデプロイしたところ、問題なくデプロイできました。

なお、実際のNode.jsのメモリサイズを確認する方法については、下記動画で詳しく説明されています。

まとめ

以上、Serverless Frameworkでメモリ不足が発生した場合の対象方法でした。

もちろん、この方法では対処出来ない場合もあるので、その場合はアプリ構成を考えたり(肥大化が原因の可能性がある)、場合によってはPC環境のスペックアップも考える必要があると思います。

ただ、暫定的な対応には使えると思うので、一度試すのもありかと思います。

告知

4/7(火)にオンラインで行われた「VS Code Meetup #4」にて、「開発チーム管理で役立ったVSCode拡張機能」という内容でオンライン登壇をさせて頂きました。
また、その時の登壇資料も公開していますので、よろしければご参照ください。

vscode.connpass.com

www.slideshare.net

その他、4/24(金)に同じくオンラインで開催される「Infra Study Meetup #1 ~Infrastructure as Code~」にも「Infrastructure as Codeを導入して良かった点」という内容でオンライン登壇させて頂くことになりましたので、よろしくお願いいたします。(てか4/12(日)時点で、参加者1400人超えてる...)

forkwell.connpass.com

それでは、今回はこのへんで。

【Serverless】Serverless Meetup Tokyo #16で発表した感想

経緯

先日、サーバーレスの勉強会イベントである「Serverless Meetup Tokyo #16」がオンラインで開催されました。
serverless.connpass.com

そしてこのイベントで、「AWS x Serverless Framework x QuickSightでIoTデータ可視化」という内容で、発表を行いました。(発表資料はslideshareで公開してます。)

www.slideshare.net

本日は、その「Serverless Meetup Tokyo #16」で登壇した感想についての話です。
※「Serverless Meetup Tokyo #16」の配信内容は、下記「Serverless Community(JP)」の公式ページ内のYoutubeリンクから閲覧できます。

【参考】Serverless Community(JP) について

Serverless Community(JP) はサーバーレスアーキテクチャを用いたアプリケーションの構築における経験の共有を目的とした、コミュニティです。

ServerlessConf Tokyo および Serverless Meetups in Japan の実行組織でもあります。
serverless.connpass.com

開催までの話

  • MS Ignite Tour Osakaで、株式会社Serverless Operationsの堀家さん(Serverless Frameworkのすごい人)のセッションに参加したことがきっかけで、「名古屋でサーバーレスイベントやりましょう」という話になる。
  • では、まず東京のイベント(サーバーレス + IoT)に参加することに
  • 今回ではAzureネタでの発表がほとんどらしいので、 AWSで何か発表しませんか?というお話を頂く
  • じゃあAWS関連で発表しよう&東京のサーバーレス勉強会の雰囲気を肌で感じよう!
  • 翌日は仕事休んで、ゆっくり東京観光でも...

と、思ってたんですけどねえ。

オンライン開催に変更

...まあ、新型コロナウィルスの影響もあり、オンライン開催に変更されました。
(最初は現地開催したいよね...という話もありましたが、最終的にはオンラインになりました)

残念ですが、こればっかりは仕方がないですね。

ちなみに当日ですが、

  • 参加者の方にはYouTubeのURLを連絡し、Youtubeで見てもらう
  • 発表者はZoomでチャット・画面共有などを実施し、いろいろ調整する

という内容でした。(ちなみに、発表者の間で、事前に配信テストなんかも行ってました。)

おかげで(?)当日は大きなトラブルにも見舞われず、イベント自体は(手前味噌ながら)大成功だった、と思っています。

実際にオンラインイベントで発表を行った感想&アドバイス

「聞いている人たちの感想&リアクションがない」ので、不安になる。

オンラインではリアルタイムに聞いている人のリアクションが分からないので「うまくいってるのか?」と、いろいろ不安になります。
(PowerPointを開くと複数ウィンドウがPowerPointで埋まるので、YouTubeとかTwitterを見られないんです)

これに関しては、イベント終了後のお話で「Power BI 王子」こと清水 優吾さんが「一例として、以下の方法がある」とおっしゃっており、実際おすすめです。

使用するアプリの操作が分からないので、何をしていいかわからない

これに関しては、本番でやらかしてしまわないよう、配信に使用するアプリ(今回ならZoom)の基本的な使い方は、あらかじめ押さえておくことをお勧めします。

特に下記あたりの機能は、あらかじめ確認しておいた方が良いです。

  • マイクのミュート/ミュート解除
  • カメラのON/OFF
  • チャット機能
  • 画面共有/共有の解除

オンライン会議の作法が分からない

これに関しては、やればわかる(し、多分経験者が教えてくれる)ので、あまり神経質にならなくてもよいとは思います。
少なくとも、下記の点あたりを押させておけばよいと思います。

  • 他の発表者の方が発表中の時は、マイクはミュートにする。
  • ガタガタしそうな場合(席を外す、物を探す...等)、マイクをミュートにする。
  • マイクのミュート/ミュート解除の勘違いに気を付ける。
    • うっかり何気ないつぶやきや、家族の会話がダダもれになったり...(経験者)
  • 事前に家族に伝えておく。
    • うっかり家族が入ってきたり、完全に油断した格好だったりすると...
  • カメラをONにし続ける場合、何気ない動作もオンラインで映ってたりするので、気を付ける

まあでも「物は試し」というか「経験して慣れる」のが一番だと思います。

参加者(=見る&聴く側の方)へのお願い

YouTubeなど、配信アプリのチャット&Twitterへの(ハッシュタグ付き)ツイートを、バンバン書き込んでください。

  • リアクションが見えるだけで、マジで不安が和らぎます。
  • コメント&ツイートが多いと「反響があった」という点で、本当に嬉しいです。

ディスりはNG、でも意見は大歓迎

  • 発表者も、その内容&関連項目について100%把握してる...とは限りません。
  • むしろ、詳しい方の意見・見解を頂けると、すごく参考&勉強になります。

感想

ただでさえ参加者が多いイベントで、初めての登壇(=発表)がオンラインということで、めちゃくちゃ緊張しましたが、「やってよかった!」と本当に思ってます。

ただ聴く側ではなく、発表を行うことで、いろいろ経験になりますし、何よりアプトプットを行うことで「多くのインプットが身につく」という恩恵もあります。(これは本当にそう思いました)

最近では「DevRel(Developer Relations)」という考えもありますが、自分がアプトプットを行うことで、下記のようなメリットもありますので、本当に登壇・発表を行うことはお勧めだと思いました。

  • 「自分」という技術者のアピール&PR(自分を知ってもらう)
  • 自分を知ってもらうことで、多くの方々と知り合う&関係を持つことができる
  • 知見を共有する&得ることができ、様々なソリューションに繋がる...など

機会があれば、また積極的にチャレンジしたいと思っています。

告知

上記「Serverless Meetup」イベントですが、「Serverless Meetup Tokyo #16」内でも私が発表した通り、名古屋でも開催します!

※名古屋では初めての「Serverless Meetup」イベントになります!
内容がそれなりに固まり次第、connpass上で公開します。

※【3/16 更新】公開しました!

serverless.connpass.com

(個人的には)クラウド&サーバーレスは、まだまだ名古屋ではそこまで浸透していない(オンプレがバリバリ現役)と思っているので、これを機会に名古屋でもクラウド&サーバーレス、及びそのコミュニティを広めたいと思っています。

みなさま、機会が合えば、ぜひよろしくお願いします!

  • コロナウィルス(COVID-19)の影響により、connpassページの内容(開催日・開催方法など)が変更になる場合があります。ご了承ください。
  • 変更が発生した場合、connpassページ、およびServerless Community(JP)公式Twitterアカウント(@serverless, ハッシュタグ#serverlessnagoya)より、随時連絡させて頂きます。

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

【PowerApps】PowerAppsアプリで撮影した画像をS3バケットにアップロードする【Serverless Framework】

はじめに

Micorsoft の製品の一つ、Power Platform
中でもPower AppsやPower Automateは、ノーコーディング(またはローコーディング)でかなり本格的なアプリが簡単に作れる、画期的な製品です。

また簡単なアプリならコーディングなしでサクッと作れてしまうので、ITエンジニアにも便利だと思います。

そこでお試しに、(趣味と実用を兼ねて)「カメラで撮影した画像を、AWSのS3バケットに保存する」アプリを作成しました。

なおPower Platformについては、「Power BI 王子」こと清水優吾さんが、素晴らしい資料を公開してますので、ご参照ください。

www.slideshare.net

使うもの

  • Power Apps
    • 上で説明した通りです。
  • カスタムコネクタ
    • Power Platform製品の「コネクタ」(=他のアプリとの連携用の部品)でサポートされていないアプリ・サービスとも連携を可能にする機能。
    • 主に、地先APIを始め、外部Web APIのコールなど
  • AWS Lambda & AWS S3
    • S3にファイルを保存する関係で使います。
  • Serverless Framework
    • もちろん今回も使います。

【注意】カスタムコネクタについて

カスタムコネクタですが、Power Appsで使用する場合「Premium限定機能」となります。(ダイアモンドのアイコンが表示されている)
そのため、試用は可能ですが、一定期間が過ぎると使用不可能(またはサブスクリプションの購入が必要)なので、注意してください。

※あくまで「Power Platformの色々な機能のお試し」として読んでください。

Power Apps側の作成

f:id:Makky12:20200301173858p:plain f:id:Makky12:20200301173941p:plain

Power Apps側の機能ですが、こんな感じになってます。(「Kintai-Upload」は、なんとなく付けただけで、意味はないです)

  • 「撮影」画面で、カメラ機能を使って撮影する。(撮影すると自動で「確認」画面に遷移する)
  • 「確認」画面で「送信する」をクリックすると、S3バケットに撮影した画像をアップロードする。
  • 「やりなおす」をクリックすると、「確認」画面に戻る

で、上記機能の実装方法なんですが、変に説明をするより、マイクロソフトの吉田大貴さんのこの動画を見た方が早いですので、そちらを参照ください。
マジでこの動画を参考にすれば、画像をS3にアップロードする直前までできてしまいます。

www.youtube.com

注意点としては、以下の通りです。

# JSON([画像のバイナリデータ], JSONFormat.IncludeBinaryData) とすると、バイナリデータをBase64形式の文字列に変換できる。    
# [画像のバイナリデータ]には「Image1.Image」など、「画像の表示部品の名前.Image」を指定する。
JSON(Image1.Image, JSONFormat.IncludeBinaryData)

AWS側の設定について

今回、カスタムコネクタ作成にはOpen API(swagger)の定義を利用します。
またOpen API定義はAPI Gatewayからエクスポートできるので、先にAWS側のリソースを作成する必要があります。

というわけで、今回もServerless Frameworkの出番です。

...といっても、Serverless Frameworkは過去記事でもかなり扱ってるので、今回はserverless.ymlの内容だけ。

service: kintai-upload
  
provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-northeast-1
  stackName: ${self:service}
  apiName: api-${self:service}
  profile: default
  
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:ListBucket"
        - "s3:PutObject"
        - "s3:GetObject"
      Resource:
        - arn:aws:s3:::${self:service}/*  
  
  environment:
    TZ: Asia/Tokyo
  
functions:
  CreateImage:
    handler: createImage.index
    events:
      - http:
          path: /create
          method: post
          request:
            parameters:
              body:
                imagebinary: false
    environment:
      BUCKET_NAME: ${self:service}
  
  SendSms:
    handler: sendSms.index
    events:
      - s3:
          bucket: ${self:service}
          event: s3:ObjectCreated:*
    environment:
      BUCKET_NAME: ${self:service}

ざっくりまとめると、下記の流れです。(「SendSms」Lambda自体は、今回の記事では未使用)

  • api-kintai-uploadという名前のAPI Gatewayを作って、
  • そこに「CraeteImage」Lambdaを実行するエンドポイントを作成して、
  • 「kintai-upload」という名前のバケットを作成して、そこに「createObject」トリガを定義して
  • 上記トリガで「SendSms」Lambdaを実行する

なお「resourceセクションへのS3バケットの定義(てか、そもそもresourceセクション自体)がないけど」と思ったかもしれませんが、「function」セクションの「events」で「s3」を定義するだけで、下記設定を自動で行ってくれますので、「resources」セクションの定義は不要です。

  • events.s3.bucket に指定した名前のバケット作成
  • events.s3.event に定義したイベントトリガの作成

カスタムコントロールの作成

で、肝心のカスタムコネクタの作成ですが、これはPower Appのホーム画面から[データ]-[カスタムコネクタ]を選択し、右上の「カスタムコネクタの新規作成」をクリックすればOKです。

なお、作成方法がいくつかありますが、今回は「OpenAPIファイルをインポート」で実行します。 f:id:Makky12:20200307085858p:plain

OpenAPIファイルの取得

OpenAPIファイルですが、API Gatewayの場合、該当のAPIを選択した後、下記手順で取得できます。

  • 左のリストから「ステージ」を選択  
  • 「ステージ」で該当ステージを選択後、「エクスポート」タブを選択
  • 「次の形式を選択」で「Swagger」を選択後、ファイル形式に「JSON」を選択する。
    • OpenAPI3、及びYAML形式はまだサポートしてません。

f:id:Makky12:20200307091646p:plain

ファイルをDLしたら、「カスタムコネクタの作成」の「OpenAPIファイルをインポートします」で、DLしたファイルを選択します。
また「コネクタ名」に、一意の名前を入力します。
f:id:Makky12:20200307091806p:plain

で、あとは「全般」「セキュリティ」「定義」などを設定しますが、ここからは「swaggerエディタ」をONにすれば直接OpenAPIファイルの内容を編集できますので、そちらで編集します。
f:id:Makky12:20200307091905p:plain

今回は。こんな感じで定義しました。

swagger: '2.0'
info: {version: '2020-02-29T10:45:32Z', title: api-kintai-upload-to-cloud}
host: *******.amazonaws.com
basePath: /dev
schemes: []
consumes: []
produces: []
paths:
  /create:
    post:
      responses:
        '200': {description: OK}
        '400': {description: Request Error}
        '500': {description: Internal Error}
        default: {description: Something Error}
      parameters:
      - name: imagebinary
        in: body
        description: kintai file binary
        required: true
        schema: {type: string}
      operationId: Kintai-upload-to-cloud-makky12
      description: Kintai-upload-to-cloud用のカスタムコネクタ
      summary: Kintai-upload-to-cloud用のカスタムコネクタ
definitions: {}
responses: {}
securityDefinitions: {}
security: []
tags: []

ちなみに、テストをする場合「テスト」タブで必要な値を入力すればOKです。
(今回の場合、「imagebinary」にbase64文字列に変換した画像のバイナリデータを入力する) f:id:Makky12:20200304201223p:plain

Power Appsに組み込む

で、作成したカスタムコネクタをPower Appsに組み込む方法ですが、これは左のツリーの[データソース]-[コネクタ]から、先程作成したカスタムコネクタを選択すればOKです。

そして、実際にAPIにリクエストを送るには、ボタンの「onSelect」イベントなどで、下記のように設定すればOKです。

# 「api-kintai-upload-to-cloud」は、カスタムコネクタ名。    
# 「Kintaiuploadtocloudmakky12」は、OpenAPIの「operationId」の値。(「定義」タブの「操作ID」で設定可能)  
# imageBase64は、base64文字列に変換した画像のバイナリデータ
'api-kintai-upload-to-cloud'.Kintaiuploadtocloudmakky12(imageBase64);  

S3バケットに保存する。

ここまでこれば、あとはLambda側の処理です。

Lambda側では、特に特別なことはしていません。
よく見かける、画像をs3バケットに保存する処理だと思います。

強いて言えば、注意するのは下記2点です。

  • JSON()関数でbase64文字列にした場合、先頭と末尾に「"」がついているので、「"」を除去する
  • その他、「data:image/png;base64,」という文字列も付与されるので、これを取り除く
// @ts-check
'use strict';

const AWS = require("aws-sdk");
const S3 = new AWS.S3();
const moment = require("moment");

module.exports.index = async event => {
  
  let statusCode = 200;
  let message = "";
  
  try {
    console.info(`[even] ${JSON.stringify(event)})`);
    console.info(`[event body] ${event.body})`);  
  
    const bodyReplaced = event.body.replace(/\"/g, "").replace("data:image/png;base64,", "");
    console.info(`[event replaced] ${bodyReplaced})`)  
  
    const timeStamp = moment().format("YYYYMMDDHHmmssSSS");
    const params = {
      Bucket: process.env.BUCKET_NAME,
      Body: Buffer.from(bodyReplaced, 'base64'),
      Key: `kintai_${timeStamp}.png`,
      ContentType: "image/png"
    };
  
    const data = await S3.putObject(params).promise();
    // console.info(`[S3 data] ${JSON.stringify(data)}`);
  } catch (error) {
    statusCode = 500;
    message = error.message;
    console.error(`[error Message] ${message}`);
  }
  
  return {
    statusCode: statusCode,
    body: JSON.stringify({ message: message }),
  };
};
  

結果

「送信する」ボタンをクリックすると、S3バケットに画像ファイル(*.png)が保存されます。 f:id:Makky12:20200307193524p:plain

そして、ダウンロードして画像ビューワーで見ると、問題なく表示できます。 f:id:Makky12:20200307193617p:plain

まとめ

以上、カスタムコネクタを使用して、画像をS3バケットにアップロードする方法でした。

カスタムコネクタはプレミアム限定機能ですが、こういう感じで、自作APIなどの操作をローコーディングで行えます。
また、自作APIでなくても、プレミアム限定でなくても使用できるAPIもありますので(Twitterとか)、非常に便利です。

Power AppsやPower Automateなど、Power Platform製品、なかなか便利なので、今後も使っていきたいです。

それではまた。

【Serverless Framework】201個以上のリソースをデプロイする方法

はじめに

Infrastructure as Code(IaC)の代表格の1つである、AWS CloudFormation。
僕も業務でよく使うのですが、CloudFormationで1度にデプロイできるリソースの数(=1スタックのリソース数)は、「最大200個」と決められています。

なので当然、Serverless Frameworkでデプロイする際も、1度にデプロイできるリソースの数は200個までです。

でも、プロダクトが大きくなると「200個では足りない!」というケースもあると思います。
今回は、その場合にスタックをネストして、201個以上のリソースをデプロイする方法(+α)についてです。

CloudFormationの制限とスタックのネスト

「CloudFormationで1度にデプロイできるリソース数は、200個が上限」については、公式ページでも明言されています。
(一部ブログを見る限り、昔は明言されてなかった?)
AWS CloudFormation の制限

200個というのも、決して少なくはないのですが、プロダクト(≒リソース)が肥大化してくると、オーバーするケースもあります。(特にロール・ポリシーやアラートが色々増えると)

その解決方法の一つとして、公式サイトでも紹介されているのが「スタックのネスト」で、下記の考え方になります。

  • serverless.yml内で、serverless.ymlのデプロイ先スタック(=スタックA)とは別のスタック(スタックB)を別途定義する。
  • 200個を超えるリソースは、スタックBに紐づくリソースとして定義する。
  • 実際にserverless.ymlをデプロイすると200個を超えるリソースが作成されるが、スタックBに紐づけたリソースはスタックBで「上限200個」に影響するので、スタックAでの「上限200個」には影響しない。
    • もちろん、スタックBのリソースが200個を超えたらNG。
    • スタックB自身は(serverless.ymlに定義されるので)、スタックAの「上限200個」に影響する。

【参考】ネストされたスタックの操作

そこで今回は、Serverless Frameworkで「スタックのネスト」で対応する方法について扱いたいと思います。
※純粋なCloudFormationテンプレート、及びServerless Frameworkの「resources」セクションで扱う方法については、調査完了次第ブログにします。

Serverless Framework公式ページ

「serverless-plugin-split-stacks」という超便利プラグイン

...と、なんかもったいぶって書き方をしましたが、実はServerless Frameworkでスタックをネストする」のは、めちゃくちゃ簡単です。

やり方ですが、下記2つを実行するだけです。

  • 「serverless-plugin-split-stacks」というプラグインをインストールする(下記)
  • serverless.ymlの「plugins」セクションに「serverless-plugin-split-stacks」を追加する。

github.com

plugins:  
  - serverless-plugin-split-stacks  # この定義を追加するだけ
  - ...

これだけ。本当にこれだけ。CloudFormationテンプレートファイルのような「定義ファイルの分割」も一切不要です。(てか、マジで便利すぎ。このプラグイン)

上記作業さえ行っておけば、「deploy」コマンドなどを実施した際に、「serverless-plugin-split-stacks」がリソース数を計算し、200を超えたら自動で定義ファイルを分割してくれますので、こちらの作業は一切不要です。

なお「serverless-plugin-split-stacks」のカスタマイズについては、下記ブログで詳しくまとめられています。

qiita.com

いや、マジで便利すぎます。このプラグイン

デプロイを分割する

今回は「1回のデプロイで作業を完結させる」ために、スタックのネスト方法を記載しましたが、あえて「デプロイ自体を複数回行い、スタック自体を分ける」のも一つの手です。

確かに「何回もデプロイをやるなんて面倒」と思うかもしれませんが、あえて分けることで、以下のようなメリットもあります。

  • デプロイするリソースを分割できる
    • 1ファイルにまとめてしまうと、やたらデプロイに時間がかかるリソースがある場合(CloudFrontなど)、毎回すごい時間がかかってしまう。
    • 「修正(=デプロイ)頻度」「依存関係」などでファイルを分割し、必要なリソースだけデプロイすることで、そういった無駄なデプロイ時間をなくすことができる。
  • 「出力」の参照ができる
    • CloudFormationのスタックには「出力」という参照用項目がある。
      • Serverless Frameworkでは「resources」セクションの「Outputs」で定義できます。
    • 「出力」に値を設定しておけば、後でデプロイする側は、先にデプロイされた側の「出力」の値を参照できる。(ARNなど)

ただし、やはりデプロイを複数回にすると、どうしても管理の煩わしさの問題は発生すると思うので、そこは検討する必要があると思います。

【参考】: serverlessフレームワークで複数スタックに分割して、リスクを軽減する方法 - Qiita

まとめ

  • CloudFormationでは、1スタック(=1デプロイ)200リソースが上限である。
  • スタックのネストを行えば、1デプロイで200個を超えるリソースもデプロイできる。
  • Serverless Frameworkでは、「serverless-plugin-split-stacks」プラグインを使うと、驚くほど簡単にスタックのネストが行える
  • 場合によっては、あえてデプロイ(=スタック)自体を分けるのも一つの手

「リソース管理の煩雑さからの解放」が「冪等性(※)」と並ぶIaCの大きな魅力なので、「スタックのネスト」「スタックの分割」など、いろいろな方法で、極力リソース管理の煩わしさから解放され、注力すべき作業に注力したいですね。

てかそれがAWSやAzureなど、クラウドの大きな魅力の一つでもありますから。

※冪等性(べきとうせい):「誰が何回作業を行っても、必ず毎回同じ結果になる」性質のこと。毎回同じ品質を提供できるというメリットがある。

告知

私事ですが、今週木曜日の27日に開催される「Serverless Meetup Tokyo #16」イベント(下記)にて、スピーカーをさせて頂きます。(オンライン開催です)

serverless.connpass.com

コロナウィルスの影響で、オンライン開催に変更されましたが、発表自体は予定通り行いますので、よろしくお願いいたします。
※当日は、YouTubeでのライブ配信も行われます。

発表では、下記について触れる予定です

  • AWS
  • Infrastructure as Code(IaC)&Serverless Framework(これがメイン...にしたい)
  • AWS Athena&AWS QuickSight

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