はじめに
Oracle Cloud が提供している FaaS である、Oracle Functions から OCI のSDKを実行する方法を書いていきます。
OCI には、現在のところ、4種類の言語でSDKが使用できるようです。
- Java
- Python
- Ruby
- Go
今回実装する内容は、Go言語のSDKを使って、Function から OCI の LoadBalancer 名前一覧を取得するものです。
GitHubにソースコードやDockerFileをアップロードしています。
#SDK のクレデンシャル管理
SDKを実行する方法
まずは、oci sdk を実行する方法を確認します。以下のGitHubに記載されています。
https://github.com/oracle/oci-go-sdk#configuring
2種類の実行方法があります。
-
oci 用の config ファイルを作成、RSA 秘密鍵を格納
~/.oci/config
-
Interfaceを実装
// ConfigurationProvider wraps information about the account owner type ConfigurationProvider interface { KeyProvider TenancyOCID() (string, error) UserOCID() (string, error) KeyFingerprint() (string, error) Region() (string, error) }
今回は、「2. Interfaceを実装」の方法を採用します。Oracle Functions は、コンテナイメージを使用して Function を実行するアーキテクチャとなっており、選択肢1では、コンテナイメージ内にRSA秘密鍵を格納する必要があることから、セキュリティ的に懸念があり、2を採用します。
2の選択肢では、Oracle Functions の環境変数に秘密鍵やUserOCID などの情報を指定することで、コンテナイメージ内にクレデンシャル情報を格納しない方法を取ります。
ConfigurationProvider の Interface を実装
ConfigurationProvider Interface を、環境変数を利用する内容で実装します。なお、oci-go-sdk の common パッケージ配下にも、環境変数を使用するライブラリはありますが、秘密鍵そのものを環境変数として受け取る形ではないため、独自に実装するものとします。
参考:oci-go-sdk で環境変数を使用するライブラリ
https://github.com/oracle/oci-go-sdk/blob/master/common/configuration.go#L116
詳細は省略しますが、以下のGitHubのソースコードが、独自に実装した内容となります。oci-go-sdk/common で指定されている ConfigurationProvider
Interface を実装している形になります。
https://github.com/Sugi275/fn-oci-lb-list/blob/master/src/ocilib/configration.go
実行方法
GitHubからクローンして実行
Oracle Functions が実行できる環境で、自分が作成した Repository を Clone します
git clone https://github.com/Sugi275/fn-oci-lb-list.git
Oracle Functions にDeployします。なお、名前やコンテナイメージのバージョンなどが気になる場合は、適宜 func.yaml を変更してください。
fn --verbose deploy --app <fn application name> --no-cache
環境変数設定
Function に環境変数を設定します。OCIDなどは適宜自分の環境のものを指定します。
bashの場合
# 秘密鍵をbase64でエンコードして、変数に格納
export OCI_PrivateRSAKeyEncyped=`base64 /home/ubuntu/.oci/oci_api_key.pem`
fn config func env-app oci-lb-list OCI_PrivateRSAKeyEncoded $OCI_PrivateRSAKeyEncoded
fn config func env-app oci-lb-list OCI_TenancyOCID "ocid1.tenancy.oc1..secret"
fn config func env-app oci-lb-list OCI_UserOCID "ocid1.user.oc1..secret"
fn config func env-app oci-lb-list OCI_KeyFingerprint "00:00:00:00:00:00:00:00:00:00:00:se:cr:et:da:yo"
fn config func env-app oci-lb-list OCI_Region "us-phoenix-1"
fn config func env-app oci-lb-list OCI_COMPARTMENT_ID "ocid1.tenancy.oc1..secret"
# 空白は設定しても反映されない。パスフレーズを指定する場合はコメントアウトを外して指定
# fn config func env-app oci-lb-list OCI_PrivateRSAKey_passphrase ""
fishの場合
自分がfishをよく使っているので、fishの場合も記載します。
# fishでの環境変数設定。改行を有効にする
set IFS
set -x OCI_PrivateRSAKeyEncoded (base64 /home/ubuntu/.oci/oci_api_key.pem)
set IFS \n" "\t
fn config func env-app oci-lb-list OCI_PrivateRSAKeyEncoded $OCI_PrivateRSAKeyEncoded
fn config func env-app oci-lb-list OCI_TenancyOCID "ocid1.tenancy.oc1..secret"
fn config func env-app oci-lb-list OCI_UserOCID "ocid1.user.oc1..secret"
fn config func env-app oci-lb-list OCI_KeyFingerprint "00:00:00:00:00:00:00:00:00:00:00:se:cr:et:da:yo"
fn config func env-app oci-lb-list OCI_Region "us-phoenix-1"
fn config func env-app oci-lb-list OCI_COMPARTMENT_ID "ocid1.tenancy.oc1..secret"
# 空白は設定しても反映されない。パスフレーズを指定する場合はコメントアウトを外して指定
# fn config func env-app oci-lb-list OCI_PrivateRSAKey_passphrase ""
function実行
functionの実行
fn --verbose invoke env-app oci-lb-list
実行例。LoadBalancerを2個作成しているため、2個の名前が表示されています。何も作っていない場合は、null と表示されます。
> fn --verbose invoke env-app oci-lb-list
{"message":["lb-20190220-0835","lb-20190221-0641"]}
メモ ハマりポイント alpineからHTTPSアクセス
alpine linux をベースのコンテナイメージとしているが、コンテナからOCIのHTTPSエンドポイントをたたくためには、ca-certificates
をinstallする必要があった。
FROM golang:1.11.5 as builder
WORKDIR /go/src/funcdir
COPY Gopkg.toml .
COPY src .
RUN go get -u github.com/golang/dep/cmd/dep && \
dep ensure
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o func .
FROM alpine:3.9
WORKDIR /function/
RUN apk update && \
apk add --no-cache ca-certificates <============= これ!
COPY --from=builder /go/src/funcdir/func .
ENTRYPOINT ["/function/func"]
参考URL
OCI の GO SDK
https://github.com/oracle/oci-go-sdk
SDK Config
https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
Example
https://github.com/oracle/oci-go-sdk/tree/master/example