LoginSignup
3

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-08-28

はじめに

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
  3. You can use dark theme
What you can do with signing up
3