はじめに
この記事は、Oracle Cloud Infrastructure Advent Calendar 2025 の Day 16 の記事です。
OCI でもこんな事が出来るんだよって事をもっと知ってほしくて書いてみました。
頑張っていきましょう。よろしくお願いします。
目的
こちらの記事は、OCI (Oracle Cloud Infrastructure) に関する Howto 系の記事です。
この記事を読むことで、下記の操作が出来るようになることを目的としています。
- OCI Functions のリソースをデプロイすることが出来る
- OCI API Gateway をデプロイして、クライアントから API 呼び出しが出来る
- API Gateway の背後には、予め作成しておいた Functions を配置します
- 最終的には Entra IDを使って、API を呼び出すために認証が必要な状態にする
- 認証方法は、Entra ID から発行されたトークンを API Gateway 側で検証する「リモート JWKS」を用いた方法です
手順
OCI Functions の作成
アプリケーションの作成
OCI コンソールからアプリケーションを作成します。
今回の場合、東京リージョンにアプリケーションを作成します。
名前は適当に、VCN やシェイプに関しても適宜選択します。
API Gateway 配下にデプロイする予定なので、アプリケーションは Private サブネットに展開します。
ファンクションの作成
下記の公開情報を参考に、ファンクションを作成します。
ファンクションですが、適当に作成します。
作成方法が分からない方は、アプリケーションの詳細画面にある「スタート・ガイド」を参考にすると良いです。
例えば「クラウド・シェル設定」のガイドの表示をクリックすると、ファンクションの作成からデプロイまでのコマンドが記載されています。

私はローカル環境で開発して OCI にデプロイするスタイルが好きなので、せっかくなので WSL2 の Ubuntu 環境からファンクションの作成とデプロイを実施しようと思います。
OCI コンソールからコンテナ レジストリを作成
ファンクションですが、関数として動作させる処理をコンテナ イメージ化する必要があります。
わざわざコンテナ レジストリを作成しなくても良いですが、(検証環境の制限上) 自分が管理しているコンパートメントにコンテナ レジストリを作成します。
コンテナ レジストリ自体の作成はとても簡単です。
下記公開情報をもとに作成しましょう。
作成したコンテナ レジストリへイメージを PUSH するには、認証トークンの作成が必要です。
こちらも上記公開情報を元に作成し、生成されたトークンをコピーして控えておきましょう。
WSL2 の Ubuntu 環境にて、ファンクション作成のための準備を行う
もし同じように WSL2 環境にてファンクションを作成されたい場合は、事前に下記の公開情報を元に WSL2 のセットアップをお願いします。
ローカル環境でファンクションを作成するには、事前に下記の準備が必要です。
- docker のインストール
- OCI プロファイルの設定 (OCI CLI のインストールでも OK)
- Fn CLI のインストール
docker のインストール方法については省略します。
OCI プロファイルの設定については、下記公開情報の "2.API署名キーおよびOCIプロファイルの設定" をご参考ください。
"~/.oci/config" に書き込む内容は、あとからユーザー情報の "APIキー" から確認可能です。
対象のフィンガープリントから "構成ファイルの表示" をクリックして、確認してみてください。

公開情報では、OCI 側で作成した秘密鍵をダウンロードするように明記されておりますが、自分で作成した秘密鍵を使うことも可能です。
その場合は、APIキー作成時に公開鍵の内容を貼り付ける必要があります。
ここで注意が必要な事として、パス フレーズがある鍵ペアを作成すると Fn CLI が動作しない可能性があります。
Fn CLI を使ったデプロイ時に、"Fn: can not create client, bad configuration: did not find a proper configuration for private key" のエラーが発生する。
そのため自分で秘密鍵を作成する場合は、下記コマンドのようにパス フレーズ無しで作成してください。
openssl genrsa -out oci_api_key_nopass.pem 2048
openssl rsa -pubout -in oci_api_key_nopass.pem -out oci_api_key_nopass_public.pem
Fn CLI のインストール方法についても、OCI プロファイルの設定が記載してある公開情報に記載されております。
"3.Fn ProjectのCLIのインストール" の箇所をご参考にインストールします。
このように、各種パッケージのバージョンが確認できていれば OK です。
ファンクションを作成する
ファンクションの作成前に、Fn CLI のセットアップが必要です。
fn create context <コンテキスト名> --provider oracle
fn use context <コンテキスト名>
fn update context oracle.profile <~/.oci/config ファイルで指定したプロファイル名>
fn update context oracle.compartment-id <Functions のアプリケーションを管理しているコンパートメントの OCID>
fn update context api-url https://functions.<region-identifier>.oraclecloud.com
# 例
# fn create context my-func-context --provider oracle
# fn use context my-func-context
# fn update context oracle.profile MYPROFILE
# fn update context oracle.compartment-id ocid1.compartment.oc1..aaa****6ka
# fn update context api-url https://functions.ap-tokyo-1.oraclecloud.com
次にファンクションの雛形を作成します。
ここでは Python のファンクションを作成します。
fn init --runtime python python-func
cd python-func
次に、予め作っておいたコンテナ レジストリと紐づけてログインします。
fn update context registry "ocir.<region-identifier>.oci.oraclecloud.com/<tenancy-namespace>"
docker login ocir.<region-identifier>.oci.oraclecloud.com -u '<tenancy-namespace>/<user-name>'
# テナントが Oracle Identity Cloud Service とフェデレートされている場合は、ユーザー名部分が異なるので注意です。
# docker login ocir.<region-identifier>.oci.oraclecloud.com -u '<tenancy-namespace>/oracleidentitycloudservice/<user-name>'
# Password は、予め作成しておいた認証トークンを指定してください。
# 例
# fn update context registry "ocir.ap-osaka-1.oci.oraclecloud.com/*****"
# docker login ocir.ap-tokyo-1.oci.oraclecloud.com -u "*****/oracleidentitycloudservice/jun.kitayama@*******"
その後、fn -v deploy --app <アプリケーション名>を実行してファンクションをアプリケーションにデプロイします。
もし下記のようなエラーが発生する場合は、予め作成しておいたコンテナ レジストリに対してデプロイ予定のファンクションと同名 (今回の場合だとpython-func) のレジストリを作成してから改めて fn deploy コマンドを実行してみてください。
denied: User UserId(ocid1.user.oc1..***********) not authorized
デプロイに成功すると、Successfully created function: python-func with ocir.ap-tokyo-1.oci.oraclecloud.com/....のメッセージが表示されます。
OCIコンソールからアプリケーションを確認すると、下図のとおりファンクションがデプロイされていることが確認出来ます。
下記のコマンドを実行して、デプロイしたファンクションが実際に動作することを確認します。
fn invoke <アプリケーション名> <ファンクション名>
# 例
# fn invoke jk-function-app-01 python-func
もし「Error invoking function. status: 502 message: Failed to pull function image」のようなエラーが発生する場合は、アプリケーションが Private サブネットに展開されておりコンテナ レジストリにアクセス出来ていないかもしれません。
その場合は、アプリケーションの作成で説明したとおり、サービス ゲートウェイの設定を見直してください。
問題なく{"message": "Hello World"}が返ってこれば、ファンクションのデプロイは完了です。
OCI API Gateway の作成
クライアントが直接アクセスする OCI API Gateway を作成します。
API Gateway がファンクションを呼び出せるようにポリシーを作成する
OCI Functions は匿名実行が出来ません。
実行しようとすると、IAM 検証で 401 を返されます。
そのため、API Gateway からファンクションを呼び出せるようにポリシーの作成が必要です。
下記の公開情報を参考に、動的グループの作成 & 作成した動的グループへのポリシー割り当てを行います。
「FunctionsへのAPIゲートウェイ・アクセスのポリシーの設定」の箇所を参考にしましょう。
API Gateway リソースの作成
OCI コンソールから、API Gateway を作成します。
API Gateway は、「開発者サービス - API 管理」のカテゴリにあります。
「ゲートウェイの作成」をクリックして、API Gateway リソースを作成しましょう。

下図のように、パブリックな API Gateway を作成します。
デプロイ先のサブネットも、Public なサブネットを指定しましょう。
デプロイメントの作成
API Gateway リソース作成後に、デプロイメントを作成します。

予め作成しておいたファンクションへルーティングするための設定を行います。
下図のような設定の場合は、"GET /python-func" を呼び出すと予め作成しておいたファンクションの API が呼び出されます。
その後、作成をクリックしてしばらくするとデプロイメントが作成されます。
デプロイメント作成後、エンドポイントをコピーすることで API を呼び出すことが出来ます。

下記の URL にアクセスすることで、API Gateway を経由してファンクションの呼び出しが可能です。
<コピーしたエンドポイント>/<デプロイメント作成時に指定したパス>
問題がなければ、下図のとおり JSON のレスポンスが返却されます。
Entra ID を使った認証
せっかくなので、API Gateway の認証機能を用いてセキュアに API を呼び出せるようにしてみます。
今回は Entra ID を使って、リモート JWKS を使った検証を API Gateway 側で実施しようと思います。
Entra ID 側の構成は下記のようなイメージです。
Entra ID
├── API アプリ(リソースアプリ) ← 1つだけ
│ Application ID URI = api://my-oci-api
│ Scope = api://my-oci-api/access_as_user
│
├── クライアントアプリA(サービスプリンシパルA)
├── クライアントアプリB(サービスプリンシパルB)
└── クライアントアプリC(サービスプリンシパルC)
↓(それぞれが以下のスコープでトークン取得)
scope=api://my-oci-api/access_as_user
↓
OCI API Gateway(JWT検証)
Entra ID 側でアプリケーションを作成する
下記から、Microsoft Entra 管理センターにアクセスします。
アプリの登録から、「新規登録」をクリック。
適当な名前を指定して、「登録」をクリックします。
API の公開から「Scope の追加」をクリック。
「保存してから続ける」をクリックします。

下図のように、スコープ名や管理者の表示名などを指定します。
アプリケーション ID の URI は後で使用するのでコピーしておきましょう。
「スコープの追加」をクリックします。

アプリ ロールから「アプリ ロールの作成」をクリック。
下図のようにパラメーターを指定して、「適用」ボタンをクリックします。

次に、同じ方法でクライアント アプリケーションを新たに作成します。

作成したクライアント アプリケーションに対して、API のアクセス許可のページから「アクセス許可の追加」をクリック。
下図のように、先程作成した API を追加します。

「既定のディレクトリに管理者の同意を与えます」をクリックし、「はい」をクリックします。

API Gateway の API を呼び出すためにトークンを指定する必要があるので、トークン取得のためにクライアント アプリケーションに対してクライアント シークレットを追加します。
作成後は、必ずクライアント シークレットの値を控えておきましょう。

これで、Entra ID 側の設定は完了です。
API Gateway のデプロイメントを更新
OCI コンソールを開いて、先程作成した API Gateway のデプロイメントを編集します。


認証ステップにて、認証なしから単一認証を選択します。
下図のように認証タイプやトークンの場所などを指定します。
JWT トークン・ヘッダー名には "Authorization" を、認証スキームには "Bearer" を指定します。

検証タイプは、タイプを「リモートJWKS」を選択します。
JWKS URIには、下記を指定します。
https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys
追加のJWT検証の発行者とオーディエンスに指定する値は下記のとおりです。
https://sts.windows.net/<tenant-id>/
api://<oci-appの client_id>
そして次へ次へとクリックしていき、変更した内容を保存します。
トークンを取得して API を呼び出す
適当な HTTP 実行ツールを使ってトークンを取得します。
自分は Postman を使って取得しました。
トークンを取得するための URL やリクエスト情報は下記を参考ください。
取得した access_token の値は、コピーして控えておきます。
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
client_id: <client-app-A の client_id>
client_secret: <client-app-A の secret>
scope: api://<oci-appの client_id>/.default
grant_type: client_credentials
その後、API Gateway にデプロイした API を呼び出します。
呼び出す際には、リクエスト ヘッダーに Authorization: Bearer <access_token の値> を指定しましょう。
すると、下図のとおり期待どおりレスポンスが返ってくることを確認できます。
試しにトークンを意図的に指定しなかった場合は、下図のとおり 401 エラーが返却されました。
これも期待どおりですね。































