シリーズ目次
- AWS Lambda 関数を Docker コンテナを使ってビルド & デプロイ
- Fortran を AWS Lambda のCustom Runtime で実行する
概要
記事 AWS Lambda Custom Runtimesを利用してFortranで数値計算 #reinvent を参考に
Fortran を AWS Lambda の Custom Runtime で実行する方法を書きました
AWS Lambda のCustom Runtime とは、
AWS Lambda ランタイムは、どのプログラミング言語でも実装できます。
ランタイムは、関数が呼び出されたときに Lambda 関数のハンドラメソッドを実行するプログラムです。
カスタムランタイムを使用するには、
と、Docker から生成したファイル(今回はhello)
を用いて実行します。
AWS Lambda 関数を 作成するには以下の3ステップが必要です
1.Docker イメージを作成する
2.Docker イメージから 実行ファイルを生成
3.**圧縮ファイル(.zip)**を Amazon Lambda にアップロード
前提条件
Docker Desktop がインストールされていること
この記事は Mac 上で Docker を用いて操作しています。
この記事の作業はローカル環境に Docker Desktop がインストールされていることを前提で進めます。インストールされていない場合は、インストールしてから進めてください。
Amazon CLI がインストールされていること
Amazon CLI
https://aws.amazon.com/jp/cli/
aws configure (初期化) が済んでいること
> aws configure
AWS Access Key ID [None]: ATI********CS
AWS Secret Access Key [None]: ***erg***sdfg***bs1sderg**
Default region name [None]: ap-northeast-1
Default output format [None]: json
gfortran がインストールされていること
Mac (macOS Catalina, 10.15.2)にgfortranとPGI Fortran 19.10をインストールしたときの手順
% brew install gcc
インストールが完了したら,そのままターミナルでgfortran --version
コマンドを実行してください.以下のようなメッセージが表示されれば,インストールは成功しています.
% gfortran --version
GNU Fortran (Homebrew GCC 11.2.0) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
実装
手順1: 4つのテキストファイルを用意する
作業するフォルダを決めて
以下の4つのテキストファイルを作成しましょう
それぞれのファイルの中身は以下の通りとします。
hello.f90
program hello
implicit none
write(*,*) 'Hello World!'
stop
end program hello
【解説】
今回の Fortran コードは、ただ 'Hello World!' を出力するだけ
Dockerfile
FROM amazonlinux:latest
RUN yum -y install gcc-gfortran glibc-static
COPY hello.f90 /
RUN gfortran -c hello.f90
RUN gfortran -static -o hello hello.o
CMD /bin/bash
【解説】
FROM 命令で amazonlinux の AWS 公式の公開イメージを指定しています.
amazonlinux に gfortran をインストールしています。
COPY コマンドでローカルに配置されている Lambda 関数本体である hello.f90 ファイルをイメージにコピーしています。そして CMD で Lambda 関数のハンドラーを渡しています。
gfortran で hello.f90 をコンパイルして、配置しています。
bootstrap
#!/bin/sh
set -euo pipefail
LM=$(echo "$_HANDLER" | cut -d. -f2)
while true; do
HEADERS="$(mktemp)"
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)
RESPONSE="$(./$LM "$EVENT_DATA")"
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
【解説】
ほぼ公式チュートリアルのものと変わりませんが、実行バイナリの名前をハンドラ(環境変数$_HANDLER)から指定するようにしています。
Makefile
TARGET=hello
IMAGE=temp:latest
all: $(TARGET).zip
$(TARGET).zip: $(TARGET) bootstrap
zip $(TARGET).zip bootstrap $(TARGET)
$(TARGET): hello.f90
docker build -t $(IMAGE) .
docker run -it --rm -v `pwd`:/tmp -w /tmp --entrypoint=cp $(IMAGE) /$(TARGET) /tmp
解説
なんだかよくわかりませんが、なにやら Docker にイメージをビルドして bootstrap ファイルと一緒に
圧縮しているみたい
手順2: make コマンドの実行
$ make
なにやらコマンドが走ります。
hello というファイルと hello.zip というファイルが生成されます。
手順3.Lambda関数に アップロードする手順
AWS Lambda ダッシュボードから 関数作成 ボタンをクリックする
- 一から作成
- ランタイムを
Amazon Linux2 でユーザー独自のブートストラップを提供する
を選択します。
ランタイム設定を変更
ハンドラを fortran.hello
に変更してくださ
hello.zip ファイルをアップロード
アップロードボタンから .zipファイルを選択し、 生成しておいたhello.zip
を選択してください
手順4:作成された関数を実行確認
そしていよいよ実行することができます。作成された関数を実行してみましょう。
> aws lambda invoke --function-name fortran_hello output ; cat output
正常に返ってきました!!