概要

仕事をしていると、歴史のあるシェルスクリプトがEC2で動いていたりすることがある。
そういったスクリプトをなにかしらのスクリプト言語で書き換えるのもやぶさかではないのだが、数が多いと諦めの気持ちが湧き出てくる。
そこで、シェルスクリプトのままでもLambdaにデプロイしてバッチ的に動かして、サクッと移行できたりしないかなという思いが出てきた。
そこで、Lambdaのデプロイツールにlambrollを検証してみることにした。

インストール

手元がMacOSなのでbrewでインストール。

$ brew install fujiwara/tap/lambroll
$ lambroll versions
2023/01/18 23:14:53 [info] lambroll v0.14.1 with function.json
2023/01/18 23:14:53 [error] failed to load function: open function.json: no such file or directory

使ってみる

とりあえす空ディレクトリで下記を実行する

$ lambroll init --function-name=testLambrollFunction --profile XXXXX
2023/01/18 23:22:05 [info] lambroll v0.14.1 with function.json
2023/01/18 23:22:05 [info] function testLambrollFunction is not found
2023/01/18 23:22:06 [info] creating .lambdaignore
2023/01/18 23:22:06 [info] creating function.json
2023/01/18 23:22:06 [info] completed

出来上がったJSONを見ると、デフォルトでは nodejs14.x が選択されていた。

{
  "FunctionName": "testLambrollFunction",
  "Handler": "index.handler",
  "MemorySize": 128,
  "Role": "arn:aws:iam::489667813116:role/YOUR_LAMBDA_ROLE_NAME",
  "Runtime": "nodejs14.x",
  "Timeout": 3
}

lambrollではIAMは作らないので、別で作る必要がある。
このあたりはlambda-uploaderと似ている。シンプルで良い。
元々Lambdaを実行するためだけのIAM Roleは別で作っていたのでそれを書いてあげる。

あと、bashに関してはbash layerというのがあったらしく、下記を参考にしながら書いてみたのだが、よく見るとbash-lambda-layerは No Longer Support になっていた。

しかも、kayacさんもforkしたけど、ReadOnlyになっていた。
ということで、素直にカスタムランタイムを使おうと思い、下記を参考にしてみることにした。

https://dev.classmethod.jp/articles/tutorial-lambda-custom-runtime-with-shellscript/

ファイルとしては bootstrap と function.sh とlambrollの設定ファイルである function.json があれば良い。

function.json はこれだけで良い。

{
  "FunctionName": "testLambrollFunction",
  "Handler": "function.handler",
  "MemorySize": 128,
  "Role": "arn:aws:iam::自分で作ったLambda実行ロール",
  "Runtime": "provided",
  "Timeout": 3
}

bootstrap はクラメソさんが参考にしたAWSチュートリアルそのまま。

#!/bin/sh

set -euo pipefail

# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"

# Processing
while true; do
  HEADERS="$(mktemp)"
  # Get an event
  EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
  REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)

  # Execute the handler function from the script
  RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")

  # Send the response
  curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done

function.sh は雑にこんな感じ。

function handler() {
    for i in $(seq 1 5);do
        echo $i
    done
    echo "Hello World\n"
    uname -a
    cat /etc/os-release
}

手元で検証

lambrollは手元で検証できるのでやってみる。
まずはデプロイ。

$ lambroll deploy --profile XXXXX

そして実行。

$ lambroll invoke --profile XXXXX
2023/01/19 00:23:11 [info] lambroll v0.14.1 with function.json
Enter JSON payloads for the invoking function into STDIN. (Type Ctrl-D to close.)
{}
1
2
3
4
5
Hello World\n
Linux 169.254.57.69 4.14.255-285-225.501.amzn2.x86_64 #1 SMP Wed Jul 13 16:23:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
VARIANT_ID="202205231238-al2018.03.882.0"
2023/01/19 00:23:13 [info] StatusCode:200
2023/01/19 00:23:13 [info] ExecutionVersion:$LATEST

うむ、Amazon Linux1だったwこれは古いw
lambrollの指定の仕方が間違っていた。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-runtimes.html

--  "Runtime": "provided",
++  "Runtime": "provided.al2",

al2をサフィックスで指定することで Amazon Linux 2 になる。
で再デプロイしてinvokeした結果。

$ lambroll invoke --profile XXXXX
2023/01/19 00:29:55 [info] lambroll v0.14.1 with function.json
Enter JSON payloads for the invoking function into STDIN. (Type Ctrl-D to close.)
{}
1
2
3
4
5
Hello World\n
Linux 169.254.159.73 4.14.255-285-225.501.amzn2.x86_64 #1 SMP Wed Jul 13 16:23:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
VARIANT_ID="202205231235-2.0.821.0"
2023/01/19 00:29:57 [info] StatusCode:200
2023/01/19 00:29:57 [info] ExecutionVersion:$LATEST

ちゃんとAmazon Linux 2のカスタムランタイムで実行できてる。

感想

触りの触りだけど、サクッとデプロイして手元からLambdaを実行できるのでとても便利。
まだカスタムランタイムの癖というか、ちょっと調べた限りだとamazon linuxのカスタムランタイムイメージにはyumがなかったりするので、カスタムランタイムそのものの深堀りはしていきたいところ。

<p style='padding: 5px;'>