Oracle Functions (Fn) で環境変数を指定

# はじめに

Oracle Functions で環境変数を扱います。OSS の Fn Project のDocumentを参考にして進めます。
https://github.com/fnproject/docs/blob/master/fn/develop/configs.md

Fn Project では、3つの方法を使用して環境変数を設定できます。

1. fn cli で application レベルで指定
2. fn cli で function レベルで指定
3. func.yaml ファイルを編集して指定



それぞれの方法を確認します。



Oracle Functions のチュートリアルはこちらを参照してください
https://qiita.com/sugimount/items/018e08f575ecefb1546c



# fn cli で application へ指定

事前に `env-app` という名前で、applicationを作成しています。fn config コマンドを使用して、`env-app` へ環境変数をconfigします。
KEY LOG_LEVEL で、値を debug にしています
applicationへ指定しているため、application配下のすべての関数に適応される環境変数となります。
ユースケースとしては、OCIを操作するための secret を登録するのが便利に使えるのかなと思います。

```
fn config app env-app LOG_LEVEL debug
```



実行例

```
> fn config app env-app LOG_LEVEL debug
env-app updated LOG_LEVEL with debug
```



fn ls コマンドで、確認します。KEY LOG_LEVEL が確認できます。OCI上の Functions のコンソールには、設定したconfigは現段階では表示されていませんが、GAされたら表示されると思います。たぶん。

```
> fn ls config app env-app
KEY             VALUE
LOG_LEVEL       debug
```



なお、fn inspect コマンドでも config を確認することが出来ます

```
> fn inspect app env-app
{
        "annotations": {
                "oracle.com/oci/appCode": "mwnn4cxig4a",
                "oracle.com/oci/compartmentId": "ocid1.compartment.oc1..secret",
                "oracle.com/oci/subnetIds": [
                        "ocid1.subnet.oc1.phx.aaaaaaaacqcxgx4lsbvt36iy5j2ujngcnntznixqs5srfnsniedpkbcjneka",
                        "ocid1.subnet.oc1.phx.aaaaaaaabrizkrcvtafcpqsmhg2b5rxgrksgxat3af4teymx5mrgpf37vrxa",
                        "ocid1.subnet.oc1.phx.aaaaaaaa32rb6446d5wrix4a4foyxiqpylzdd5ba6mzckh4bpjnfnuwxcqra"
                ]
        },
        "config": {
                "LOG_LEVEL": "debug"
        },
        "created_at": "2019-02-17T08:23:39.575Z",
        "id": "ocid1.fnapp.oc1.phx.aaaaaaaaahwgecozhlfvukpflbshttkh3p4w5hrw2bv4ncnzvmwnn4cxig4a",
        "name": "env-app",
        "updated_at": "2019-02-17T08:24:30.344Z"
}
```



golang で環境変数を print out するものを作成します

```
cd /home/ubuntu/go-third-party/src/fn_work/
fn init --runtime go env-print
```



func.go を適当に編集して、環境変数をJSONで Response するコードを書きます。
GitHubにもアップロードしているので必要であればご活用ください
https://github.com/Sugi275/fn-print-env/blob/master/func.go

```go
package main

import (
        "context"
        "encoding/json"
        "fmt"
        "io"
        "os"

        fdk "github.com/fnproject/fdk-go"
)

func main() {
        fdk.Handle(fdk.HandlerFunc(printEnv))
}

func printEnv(ctx context.Context, in io.Reader, out io.Writer) {

        msg := struct {
                LogLevel string `json:"loglevel"`
        }{
                fmt.Sprintf(os.Getenv("LOG_LEVEL")),
        }

        json.NewEncoder(out).Encode(&msg)
}
```





deploy & run

```
fn --verbose deploy --app env-app
fn --verbose invoke env-app env-print
```



実行例
正常にLogLevelが表示されています

```
> fn --verbose invoke env-app env-print
{"loglevel":"debug"}
```





# fn cli で function へ指定

functionへ configを作成します。application で指定したものと違って、function 単体に有効な環境変数となります。

```
fn config func env-app env-print funcenv true
```



実行例

```
> fn config func env-app env-print funcenv true
env-app env-print updated funcenv with true
```





fu ls config func コマンドで環境変数を確認することが出来ます。

```
> fn ls config func env-app env-print
KEY     VALUE
funcenv true
```



fn inspect func も同様です

```
> fn inspect func env-app env-print
{
        "annotations": {
                "fnproject.io/fn/invokeEndpoint": "https://mwnn4cxig4a.us-phoenix-1.functions.oci.oraclecloud.com/invoke/ocid1.fnfunc.oc1.phx.aaaaaaaaadu6qtn6zyn754zbiqi3boavtunsdbkwfllggixg7hkwjihfo5ma",
                "oracle.com/oci/compartmentId": "ocid1.compartment.oc1..secret"
        },
        "app_id": "ocid1.fnapp.oc1.phx.aaaaaaaaahwgecozhlfvukpflbshttkh3p4w5hrw2bv4ncnzvmwnn4cxig4a",
        "config": {
                "funcenv": "true"
        },
        "created_at": "2019-02-17T19:12:38.866Z",
        "id": "ocid1.fnfunc.oc1.phx.aaaaaaaaadu6qtn6zyn754zbiqi3boavtunsdbkwfllggixg7hkwjihfo5ma",
        "idle_timeout": 30,
        "image": "phx.ocir.io/sugimount2/oracle-function/env-print:0.0.4",
        "memory": 128,
        "name": "env-print",
        "timeout": 30,
        "updated_at": "2019-02-17T20:56:33.222Z"
}
```





func.go を適当に編集して、環境変数 funcenv を追加します。

```go
package main

import (
        "context"
        "encoding/json"
        "fmt"
        "io"
        "os"

        fdk "github.com/fnproject/fdk-go"
)

func main() {
        fdk.Handle(fdk.HandlerFunc(printEnv))
}

func printEnv(ctx context.Context, in io.Reader, out io.Writer) {

        msg := struct {
                LogLevel string `json:"loglevel"`
                FuncEnv  string `json:"funcenv"`
        }{
                fmt.Sprintf(os.Getenv("LOG_LEVEL")),
                fmt.Sprintf(os.Getenv("funcenv")),
        }

        json.NewEncoder(out).Encode(&msg)
}
```



deploy & run

```
fn --verbose deploy --app env-app
fn --verbose invoke env-app env-print
```



実行例

```
> fn --verbose invoke env-app env-print
{"loglevel":"debug","funcenv":"true"}
```



# func.yaml ファイルで指定

fn deploy するときに使用する、 function file (func.yaml) へ指定することで環境変数を指定することが出来ます。
この設定範囲は function レベルです。fn config とは違い yaml ファイルとして管理出来るため、Function as a Code がやりやすいのではないでしょうか

まずは、編集前の func.yaml の中身を確認します

```
> cat func.yaml
schema_version: 20180708
name: env-print
version: 0.0.5
runtime: go
entrypoint: ./func
format: http-stream
```



上記に、config を追記します

```
> cat func.yaml
schema_version: 20180708
name: env-print
version: 0.0.5
runtime: go
entrypoint: ./func
format: http-stream
config:
    yamlenv1: "I am func.yaml env1"
    yamlenv2: "I am func.yaml env2"
```



func.go を適当に編集して、環境変数 funcenv を追加します。

```go
package main

import (
        "context"
        "encoding/json"
        "fmt"
        "io"
        "os"

        fdk "github.com/fnproject/fdk-go"
)

func main() {
        fdk.Handle(fdk.HandlerFunc(printEnv))
}

func printEnv(ctx context.Context, in io.Reader, out io.Writer) {

        msg := struct {
                LogLevel string `json:"loglevel"`
                FuncEnv  string `json:"funcenv"`
                YamlEnv1 string `json:"yamlenv1"`
                YamlEnv2 string `json:"yamlenv2"`
        }{
                fmt.Sprintf(os.Getenv("LOG_LEVEL")),
                fmt.Sprintf(os.Getenv("funcenv")),
                fmt.Sprintf(os.Getenv("yamlenv1")),
                fmt.Sprintf(os.Getenv("yamlenv2")),
        }

        json.NewEncoder(out).Encode(&msg)
}
```



deploy & run

```
fn --verbose deploy --app env-app
fn --verbose invoke env-app env-print
```



実行例 (見にくいため、jq で 見やすくしました)

```
> fn --verbose invoke env-app env-print | jq .
{
  "loglevel": "debug",
  "funcenv": "true",
  "yamlenv1": "I am func.yaml env1",
  "yamlenv2": "I am func.yaml env2"
}
```







# 参考URL


Fn Project
https://github.com/fnproject