OCI Functions で OCI CLI を実行してみる。(Fn HotWrap, Oracle Cloud Infrastructure)

(※2024/12/22追記)改良版を書きました。是非下記記事も参照して下さい彡(^)(^)

https://qiita.com/ora_gonsuke777/items/f1309c67d0fb247b975e

OCI Functions で OCI CLI を実行してみます。Functions が基盤とする Fn には HotWrap という仕組みがあり、この HotWrap で UNIX/Linux のコマンドを実行できます。HotWrap の仕組みを利用して OCI CLI を OCI Functions で実行してみますやで。
彡(^)(^)

# 1. Fn HotWrap について

Fn HotWrap は UNIX/Linux のコマンドを Dockerコンテナとして作成します。Fn HowWrap によるコマンドの実行は下記で解説されています。

> Make your own Linux command Function with HotWrap and a Customer Docker Image
> https://fnproject.io/tutorials/docker/CustomLinuxContainer/

下記は Fn HotWrap の GitHubリポジトリです。

https://github.com/fnproject/hotwrap

# 2. 環境

下記記事で作成した Compute + Fn + OCIR(Dockerレジストリ) + OCI Functions の環境を利用します。
OCI CLI はこの記事では OCI CLI の Dockerイメージ を使用しているため、Compute の OCI CLI には依存しません。

https://qiita.com/ora_gonsuke777/items/2efa42eb189778c5417e

# 3. 動的グループの作成と権限付与(リソース・プリンシパル)

OCI Functions が OCI CLI を実行できるようにするための権限付与(リソース・プリンシパル)を行います。

下記は作成した動的グループです。Functions のみの実行であればインスタンス・プリンシパル(instance.～)は不要です。今回は Fn をビルドする Compute でも OCI CLI を実行したいのでリソース・プリンシパル(resource.～)と一緒に定義しています。

```shell
Any {instance.compartment.id = 'ocid1.compartment.oc1.............'}
Any {resource.compartment.id = 'ocid1.compartment.oc1.............'}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/59895b34-fc05-f644-cf37-5f45629f68b9.png)

作成した動的グループに権限(ポリシー)を付与します。今回は Object Storage の権限を付与します。

```shell
Allow dynamic-group ayu-dynamic-group01 to manage buckets in compartment ayu-compartment01
Allow dynamic-group ayu-dynamic-group01 to manage objects in compartment ayu-compartment01

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/c29d45ec-9b6c-c96d-bb86-0c2899d8b030.png)

# 4. OCI Functions関数の作成とデプロイ

まず Fn のコンテキスト設定、Dockerレジストリのログインを済ませておきます。これらの詳細は上記 2. の記事を参照して下さい。

```shell
fn list context
fn use context ayu-compartment01
docker login -u '<namespace>/<ユーザー名>' <レジストリ名>
<レジストリのパスワードを入力>
```

```shell
[opc@ays-prv-compute02 ~]$ fn list context
CURRENT NAME                    PROVIDER        API URL                                         REGISTRY
*       ayu-compartment01       oracle          https://functions.us-phoenix-1.oraclecloud.com  phx.ocir.io/xxxxxxxxxx/ayu-repo1
        default                 default         http://localhost:8080
[opc@ays-prv-compute02 ~]$ fn use context ayu-compartment01

Fn: Context ayu-compartment01 currently in use

See 'fn <command> --help' for more information. Client version: 0.6.34
[opc@ays-prv-compute02 ~]$ docker login -u 'xxxxxxxxxxxxxx/oracleidentitycloudservice/xxxxxxxx.xxxxxxxx@xxxxxxxxx.xxxxxxxxxx' phx.ocir.io
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
Password:
Login Succeeded!
[opc@ays-prv-compute02 ~]$
```

上記 2. の環境でディレクトリを作成して移動します。

```shell
mkdir hotwrap-func
cd hotwrap-func
```

func.yaml を作成します。コピペで OK

```yaml:func.yaml
schema_version: 20180708
name: hotwrap-func
version: 0.0.1
```

同じディレクトリに Dockerfile も作成します。こちらもコピペ

```Dockerfile:Dockerfile
FROM ghcr.io/oracle/oci-cli:latest

COPY --from=fnproject/hotwrap:latest /hotwrap /hotwrap

ENV OCI_CLI_AUTH=resource_principal

CMD ["oci", "${OCI_CLI_COMMAND}"]

ENTRYPOINT ["/hotwrap"]
```

Dockerイメージをレジストリにデプロイします。--app で指定するアプリケーション名は上記 2. の記事で作成済みのものを流用します。

```shell
fn --verbose deploy --app ayu-functions1
```

以下はデプロイ時の実行ログ(抜粋)となります。

```shell
[opc@ays-prv-compute02 hotwrap-func]$ fn --verbose deploy --app ayu-functions1
Deploying hotwrap-func to app: ayu-functions1
Bumped to version 0.0.2
Using Container engine podman
Building image phx.ocir.io/xxxxxxxx/ayu-repo1/hotwrap-func:0.0.2
Dockerfile content
-----------------------------------
FROM ghcr.io/oracle/oci-cli:latest

COPY --from=fnproject/hotwrap:latest /hotwrap /hotwrap

ENV OCI_CLI_AUTH=resource_principal

CMD ["oci", "${OCI_CLI_COMMAND}"]

ENTRYPOINT ["/hotwrap"]

-----------------------------------
FN_REGISTRY:  phx.ocir.io/xxxxxxxx/ayu-repo1
Current Context:  ayu-compartment01
TargetedPlatform:  amd64HostPlatform:  amd64
STEP 1/5: FROM ghcr.io/oracle/oci-cli:latest
STEP 2/5: COPY --from=fnproject/hotwrap:latest /hotwrap /hotwrap
--> Using cache 13c9bd7483e3b9813ed98399bd3359a0a2108eb53b3c821bd305b46a12d0dc25
--> 13c9bd7483e3
：
Updating function hotwrap-func using image phx.ocir.io/xxxxxxxx/ayu-repo1/hotwrap-func:0.0.2...
Successfully created function: hotwrap-func with phx.ocir.io/xxxxxxxx/ayu-repo1/hotwrap-func:0.0.2
[opc@ays-prv-compute02 hotwrap-func]$
```

デプロイが成功すると OCIコンソールからは以下のように参照できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/250b87d4-3fc7-3084-f62f-9ccc91ac6c70.png)

# 5. OCI Functions による OCI CLI の実行

fn configコマンドで関数(hotwrap-func)の環境変数OCI_CLI_COMMAND に OCI CLI の oci～ よりも後のオプションを指定します。ここではコマンドラインから環境変数を設定していますがOCIコンソールからも設定可能です。
今回は Object Storage のバケット・リストを取得してみます(oci os bucket list)。

```shell
fn config function ayu-functions1 hotwrap-func OCI_CLI_COMMAND "os bucket list --compartment-id ocid1.compartment.oc1......."
```

下記は環境変数設定の実行ログです。

```shell
[opc@ays-prv-compute02 hotwrap-func]$ fn config function ayu-functions1 hotwrap-func OCI_CLI_COMMAND "os bucket list --compartment-id ocid1.compartment.oc1......."
ayu-functions1 hotwrap-func updated OCI_CLI_COMMAND with os bucket list --compartment-id ocid1.compartment.oc1.......
[opc@ays-prv-compute02 hotwrap-func]$
```

環境変数OCI_CLI_COMMANDの設定が完了した関数(hotwrap-func)を実行します。

```shell
fn invoke ayu-functions1 hotwrap-func
```

下記は関数(hotwrap-func)の実行結果です。

```shell
[opc@ays-prv-compute02 hotwrap-func]$ fn invoke ayu-functions1 hotwrap-func
{
  "data": [
    {
      "compartment-id": "ocid1.compartment.oc1........",
      "created-by": "ocid1.saml2idp.oc1........",
      "defined-tags": null,
      "etag": "f1d572a9-21cb-43a1-88b3-9ff00582cfa2",
      "freeform-tags": null,
      "name": "ayu-bucket1",
      "namespace": "xxxxxxxx",
      "time-created": "2020-12-01T13:52:07.029000+00:00"
    },
    {
      "compartment-id": "ocid1.compartment.oc1........",
      "created-by": "logging/9A5C4B3CF0F9A881D4C6CFAAFCEA78DB2106BD3582B1A485072E9BF75EB2",
      "defined-tags": null,
      "etag": "d8baa063-3902-4963-9843-a7c932aa7303",
      "freeform-tags": null,
      "name": "oci-logs._flowlogs.ocid1.compartment.oc1........",
      "namespace": "xxxxxxx",
      "time-created": "2024-01-31T13:56:02.061000+00:00"
    }
  ]
}
```

Object Storage のバケット・リストを取得できています。
彡(^)(^)

# 6. まとめ

OCI Functions で OCI CLI を実行できました。OCI Functions は直近で Scheduled Functions という定時実行の機能がリリースされており、今回の記事と下記を組み合わせると色々できそうです。夢が広がりんぐ。
彡(^)(^)

> OCI Functionsのスケジュール実行のサポート
> https://blogs.oracle.com/oracle4engineer/post/oci-functions-scheduled

次回は Scheduled Functions で OCI CLI を定時刻で実行する検証をしてみようと思います。

# Special Thanks!
こちらの記事は日本オラクル社の S.Kさん と K.Dさん が社内で検証されたものを記事化したものです。この場で篤く御礼申し上げます。彡(^)(^) ｻﾝｶﾞｯﾂ