【OCI クラウド移行ガイド】 AWS Lambda を OCI Functionsへ移行してみた（その1:Hello World編）

# OCIクラウド移行ガイドとは

オンプレミスやAWSなど、複数のプラットフォームからOracle Cloud Infrastructureへの移行プロジェクトに取り組んでいるクラウドエンジニア（@araidon,@kazunishi,@yama6）による、OCI移行手順をまとめたシリーズ記事です。
各回、サンプルワークロードから対象サービスを取り上げ、移行手順をガイドいたします。
まとめ記事は以下になります。

https://qiita.com/yama6/items/b197c0fe3ec75eb02637

# 移行するサービス：AWS Lambda

今回、移行対象とするのはAWS Lambdaです。

AWS Lambdaの公式サンプルのHello Worldのソースコードを元に、OCI Functionsで動くように書き換えて見ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276568/c42f9d47-9594-4ab4-08ab-f69f0e048677.png)

# OCI Functionsとは
一言でいうと、OCIでのFaaSサービスです。
いわゆるサーバレスサービスで、AWS Lambda、Azure Functions、Google Cloud Functions等と同等のサービスです。

AWS Lambdaと比較して、価格面で優位となっているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276568/17439df8-faea-79f7-bcba-f2b6b1d207aa.png)

https://speakerdeck.com/oracle4engineer/functions-overview


# 前提条件
- 言語はPythonとします
- AWS LambdaとOCI Functionsの環境構築について、今回は触れません。

# AWS LambdaのHello World公式サンプル
関数作成時の、設計図（blueprint）の、[Hello world function] python3.10を参照します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276568/3e632f97-42b4-6071-9e1c-f6f812d8bed3.png)


```python: (AWS)lambda_function.py
import json

print('Loading function')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))
    print("value1 = " + event['key1'])
    print("value2 = " + event['key2'])
    print("value3 = " + event['key3'])
    return event['key1']  # Echo back the first key value
    #raise Exception('Something went wrong')
```

Lambdaのテストイベントとして、以下のjsonファイルを使用して呼び出します。

```json: イベントjson
{
  "key1": "Hello world",
  "key2": "value2",
  "key3": "value3"
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276568/0f6a1952-2a63-e9ed-2a5b-511da1c5d11a.png)

# 書き換えにあたり注意すること
AWS LambdaとOCI Functionsはサービスから呼び出される際のハンドラ部分の挙動が違います。

## ・Lambda
ランタイム設定のハンドラの設定が参照されます。
下記画像であれば、lambda_function.py の lambda_handler メソッドが読み込まれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276568/187cda7d-0f10-a244-afe6-85ab8ca299cb.png)

```python: AWSのhundler部分
def lambda_handler(event, context):
```

## ・OCI
functionsを定義する設定ファイル、 **func.yaml** 内の、**entrypoint:列** が参照されます。
下記記載であれば、func.py の handler が読み込まれます。

```yaml: func.yaml
schema_version: 20180708
name: hello-fromlambda
version: 0.0.7
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256
```

AWSのソースコードのファイル名とハンドラ名をそのまま使うのであれば、 **entrypoint:列** を書き換え、lambda_function.py の lambda_handler メソッドが読み込まれるようにします。
```yaml: func.yaml
entrypoint: /python/bin/fdk /function/lambda_function.py lambda_handler 
```


# 書き換え
先に完成版を見せます。
```python: (OCI)lambda_function.py
import json
import io ### 1. 行追加-イベントデータの受信に必要 ###

print('Loading function')

def lambda_handler(ctx, data: io.BytesIO = None): ### 2. 書き換え-handlerの仕様違いによる変更 ###

    try: ### 3. 行追加-イベントデータからjsonに変換する際の例外処理に必要 ###
        event = json.loads(data.getvalue()) ### 4. 行追加-イベントデータからjsonに変換する処理 ###
        #print("Received event: " + json.dumps(event, indent=2))
        print("value1 = " + event['key1'])
        print("value2 = " + event['key2'])
        print("value3 = " + event['key3'])
    except (Exception, ValueError) as ex: ### 5. 行追加-イベントデータからjsonに変換する際の例外処理に必要 ###
        print("error pasrsing json payload" + str(ex)) ### 6. 行追加-イベントデータからjsonに変換する際の例外処理に必要 ###

    return event['key1']  # Echo back the first key value
```

5箇所の変更が必要でした。
イベントデータの受け取り部分に起因する行追加が5箇所、 handler の仕様違いによるメソッド定義行の変更が1箇所でした。

# OCIでの動作確認

```bash
$ echo -n '{"key1": "Hello World", "key2": "value2", "key3": "value3"}' | fn invoke hello-app hello-fromlambda
Hello World
$ 
```
# まとめ
元のソースコードが小さいだけに、書き換えが多いように見えました。
Lambda と Functionsの仕様吸収である程度は仕方ありませんが、実際はそこまで多くないようです。

次回は、S3と連携したLambdaを OCI Functionsに書き換えてみたいと思います。

# 参考

https://speakerdeck.com/oracle4engineer/functions-overview

https://docs.aws.amazon.com/ja_jp/lambda/

https://docs.oracle.com/ja-jp/iaas/Content/Functions/home.htm