[Oracle Cloud] インスタンスプリンシパル を OCI Go SDK で使ってみた

# はじめに

OCI の Compute Instance 上で、OCI SDK・OCI CLI を実行したいときに、秘密鍵やパスワードといったクレデンシャル情報をインスタンス上に格納する方法があります。
しかし、インスタンス上にクレデンシャル情報を格納するのはセキュリティに不安が残るため、これを解決するためにインスタンスプリンシパルという方法があります。

これを利用することで、クレデンシャル情報を無しに、OCI SDK などを利用することが可能です。

今回の記事では、以下の条件でインスタンスプリンシパルを利用する方法を記載します

- 言語 : Golang
- やること : Compute Instance の一覧表示



# 前提条件

- OCI上でインスタンスを作成していること
- そのインスタンスに、プログラム言語のGoを導入していること
- OCI Go SDK が導入されていること



# Dynamic Group の作成

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

- NAME : susugiya_instance_principal
- DESCRIPTIN : susugiya_instance_principal



Launch Rule Builderを押します

![1566627059794.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/dbba5139-6385-b70a-0472-3cf164b859f4.png)



前提条件で記載した Instance の OCID と Compartment の OCID を入力

![1566627517093.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/a5da7da2-fdc5-cab2-fa8d-b93d7918bad0.png)



Create Dynamic Groupを押します



# Policyの作成

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

- NAME : susugiya_instance_principal_policy
- DESCRIPTION : susugiya_instance_principal_policy
- STATEMENT 

```
Allow dynamic-group susugiya_instance_principal to manage instance-family in compartment susugiya
```





# インスタンスから確認

Sample Codeです。error は握り潰しているところがほとんどです。

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

```go
package main

import (
	"os"
	"context"
	"fmt"

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

func main() {
	provider, _ := auth.InstancePrincipalConfigurationProvider()

	compartmentID := os.Getenv("COMPARTMENT_ID")

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

	client, _ := core.NewComputeClientWithConfigurationProvider(provider)

	// 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.RegionLHR))

	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)
	}
}
```



ポイントは、14行目の以下のコードです。`InstancePrincipalConfigurationProvider` を呼び出して Provider を生成することで、インスタンスプリンシパルとして利用することが可能です。

```
provider, _ := auth.InstancePrincipalConfigurationProvider()
```



Sample Code は、コンパートメント ID を環境変数から取得するようにしているため、設定します

```
export COMPARTMENT_ID="ocid1.compartment.oc1..secret"
```



実行例

```
$ go run main.go 
list of Compute Instance: ap01 
list of Compute Instance: client 
list of Compute Instance: em01 
list of Compute Instance: insprin 
list of Compute Instance: web01 
```



# テスト：Dynamic Group を削除する

Dynamic Group を削除してみて、Sample Code の実行がエラーになるか確認します。
自分の環境では、削除してから数分後にエラーになりました。

```
$ go run main.go 
Service error:NotAuthorizedOrNotFound. Authorization failed or requested resource not found.. http status code: 404. Opc request id: 30981a00d560f8c5274551d6e302f638/B09CE4865FB8829079DE07ECCFEBEFCF/61D1977A4E4AA362DE6004BC810CEE27
```



# 参考URL

Calling Services from an Instance
https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm

Instance Principal を利用するときの sample
https://github.com/oracle/oci-go-sdk/blob/master/example/example_instance_principals_test.go

Oracle Cloud Infrastructure(OCI) のCLIを鍵認証無しで実行可能にしてみた
https://qiita.com/untitle_23/items/ddc93a74626ed431af14