LoginSignup
12
2

More than 3 years have passed since last update.

opensource COBOLをAWS Lambdaで動かしてみた

Last updated at Posted at 2019-06-17

概要

AWS LambdaがCOBOLをサポートすると発表し、バズった時からかなり遅れていますが、Lambdaを扱う機会があったため、概要をまとめたいとおもいます。

公式でサポートすると発表されていたCOBOLについては、Lambdaの一般メニューからは選択できず、サポート元のBluAge社に問い合わせないと使えないようなので、先人の知恵を借りて、カスタムランタイムとレイヤーを利用した構築を行います。

今回は、Open COBOLの日本語対応版であるopensource COBOLを利用します。

COBOLビルド環境

COBOLのビルド環境の作成ですが、オープンCOBOLソリューション部会のdocker hubにてイメージを作成しているため、そちらを利用します。

dockerイメージ

Lambdaレイヤーの作成

まずはAWS Lambdaのレイヤーを作成する必要があります。
レイヤーの作成には、必要なライブラリを集めてアップロードする必要があります。
ビルドしたCOBOLアプリケーションに対し、lddコマンドで依存性を確認して必要なファイルを選定します。

[root@2a4317c788de /]# ldd lambda/cobol/hello.so
        linux-vdso.so.1 =>  (0x00007fff3b5fd000)
        libcob.so.1 => not found
        libm.so.6 => /lib64/libm.so.6 (0x00007f79179a0000)
        libvbisam.so.1 => not found
        libgmp.so.10 => /lib64/libgmp.so.10 (0x00007f7917728000)
        libncurses.so.5 => /lib64/libncurses.so.5 (0x00007f7917501000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f79172d7000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f79170d3000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f7916d06000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f7917ea5000)

上記のファイル群をlibに、コンパイラと実行用ファイルであるcobcおよびcobcruをbinに格納し、レイヤーとしてアップロードします。

Lambda関数の作成

bootstrapの作成

カスタムランタイムを利用しているため、bootstrapを公式のサンプルをもとに編集します。

bootstrap
#!/bin/sh
set -euo pipefail

# Handler format: <cobol program id>.<dummy>
#
# The script file <cobol program id>  must be located at the root of your
# function's deployment package, alongside this bootstrap executable.

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

    # Execute the COBOL function 
    RESPONSE=$(echo $EVENT_DATA | cobcrun $(echo $_HANDLER | cut -d. -f1))

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

ここではRESPONSE=部分を修正し、cobcrunにてCOBOLアプリケーションを呼び出すようにしています。
$_HANDLERはLambdaの関数で設定する関数名のようなもの。ここではhello.handlerが入力される想定としています。

COBOLプログラム

今回の検証では、実行してレスポンスを返すだけのCOBOLプログラムを作成します。
レスポンス内容は公式サンプルのスクリプトを参考にしています。
また、入力されたEVENT_DATAが扱えるよう、標準入力を読み込むようにしています。

hello.cbl
      ******************************************************************
      *  opensource COBOL and AWS Lambda sample program
      ******************************************************************
       IDENTIFICATION              DIVISION.
      ******************************************************************
       PROGRAM-ID.                 hello.
       AUTHOR.                     nor51010.
       DATE-WRITTEN.               2019-06-11.
      ******************************************************************
       ENVIRONMENT                 DIVISION.
      ******************************************************************
       INPUT-OUTPUT                SECTION.
       FILE-CONTROL.
      ******************************************************************
       DATA                        DIVISION.
      ******************************************************************
       FILE                        SECTION.
      ******************************************************************
       WORKING-STORAGE             SECTION.
       01  HELLO-STR               PIC  X(256).
       01  ACCEPT-STR              PIC  X(128).
       01  SPACE-IDX               PIC  9(005).
      ******************************************************************
       PROCEDURE                   DIVISION.
      ******************************************************************
       MAIN-RTN.
           STRING  '{"statusCode": 200, '         DELIMITED BY SIZE
                   '"body": "Hello from opensource COBOL!", '
                                                  DELIMITED BY SIZE
                   '"input": [;'                  DELIMITED BY SIZE
                   INTO HELLO-STR.
       MAIN-001.
           ACCEPT  ACCEPT-STR FROM CONSOLE.
           PERFORM VARYING SPACE-IDX FROM FUNCTION LENGTH(ACCEPT-STR)
                                     BY   -1
                                     UNTIL SPACE-IDX = 0
              IF   ACCEPT-STR(SPACE-IDX:) NOT = SPACE
                   EXIT  PERFORM
              END-IF
           END-PERFORM.
           STRING  HELLO-STR                      DELIMITED BY ";"
                   ACCEPT-STR(1:SPACE-IDX)        DELIMITED BY SIZE
                   ';'                            DELIMITED BY SIZE
                   INTO HELLO-STR.
       MAIN-002.
           STRING  HELLO-STR                      DELIMITED BY ";"
                   ']}'                           DELIMITED BY SIZE
                   INTO HELLO-STR.
           DISPLAY HELLO-STR.
       MAIN-EXT.
           STOP RUN.

ビルド

Dockerfileを利用して、一括でビルドできるようにします。

以下、今回使用したDockerfileとビルド用のスクリプトです。
dockerhubからイメージを取得し、必要なライブラリをlambda-oss-cobol-layer.zipに、関数用のスクリプトとCOBOLアプリケーションをlambda-oss-cobol-hello.zipにまとめます。

Dockerfile
FROM opensourcecobol/opensource-cobol

# add zip command
RUN yum install -y zip

# create lambda layer
RUN mkdir -p /lambda/layer/lib
RUN mkdir -p /lambda/layer/bin
RUN cp /usr/lib/libcob.so.1 \
       /usr/lib/libvbisam.so.1 \
       /lib64/libm.so.6 \
       /usr/lib64/libgmp.so.10 \
       /lib64/libncurses.so.5 \
       /lib64/libtinfo.so.5 \
       /lib64/libdl.so.2 \
       /lib64/libc.so.6 \
       /lib64/ld-linux-x86-64.so.2 \
       /lambda/layer/lib
RUN cp /usr/bin/cobc \
       /usr/bin/cobcrun \
       /lambda/layer/bin
RUN cd /lambda/layer && zip -r /lambda-oss-cobol-layer.zip ./lib ./bin

# create lambda function
RUN mkdir -p /lambda/cobol
COPY bootstrap /lambda/cobol
COPY hello.cbl /lambda/cobol
RUN cd /lambda/cobol && cobc hello.cbl
RUN cd /lambda/cobol && zip /lambda-oss-cobol-hello.zip ./bootstrap ./hello.sh ./hello.so

WORKDIR /

ENTRYPOINT [""]
build.sh
#!/bin/bash
docker build -t lambda-oss-cobol:latest .
docker run -it --rm -v `pwd`:/tmp lambda-oss-cobol cp /lambda-oss-cobol-hello.zip /lambda-oss-cobol-layer.zip /tmp/

AWSへの適用

レイヤー登録

先ほど作成したZIPファイルからレイヤーを作成します。AWS Lambdaのコンソールからレイヤーの作成にすすみ、ZIPファイルをアップロードします。
layer.png

アップロードが完了すると、Layer画面に表示されるため、ここのバージョンARNをメモしておきます。
layer_new.png

関数の作成

引き続き関数の作成を行っていきます。一から作成でランタイムを、「ユーザー独自のブートストラップを提供する」にします。アクセス権限は必要に応じて設定してください。
func-new.png

関数ができたらレイヤーの追加を行います。DesignerのLayersを選択し、レイヤーの追加を行います。
レイヤーの追加では、先ほどメモしたバージョンARNを入力して追加します。

func-layer.png

続いて、関数コードをアップロードします。Designerの関数名を選択し、コードエントリタイプで「.zipファイルをアップロード」を選択し、先ほど作成したlambda-oss-cobol-hello.zipをアップロードします。

func-cobol.png

ファイル選択後、保存を実行するとコードが展開します。
func-boot.png

動作確認

テストを利用して、動作確認を行います。新しいテストイベントを作成します。今回はテンプレートの「Hello World」を利用します。
func-test.png

作成したテストを実行すると、レスポンスが確認できます。

func-res3.png

実行結果から、opensource COBOLがLambda上で動作し、引数としてイベント情報のJSONを読み込めていることがわかります。

まとめ

AWS Lambdaのカスタムランタイムを利用することで、容易にopensource COBOLのCOBOLアプリケーションをサーバーレス化することができました。
作りこまれている業務ロジックの一部をマイクロサービス化し、新しい基盤システムと連携するなどといった活用が見込まれます。

参考資料

opensource COBOLの提供元とか参考にしたサイトなど
- OSSコンソーシアム
- opensource COBOLリポジトリ
- AWS Lambda超入門
- AWS LambdaのCustom RuntimeでCOBOLを動かしてみた #reinvent

今回作成したファイルはgithubで公開しています。
https://github.com/nor51010/lambda-oss-cobol

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2