ようへいの日々精進XP

よかろうもん

furikake-serverless を作った 〜 今夜は炊き込みご飯なので furikake は要らない 〜

これは

qiita.com

初老丸 Advent Calendar 2018 第 13 日目の記事になる予定です.

tl;dr

AWS Lambda のランタイムとして Ruby がサポートされました. 待ちに待っていた方, もう待ちくたびれた方, 悲喜こもごもだと思います.

aws.amazon.com

さて, 早速ではありますが, Lambda 上で動かしてみたいと思っていた furikake について, Lambda 上で実行出来るようにしてみましたので, 紹介させていただきます.

github.com

ちなみに, furikake を Lambda で動かすのは単なる興味からだけではなく, 以下のようなメリットがあると考えている為です.

  • 実行環境 (サーバーや個人端末) が不要
  • CloudWatch Events と組み合わせて定期実行することにより, Backlog Wiki 上の情報を新鮮に保つことが出来る

EC2 インスタンスのバックアップスクリプト等も Lambda を利用して取得していたりますので, ドキュメントについても同じように Lambda を利用して常に最新の状態に保つことが出来るのではと考えています. (同じようなアプローチで Fargate のスケジュールタスクを利用する方法もあると思いますが, そちらは別の機会に試してみたいと思います.)

furikake-serverless チュートリアル

必要なもの (準備しておくもの)

direnv も利用出来るようにしておくとより良いと思います.

セットアップ

sam で利用する S3 バケットを作成する

aws s3 mb s3://your-sam-s3-bucket

git clone

git clone https://github.com/inokappa/furikake-serverless.git

event.json の修正

event.sample.json を修正して event.json を作成します.

{
  "resources": {
    "aws": [
      "alb",
      "clb",
      "directory_service",
      "ec2",
      "elasticsearch_service",
      "kinesis",
      "lambda",
      "rds",
      "security_group",
      "vpc",
      "vpc_endpoint"
    ]
  },
  "backlog": {
    "projects": [
      {
        "space_id": "example",
        "top_level_domain": "jp",
        "wiki_id": "1234567",
        "wiki_name": "Lambda 送信テスト",
        "header": "# Test Header\n[toc]\n## Sub Header\n",
        "footer": "## Test Footer\n### Sub Footer"
      }
    ]
  }
}

resources.aws 以下のリソース名を必要に応じて, space_id 等を環境に応じて修正します. これは furikake の .furikake.yml と同じ内容になっていて, 単に YAMLJSON の違いです.

sam の template.yml の生成

KMS を利用して Backlog の API キーを暗号化しますので, make template を実行して template.yaml を生成します.

$ make template

以下のように出力されるので, KMS の Key ID を API キー, 実行間隔 (任意なので, 何も指定しない場合には Enter を押下), タイムゾーン (任意なので, 何も指定しない場合には Enter を押下) を入力します.

$ make template
KMS の Key ID を入力してください:
xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxx
API キーを入力してください:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
実行間隔を分で入力してください (デフォルト 60):

タイムゾーンを入力してください (デフォルト Asia/Tokyo):

template.yaml created.

上記のように出力されると, 正常に template.yaml が生成されていると思います. 念の為, template.yaml の中身を確認してみます.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'furikake-serverless'

Resources:
  FurikakeServerless:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./src
      Handler: lambda.run
      Runtime: ruby2.5
      Timeout: 900
      Policies:
        - ReadOnlyAccess
        - KMSDecryptPolicy:
            KeyId: xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxx
      Environment:
        Variables:
          ENCRYPTED_BACKLOG_API_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      Events:
        FurikakeSchedule:
          Type: Schedule
          Properties:
            Schedule: rate(60 minutes)
            Input: '{
  "resources": {
    "aws": [
      "alb",
...

Outputs:
  FurikakeServerless:
    Description: Serverless Furikake Lambda Function ARN.
    Value:
      Fn::GetAtt:
      - FurikakeServerless
      - Arn

CloudWatch Events で 60 分毎に Lambda 関数が起動するように設定されています.

...
      Events:
        FurikakeSchedule:
          Type: Schedule
          Properties:
            Schedule: rate(60 minutes)
...

Schedule: の値を修正することで任意の時間で Lambda 関数が起動するようにカスタマイズが可能です.

デプロイ

make packagemake deploy を実行して, Lambda 関数をデプロイします.

# packaged-template.yaml を生成して, 各種ファイルを S3 にアップロードする
make package _BUCKET_NAME=your-sam-s3-bucket

make package を実行した後, packaged-template.yaml が生成されていることを確認します.

# Lambda 関数をデプロイ
make deploy

以下のように出力されることを確認します.

$ make deploy

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - FurikakeServerless

デプロイが完了したらしばらく待ちましょう...デフォルトで 1 時間後.

しばらく放置しておくと

下図のように, 定期的に wiki が更新されていることを確認することが出来ると思います.

f:id:inokara:20181202090256j:plain

いい感じです.

以上

いよいよ Ruby が Lamda 上で動くということで, furikake を Lambda で動かせるようにしてみました. まだ色々と課題はありそうですが, furikake を作ったモチベーションの一つである, ドキュメントの鮮度を常に最新に保つ, しかもお手軽に...がこれで叶ったような気がしています. また, 他にも Lambda で動かしてみたい gem があるので, 引き続き, 試行錯誤してみようかなと思います.