
AWS LambdaのCustom RuntimeでCOBOLを動かしてみた #reinvent
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
一時期Twitterで騒然となった、AWSのCOBOL対応ですが、実際にやってみたいと思います。
Dockerとdocker-composeの環境を整える
まずは、EC2でAmazon Linuxのインスタンスを立ち上げてsshでログインします。そして次の手順でDocker環境を整えます。dockerコマンドで環境情報が表示されれば成功です。
$ sudo yum -y update $ sudo amazon-linux-extras -y install docker $ sudo service docker start $ sudo chkconfig docker on $ sudo usermod -a -G docker ec2-user $ sudo gpasswd -a $USER docker $ sudo systemctl restart docker $ exit # もう1回ログインする $ docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 ....
次に、docker-composeの環境を整えます。
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose $ docker-compose --version docker-compose version 1.23.1, build b02f1306
COBOLをコンパイルする環境を整える
Dockerにインストールするライブラリなどを指定します。
FROM amazonlinux:1
# install tools
RUN yum -y groupinstall "Development tools"
# install GnuCOBOL 2.2
RUN yum -y install gmp-devel ncurses-devel db4-devel
RUN curl -L -o gnucobol-2.2.tar.gz https://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.2/gnucobol-2.2.tar.gz/download
RUN tar zxf gnucobol-2.2.tar.gz
RUN cd gnucobol-2.2 && ./configure --prefix=/usr --libdir=/usr/lib64 && make && make install
# build lambda function package
RUN mkdir -p /cobol/lib
COPY bootstrap /cobol
COPY hello.cob /cobol
RUN cp /usr/lib64/libcob.so.4 \
       /lib64/libm.so.6 \
       /usr/lib64/libgmp.so.10 \
       /lib64/libncursesw.so.5 \
       /lib64/libtinfo.so.5 \
       /usr/lib64/libdb-4.7.so \
       /lib64/libdl.so.2 \
       /lib64/libc.so.6 \
       /lib64/libpthread.so.0 \
       /lib64/ld-linux-x86-64.so.2 \
       /cobol/lib
RUN cd /cobol && \
      COB_LDFLAGS="-Wl,--rpath=./lib -Wl,--dynamic-linker=./lib/ld-linux-x86-64.so.2" cobc -x hello.cob
RUN cd /cobol && zip -r /lambda-cobol-hello.zip ./bootstrap ./hello ./lib
CMD /bin/bash
Lambdaのサンプルそのままです。
#!/bin/sh
 
set -euo pipefail
 
LM=$(echo "$_HANDLER" | cut -d. -f2)
# 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
  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LAMBDA_TASK_ROOT/lib
  RESPONSE="$(./$LM "$EVENT_DATA")"
  echo $RESPONSE
 
  # Send the response
  curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
Dockerを起動してLambda向けのファイルをコピーします。
#!/bin/bash docker build -t lambda-cobol:latest . docker run -it --rm -v `pwd`:/tmp lambda-cobol cp /lambda-cobol-hello.zip /tmp/
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SAMPLE-01.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       PROCEDURE DIVISION.
       MAIN.
       DISPLAY "Hello world!" UPON CONSOLE.
       STOP RUN.
ビルドする
Lambdaにデプロイするために必要なファイルが揃いましたので、セットアップとコンパイルを行います。
$ ./build.sh Successfully built 912ab7f887a4 Successfully tagged lambda-cobol:latest $ ls Dockerfile bootstrap build.sh hello.cob lambda-cobol-hello.zip
ビルド済みのファイルが圧縮されて保存されていることが分かります。
Lambdaにデプロイ
出来上がったZIPを下記のコマンドでデプロイします。
$ export LAMBDA_EXEC_ROLE=arn:aws:iam::XXXXXXXXXXXX:role/exe-lambda
$ aws lambda create-function --function-name hello-cobol --runtime provided --role $LAMBDA_EXEC_ROLE --handler cobol.hello --zip-file fileb://lambda-cobol-hello.zip --region ap-northeast-1
{
    "TracingConfig": {
        "Mode": "PassThrough"
    },
....
作成したLambda関数を動かしてみる

まとめ
当初、Amazon Linux 2上で環境を作ろうとして、ライブラリ関連の相性が悪くてなかなかできませんでした。社内に相談したところ、そのままズバリの解決策を教えてもらえまして、どうにか動作確認まですることができました。山下さんありがとうございました!!














