search
LoginSignup
2

More than 3 years have passed since last update.

posted at

updated at

[Oracle Cloud] リソースプリンシパル を Oracle Functions で使ってみた

はじめに

Oracle Cloud Infrastructure(以下OCI)は、サーバレスアーキテクチャで重要な役割を担う、FaaS サービスの Oracle Functions が提供されています。Oracle Functions を動かすときには、OCI 側のリソースの操作をすることが多いと思います。

(例)
- Object Storage へファイルを格納
- インスタンスの一覧取得

上記で挙げた例を実現するためには、OCI の SDK を使用してプログラミングをするのがベーシックなやり方になります。OCI の SDK を実行する時に、リソースプリンシパルを使用することで、Oracle Functons の実行環境(コンテナ)の中に、秘密鍵やパスワードといったクレデンシャル情報を格納する必要がなくなるため、セキュリティが高くなるメリットがあります。

今回の記事では、Go言語の OCI SDK を使用して、リソースプリンシパルを活用し、インスタンスの名前一覧を出力する Function を作成する手順を紹介します。

概要図

1566987269721.png

Functions の作成

まず、Functions を動かす準備が出来ていない場合は、以下の Doucment や Quick Start Guide を参考にして、事前準備をします。
Preparing for Oracle Functions
https://docs.cloud.oracle.com/iaas/Content/Functions/Concepts/functionsprerequisites.htm

Quick Start Guide
https://www.oracle.com/webfolder/technetwork/tutorials/infographics/oci_faas_gettingstarted_quickview/functions_quickview_top/functions_quickview/index.html

Function を動かす準備が出来たら、リソースプリンシパルを使用して、インスタンス名を取得するコードをプログラミングします。以下にサンプルコードを記載します。GitHub にもアップロードしています。

GitHub : https://github.com/Sugi275/oci-gosdk-resource-principal-samplecode/blob/master/func.go

Sample Code

package main

import (
    "github.com/oracle/oci-go-sdk/common"
    "context"
    _ "encoding/json"
    "fmt"
    "os"
    "io"

    fdk "github.com/fnproject/fdk-go"
    "github.com/oracle/oci-go-sdk/core"
    "github.com/oracle/oci-go-sdk/common/auth"
)

func main() {
    fdk.Handle(fdk.HandlerFunc(myHandler))
    // reader := os.Stdin
    // writer := os.Stdout
    // myHandler(context.TODO(), reader, writer)
}

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

    provider, err := auth.ResourcePrincipalConfigurationProvider()

    if err != nil {
        fmt.Println(err)
        return
    }

    compartmentID := os.Getenv("COMPARTMENT_ID")

    request := core.ListInstancesRequest{
        CompartmentId: &compartmentID,
        LifecycleState: core.InstanceLifecycleStateRunning,
    }

    fmt.Println(request)

    client, err := core.NewComputeClientWithConfigurationProvider(provider)

    if err != nil {
        fmt.Println(err)
        return
    }

    // Override the region, this is an optional step.
    // the InstancePrincipalsConfigurationProvider defaults to the region
    // in which the compute instance is currently running
    client.SetRegion(string(common.RegionAPTokyo1))

    listInstancesResponse, err := client.ListInstances(context.Background(), request)

    if err != nil {
        fmt.Println(err)
        return
    }

    for _, item := range listInstancesResponse.Items {
        fmt.Printf("list of Compute Instance: %s \n", *item.DisplayName)
    }
}

ポイントは、25行目の以下の箇所です。go-oci-sdk の common.auth から、ResourcePrincipalConfigurationProvider() 関数を使って、リソースプリンシパルを使用した provider を生成します。これにより、後の手順で設定する権限設定が、リソースプリンシパルを経由して付与されます。

provider, err := auth.ResourcePrincipalConfigurationProvider()

上記のサンプルコードを作成後、Oracle Functios へ Function を Deploy します。Sample Code を作成したディレクトリ上にいることを確認します

> ls -la
total 28
drwxrwxr-x  3 ubuntu ubuntu 4096 Aug 28 10:20 ./
drwxrwxr-x 10 ubuntu ubuntu 4096 Aug 27 12:20 ../
-rw-rw-r--  1 ubuntu ubuntu 1370 Aug 28 10:19 func.go
-rw-r--r--  1 ubuntu ubuntu  103 Aug 28 10:19 func.yaml
drwxrwxr-x  8 ubuntu ubuntu 4096 Aug 28 10:21 .git/
-rw-r--r--  1 ubuntu ubuntu   11 Aug 28 09:35 go.mod
-rw-rw-r--  1 ubuntu ubuntu   97 Aug 24 18:03 README.md

Function の Deploy を行います

fn --verbose deploy --app susugiya

サンプルコードは、 Compartment の OCID を環境変数として渡す設定としているため、以下のコマンドで環境変数を設定します

fn config func susugiya resource_principal_sample COMPARTMENT_ID "ocid1.compartment.oc1..secret"

Function の Deploy を実施すると、 OCI のコンソール画面上に表示されます。

OCI コンソールのメニューから、Developper Services > Functions を選択します。
私の環境で、事前に作成していた Application の名前を選択します。

1566988469902.png

resource_principal_sample の Function が表示されているため、OCID の Copy を選択します。
functions の OCID例 : ocid1.fnfunc.oc1.ap-tokyo-1.aaaaaaaaadbucwrz375qjw6jghtngmj2h5k6vu4hhke5s7aqe2jsg522nptq

1566988527448.png

Dynamic Group の作成

OCI のメニューから、Identity > Dynamic Groups へ移動し、 Create Dynamic Group を押します
以下のパラメータを入力します

  • NAME : susugiya_resource_principal
  • DESCRIPTIN : susugiya_resource_principal

Rule に以下の文字列を入力します。resource.id の部分は、作成した Function の OCID を指定します。

ALL {resource.type = 'fnfunc', resource.id = 'ocid1.fnfunc.oc1.ap-tokyo-1.aaaaaaaaadbucwrz375qjw6jghtngmj2h5k6vu4hhke5s7aqe2jsg522nptq'}

1566985541129.png

Policyの設定

Indentity > Policies へ移動し、 Create Policyを押します

  • NAME : susugiya_resource_principal_policy
  • DESCRIPTION : susugiya_resource_principal_policy
  • STATEMENTを以下の文字列で指定します。 Dynamic Group で作成した名前を指定して、instance-family(Computeサービス) を manage(全操作可能) な権限を付与しています
Allow dynamic-group susugiya_resource_principal to manage instance-family in compartment susugiya

実行

ここまで設定することで、特定の OCID を持つ Funciton に、Dynamic Group と Policy を使用して、instance-family (Computeサービス) を管理する権限を付与しました。

invokeコマンドで、function を実行します

> fn invoke susugiya resource_principal_sample

Oracle Functions の Logging 設定で、syslog を使用して、Papertrail へ出力するように設定をしています。
Papertrail への出力例

1566986216173.png

list of Compute Instance の後に、em01 と stepbox と表示されています。

これは、指定した Compartment ID で RUNNING 状態で稼働しているコンピュートインスタンスの一覧を表示しています

1566988853481.png

URL

Accessing Other Oracle Cloud Infrastructure Resources from Running Functions
https://docs.cloud.oracle.com/iaas/Content/Functions/Tasks/functionsaccessingociresources.htm

Sample Code
https://github.com/oracle/oci-go-sdk/tree/master/example/example_resource_principal_function

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2