自分用メモ。 なんか最初の一歩ばっかやってるな・・・クッソタルいチュートリアルを最速で脱したい貴方へ・・・
1. 環境
- 手元の端末:
- Ubuntu Desktop 23.10
ISOからインストール直後からスタート
2. 事前準備
2.1. 前提のパッケージをインストール
$ sudo apt update
$ sudo apt install curl docker.io
$ sudo usermod -aG docker [ユーザー名]
$ sudo chmod 666 /var/run/docker.sock
docker ps がエラーなしで実行できればOK
2.2. OCI CLIを入れる
$ bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
とりあえずここでは入れるだけで設定はしない。あとでやる。
3. fnをインストール, fn serverを起動
手順(https://fnproject.io/tutorials/install/)に従う
インストール
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
fn serverを起動
$ fn start
fn serverは起動したままにしておく
以降は新しい端末を開いてそこで操作する
4. ローカルでアプリケーションを作成、動作確認
4.1. fnアプリケーションを作成
fn projectのチュートリアル(https://fnproject.io/tutorials/python/intro/)に従ってサンプルアプリケーションを作る。
$ fn init --runtime python pythonfn
$ cd pythonfn
$ fn create app pythonapp
$ fn --verbose deploy --app pythonapp --local
4.2. 動作確認
ローカルで動作確認
# fnコマンドで動作確認
$ fn invoke pythonapp pythonfn
{"message": "Hello World"}
$ echo -n '{"name":"Bob"}' | fn invoke pythonapp pythonfn --content-type application/json
{"message": "Hello Bob"}
# curl用のエンドポイントを取得する
$ fn inspect function pythonapp pythonfn
{
"annotations": {
"fnproject.io/fn/invokeEndpoint": "http://localhost:8080/invoke/01HS3ET2PVNG8G00GZJ0000002"
},
"app_id": "01HS3ERMCWNG8G00GZJ0000001",
"created_at": "2024-03-16T11:02:03.739Z",
"id": "01HS3ET2PVNG8G00GZJ0000002",
"idle_timeout": 30,
"image": "pythonfn:0.0.2",
"memory": 256,
"name": "pythonfn",
"timeout": 30,
"updated_at": "2024-03-16T11:02:03.739Z"
}
# curlコマンドで動作確認
$ curl -XPOST -H "Content-Type: application/json" "http://localhost:8080/invoke/01HS3ET2PVNG8G00GZJ0000002"
{"message": "Hello World"}
$ curl -XPOST -H "Content-Type: application/json" -d '{"name":"Bob"}' "http://localhost:8080/invoke/01HS3ET2PVNG8G00GZJ0000002"
{"message": "Hello Bob"}
5. OCI側準備
5.1. 認証トークンの作成
マネジメントコンソールにログイン
[メニュー] - [Identity & Security] - [Domains] を選択
使用するドメイン(デフォルトはDefault)を選択
Usersをクリック
デプロイするユーザをクリック
左のメニューから "Auth Tokens" を選択
名前を指定して、 [Generate Token] をクリック

作成されたトークンをコピーしてどこかにメモしておく。後で使用する。この画面を閉じると二度と取得できないので注意。なくしたら再作成すればいい。

5.2. VCN, パブリックサブネットの作成
パブリックAPIゲートウェイを経由してOCI Functionsを呼び出す場合、インターネットゲートウェイを経由してFunctionsを呼び出す必要があるため、プライベートサブネット上にFunctionsをデプロイすることはできない。(参照)
Functionsをプライベートサブネットに置くこともできる。こちらの記事をどうぞ
5.2.1. VCN, パブリックサブネットの作成
[メニュー] - [Networking] - [Virtual Cloud Networks] を選択
すでにパブリックサブネットがあればそれを使ってもいい。作るときは [Create Subnet]

5.2.2. セキュリティリストの作成とパブリックサブネットへのアタッチ
左のメニューから "Security Lists" をクリック
左のメニューから "Subnets" をクリック
上で作成したセキュリティリストを選択して、[Add Security List]

要らないセキュリティリストは必要に応じて剥がしておく
5.4. コンテナレジストリの作成
[メニュー] - [Developer Services] - [Container Registry] を選択
[Create Repository] をクリック
5.5. OCI上のFunctionの作成
マネジメントコンソールを開く
[メニュー] - [Developer Services] - [Functions] を選択
5.6. API Signing Keyを設定, OCI CLIの設定
[メニュー] - [Identity & Security] - [Domains] を選択
使用中のドメイン名を選択(今回の例では Default)
左側のメニューから "Users" を選択
Functionsをデプロイするユーザを選択
左側のメニューから "API Keys" を選択
[Generate API Key] を選択し、[Download API Key] ボタンをクリックして秘密鍵をダウンロードする。(公開鍵はダウンロード不要)

[Add] をクリックするとOCI CLIの設定ガイドが表示される。"Copy"リンクをクリックして、内容をコピーする

コピーした内容を /home/<ユーザ名>/.oci/config ファイルとして保存する
ダウンロードした秘密鍵を /home/<ユーザ名>/.oci/apikey.priv.pem として保存する
先程作成した /home/<ユーザ名>/.oci/config ファイルを編集して、秘密鍵のパスを指定する
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaac4l3ej2qwae2bw74ajafmcos2ufkzx3xwpteilaxbnadbswfxpqq
fingerprint=5b:6c:b2:52:52:29:93:be:b6:dc:f8:18:fe:e0:59:33
tenancy=ocid1.tenancy.oc1..aaaaaaaakpgyb3s46vmuzkzyh5pk5yyax2hiyzl7b3itdv6gz7gdgoms5z4a
region=ap-tokyo-1
key_file=/home/oreore/.oci/apikey.priv.pem
各ファイルのパーミッションを修正する
chmod 600 /home/oreore/.oci/*
oci iam user get --user-id <ユーザのOCID> と打ってみて、ユーザ情報が取れればOK
oci iam user get --user-id <ユーザのOCID>
{
"data": {
"capabilities": {
(省略)
},
"compartment-id": "compartmentのOCID",
(そのほかいろいろ)
},
"etag": "ETagの内容"
}
6. アプリケーションをOCI上のコンテナレジストリ、OCI Functionsにデプロイ
【書式】
-
<context名>: fn contextの名前。任意の値 -
<compartment-id>: FunctionsがあるコンパートメントのOCID。ルートコンパートメントの場合はテナンシのOCIDになる -
<region-id>: リージョン識別子。東京リージョンの場合はap-tokyo-1。一覧はこちら(https://docs.oracle.com/ja-jp/iaas/Content/General/Concepts/regions.htm) -
<region-key>: リージョンキー。東京リージョンの場合はnrt。一覧はこちら(https://docs.oracle.com/ja-jp/iaas/Content/General/Concepts/regions.htm) -
<namespace>: OCIRのnamespace名。手順5.4.でメモしたもの -
<repository-name>: OCIRのリポジトリ名。なんでもいいがローカルのコンテナ名と合わせたほうがわかりやすいと思う -
<user-id>: ユーザのログインID。メールアドレス -
<application-name>: Functions作成時に指定したアプリケーション名
cd ~/pythonfn
fn create context <context名> --provider oracle
fn use context <context名>
fn update context oracle.compartment-id <compartment-id>
fn update context api-url https://functions.<region-id>.oraclecloud.com
fn update context registry <region-key>.ocir.io/<namespace>/
docker login -u '<namespace>/<user-id>' <region-key>.ocir.io
# ここでOCI上のFunctionsに作成したアプリケーション名を確認する
$ fn list app
# アプリケーション名を指定してデプロイ
$ fn deploy --app <application-name>
例えばこんな感じにやる
$ cd ~/pythonfn/
$ fn create context oci --provider oracle
$ fn use context oci
$ fn update context oracle.compartment-id ocid1.tenancy.oc1..aaaaaaaakpgyb3s46vmuzkzyh5pk5yyax2hiyzl7b3itdv6gz7gdgoms5z4a
$ fn update context api-url https://functions.ap-tokyo-1.oraclecloud.com
$ fn update context registry nrt.ocir.io/nrigsmd1mh6f/
$ docker login -u 'nrigsmd1mh6f/oreore@example.com' nrt.ocir.io
Password: (Auth tokenを入れる)
Login Succeeded
$ fn list app
NAME ID
fn ocid1.fnapp.oc1.ap-tokyo-1.aaaaaaaad2vfqcqc3zpvrcnvqx4cezpunhdz2u3epn2ou4dtltx2lsi5e4rq
$ fn deploy --app fn
Deploying pythonfn to app: fn
Bumped to version 0.0.3
Using Container engine docker
Building image nrt.ocir.io/nrigsmd1mh6f/pythonfn:0.0.3 TargetedPlatform: amd64HostPlatform: amd64
....
Using Container engine docker to push
Pushing nrt.ocir.io/nrigsmd1mh6f/pythonfn:0.0.3 to docker registry...The push refers to repository [nrt.ocir.io/nrigsmd1mh6f/pythonfn]
7ed176f9b9e6: Pushed
3d50e2e6cae1: Pushed
3209481e9925: Pushed
ac030d1fc3bc: Pushed
03d5f9d77ddf: Pushed
401c9daff908: Pushed
7e9f3f6c7a0a: Pushed
0.0.3: digest: sha256:2be9d60ff3daa2741d72732fc33ec53149ca200c3fbb5c34ab8da1ace703aa92 size: 1779
Updating function pythonfn using image nrt.ocir.io/nrigsmd1mh6f/pythonfn:0.0.3...
Successfully created function: pythonfn with nrt.ocir.io/nrigsmd1mh6f/pythonfn:0.0.3
動作確認は以下のように行う
# fnコマンドを使う場合
$ fn invoke fn pythonfn
{"message": "Hello World"}
$ echo -n '{"name":"Bob"}' | fn invoke fn pythonfn --content-type application/json
{"message": "Hello Bob"}
# curl用のエンドポイントを取得する
$ fn inspect function fn pythonfn
"annotations": {
"fnproject.io/fn/invokeEndpoint": "https://tx2lsi5e4rq.ap-tokyo-1.functions.oci.oraclecloud.com/20181201/functions/ocid1.fnfunc.oc1.ap-tokyo-1.aaaaaaaaop736j5edwurloncg2eortyvgvt3ov6sn6m4wmkjxj3jcevpvmda/actions/invoke",
(略)
},
(そのほかいろいろ)
}
# curlコマンドで動作確認(アクセスできないのが正しい)
$ curl -XPOST -H "Content-Type: application/json" "https://tx2lsi5e4rq.ap-tokyo-1.functions.oci.oraclecloud.com/20181201/functions/ocid1.fnfunc.oc1.ap-tokyo-1.aaaaaaaaop736j5edwurloncg2eortyvgvt3ov6sn6m4wmkjxj3jcevpvmda/actions/invoke"
{"code":"NotAuthenticated","message":"Not authenticated"}
$ curl -XPOST -H "Content-Type: application/json" -d '{"name":"Bob"}' "https://tx2lsi5e4rq.ap-tokyo-1.functions.oci.oraclecloud.com/20181201/functions/ocid1.fnfunc.oc1.ap-tokyo-1.aaaaaaaaop736j5edwurloncg2eortyvgvt3ov6sn6m4wmkjxj3jcevpvmda/actions/invoke"
{"code":"NotAuthenticated","message":"Not authenticated"}
7. APIゲートウェイを作成する
7.1. APIゲートウェイを作成する
マネジメントコンソールを開く
[メニュー] - [Developer Services] - [API Management] を選択
作成には2,3分ほどかかるので待つ
左のメニューから "Deployment" をクリック
値をセットして、[Next]をクリック
API request policies, API logging policies は変更しなくていい



"No Authentication" を選択して、[Next]をクリック

内容をレビューして、[Create]をクリック
完了までに2,3分ほどかかるので待つ
エンドポイントのパスは
https://<endpoint-hostname>/<path-prefix>/<deployment-path> という形式になる
今回の場合はそれぞれ以下のようになる
-
<endpoint-hostname>:etwuensebazfriwi2yxygw6aka.apigateway.ap-tokyo-1.oci.customer-oci.com -
<path-prefix>:v1 -
<deployment-path>:fn
7.2. アクセスポリシーの作成
APIゲートウェイからFunctionsを呼び出すためのポリシーを作成する
[メニュー] - [Identity & Security] - [Policies] を選択
【書式】
-
<compartment-name>: APIゲートウェイがあるコンパートメントの名前。Rootコンパートメントの場合はtenancyとなる -
<compartment-id>: コンパートメントのOCID
ALLOW any-user to use functions in <compartment-name> where ALL {request.principal.type = 'ApiGateway', request.resource.compartment.id = '<compartment-id>'}
例えばこんな感じになる
ALLOW any-user to use functions-family in tenancy where ALL {request.principal.type= 'ApiGateway', request.resource.compartment.id = 'ocid1.tenancy.oc1..aaaaaaaakpgyb3s46vmuzkzyh5pk5yyax2hiyzl7b3itdv6gz7gdgoms5z4a'}
8. 動作確認
動作確認は以下のように行う
# curlコマンドで動作確認
$ curl -XPOST -H "Content-Type: application/json" "https://etwuensebazfriwi2yxygw6aka.apigateway.ap-tokyo-1.oci.customer-oci.com/v1/fn"
{"message": "Hello World"}
$ curl -XPOST -H "Content-Type: application/json" -d '{"name":"Bob"}' "https://etwuensebazfriwi2yxygw6aka.apigateway.ap-tokyo-1.oci.customer-oci.com/v1/fn"
{"message": "Hello Bob"}
9. そうじ
消すときは以下の順序で行う
APIGW-deployment -> APIGW -> Function-app(下のfunctionまで一気に消してくれる) -> Container Repository(下のイメージまで一気に消してくれる) -> Subnet -> Security List -> Auth Token, API Key
10. さいごに
おつかれさまでした。なんかもう、ひたすらめんどくさいッスね・・・もうちょっとなんとかならないものかしら・・・























