serverless.ymlを一行一行、見ていくしかないんや

8 min読了の目安(約7700字TECH技術記事

どうも、こんにちは。お元気ですか?

今年は夏が来るのが遅いな、と思っていたら、
すごく暑い夏をいくつか残していって
あっという間に過ぎていきましたね。

以前はServerless FrameworkやPythonについてなど
有識者の方々のを見たり、聞いたりして、教わりながら
色々と新しいことを体験しながら覚えていったので
それらの知見? 感想? をここに残しておきたいと思います。

復習を兼ねて、serverless.ymlを一行一行、見ていこうと思います

まずはこんな記述がありました、と。

service: xxxxx-xxxxx
frameworkVersion: ">=1.53.0 <2.0.0"

plugins:
  - serverless-pseudo-parameters

custom: ${file(../../serverless.common.yml):custom}

provider:
  name: aws
  runtime: python3.8
  stage: ${opt:stage, self:custom.defaultStage}
  region: ap-northeast-1
  profile: ${opt:profile, ''}
  logRetentionInDays: 30
  environment:
    TZ: Asia/Tokyo
    STAGE: ${self:provider.stage}
    API_ENDPOINT: ${self:custom.api_endpoint}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - ssm:GetParameter
        - ssm:PutParameter
      Resource:
        - arn:aws:ssm:${self:provider.region}:#{AWS::AccountId}:parameter/*
    
functions:
  Refresh:
    handler: handler.xxx_handler
    layers:
      - ${self:custom.requirements_layer}
      - ${self:custom.shared_layers}
    events:
     - schedule: cron(0 16 ? * WED *) # 1週間おき(UTC -> JST毎週木曜の1:00AM)に実行

見ていくぞ! 英語ばっかり!

service: xxxxx-xxxxx

  • ここでつけた名前がLamda関数やCloudFormationの一覧に登場します
  • xxxxx-xxxxx-<ステージ名>-<Lambda画面ではここにfunctionsの名前が追記されます>

frameworkVersion: ">=1.53.0 <2.0.0"

  • バージョン範囲です、1.53.0以上、2.0.0未満、数値の左にある frameworkVersion に対して不等号が向けられてるんですね
  • 公式ドキュメントによると チームの全員がまったく同じ設定を使用し、予期しない問題が発生しないように、正確なバージョンに固定することをお勧めします だそうです
  • 正確なバージョンとは frameworkVersion: "=1.0.3" こう書くようです

plugins:

  • 色々とプラグインが出回っているようです(出回っているというと、海賊版みたいな雰囲気ありますね)
  • Serverless Frameworkのメリットはこのプラグインが使えることにあるようです

- serverless-pseudo-parameters

custom: ${file(../../serverless.common.yml):custom}

  • ここから ../../serverless.common.yml の位置にある、 serverless.common.yml の中身の custom に書いてあることを、ここでも custom という変数名で使うよ、と

provider:

  • プロバイダー(回線をインターネットと繋げる役割を担う接続事業者)ですね
  • ここではクラウドサービスとかコンテナサービス(azure とか Google Cloud Platform とか)のようです(ご指摘いただきました、ありがとうございます)

name: aws

  • プロバイダーはAWSです

runtime: python3.8

  • ここで使用するpython言語のバージョンは3.8にします、と

stage: ${opt:stage, self:custom.defaultStage}

  • ステージ変数というらしいです
  • 関数のステージはデフォルトで「dev」に設定されています
  • 開発ステージ名はすべて dev と設定しておいて
  • 本番ではprdとしておくと見分けがつく
  • デプロイしたあとの設定名に必ずついてくる名前です
  • opt:stageでステージ名は改めて self:custom.defaultStage にしますと言っています
  • self(自分の)custom ../../serverless.common.yml に書いてある defaultStage という欄を参照してください(ここではdevです)

region: ap-northeast-1

  • リージョン(地域)です
  • ap-northeast-1はAWSの指定で アジアパシフィック (東京) になります

profile: ${opt:profile, ''}

  • プロファイル指定ですが、ここでは特使指定せず、デプロイ時に追記してください、もしくは、あとで指定があればここに、と
  • プロファイルの詳しくは、先日私が書いた「slsコマンドを使って、デプロイを行った」を参照

logRetentionInDays: 30

  • ログは30日間保存しててください、と設定

environment:

  • 直訳で環境ですが、ここでは環境変数となります(ご指摘いただきました、ありがとうございます)

TZ: Asia/Tokyo

  • タイムゾーン(地域ごとに標準時間は異なり、それらの標準時間帯)をAsia/Tokyo

STAGE: ${self:provider.stage}

  • ここでも念のためstage dev を追記

API_ENDPOINT: ${self:custom.api_endpoint}

  • API(にアクセスするためのURL)は cunstomapi_endpoint の項目に書いてあります

iamRoleStatements:

  • IAMロールの設定ですね
  • ステートメントは申告とかの意味もありますから、許可申請とかですね

- Effect: Allow

  • この下に書かれる項目の効果を許可(Allow)してます
  • 不許可はDenyを使うと思いますが、不許可ならそもそも書かなくていいと思うので、基本Allowと思います

Action:

  • じゃあ何の動作を許可するの、と

- ssm:GetParameter

  • 今回はこれと

- ssm:PutParameter

  • この2つです
  • ssmというのは、AWS Systems Managerのことで、その中にある、アプリケーション管理 > パラメータストアの挙動の許可申告をしています
  • パラメータストアというのはパスワードとかデータベースの文字列を暗号化などして、格納するのに使用します

Resource:

  • リソース:資源、仕様

- arn:aws:ssm:${self:provider.region}:#{AWS::AccountId}:parameter/*

functions:

  • 働きかけとか関数の意味らしいです
  • ここからLambda関数の記述が入ります

Refresh:

  • これは私が任意でつけた名前です
  • ここにつけた名前はLambda関数一覧で、1行目の service で付けた名前のあとに追記されます

handler: handler.xxx_handler

  • 取り扱う関数はありますか? -> handler. pyの中の xxx_handler の関数をここで使います
  • ちなみに xxx_handler の関数には app. pyの中の event の関数を使うと書いてあります

layers:

  • AWSをプロバイダーとして使用している場合(provider: name: aws)、サービス内のすべてのレイヤーはAWS Lambdaレイヤー
  • Lambda Layersは、複数の関数で共有されるコードとデータを集中管理する方法
  • 下記の2つをレイヤーに分けて使用しますよ、と

- ${self:custom.requirements_layer}

  • ../../serverless.common.yml に記述してある requirements_layer を参照します
  • ここでは 該当するCloudFormationの出力に設定されているキー までの記述が書かれていました

勘違いして覚えたこと(消してもいいですが残しておきます)

layers:

  • ここでは layers というディレクトリの中に別のserverless.ymlファイルを作っており、その中で serverless-python-requirements というプラグインを呼び出しています
  • AWS Lambdaに分割してファイルをアップロードすることで、わかりやすさとデプロイの時間短縮ができている、と

- ${self:custom.requirements_layer}

さ、気を取り直して続きです!

- ${self:custom.shared_layers}

  • ../../serverless.common.yml に記述してある shared_layers を参照します
  • ここでは 該当するCloudFormationの出力に設定されているキー までの記述が書かれていました

events:

- schedule: cron(0 16 ? * WED *) # 1週間おき(UTC -> JST毎週木曜の1:00AM)に実行

  • 今回は cron式 を使って、毎週木曜深夜1時に実施する旨を書きました
  • 当初JSTという日本時間で設定していました( TZ: Asia/Tokyo だったためです)が、どうやら、 ここの標準時間はCloudWatchに依存するようで、実施したい9時間前(UTFとかGMTとか海外の標準時間)を指定する ようです
  • cronの中に書かれている ? は、日または週日(=曜日)用の値で、疑問符である必要があるそうです
  • [日] フィールドに 7 と入力し、7 日が何曜日であってもかまわない場合、[曜日] フィールドに ? を入力できるそうです
  • 今回は水曜日(日本時間で木曜日)は指定して、何日を指定しないので[日] フィールドに ? と入力しました
  • 公式ドキュメントによると , - * ? / L W の中のどれでも良さそうですが、日と曜日だけを表しているものとして ? もしくは L で良さそうです

終わりに 長かった!

間違いがあればご指摘いただければと思います
次はもっと長くなるであろう、Python部分の記述を1行1行見ていこうと思います

ある晴れた日の午後、道を歩いていたら、
赤い洗面器を頭に乗せた男が歩いてきました。

洗面器の中にはたっぷりの水、
男はその水を一滴もこぼさないように、
ゆっくりゆっくり歩いてきます。

私は勇気をふるって
『ちょっとすいませんが、あなたどうして、
 そんな赤い洗面器なんか頭に乗せて歩いてるんですか?』
と聞いてみました。

すると男は答えました。

『それは…』

えー、お察ししますー
それではこの辺で失礼いたしますー