空谷に吼える

ブロックチェーン/DLTまわりのなにかしらを書いていく所存

Oracle Cloud Infrastructure上のComputeインスタンスから自身の所在するコンパートメント名をOCI CLIとoci-metadataを使って取得してみる

なんの話

Oracle Cloud Infrastructure(→OCI)上のComputeインスタンスの中から、自身が所在するコンパートメント名を取得して使いたいという用件があったので調べてみました。これが一番良い(かんたんな)方法かどうかはわかりませんが、以下で可能でしたのでやり方をメモ程度にまとめておきます。

  • OCIユーティリティに含まれるoci-metadataを使うと、所在するコンパートメントのOCIDが取得できる
  • OCI CLIを使ってコンパートメントのOCIDからコンパートメント名を引いてこれる

使いどころ?

OCI上のComputeインスタンスのコンパートメント名はもちろんOCIコンソール上やREST APIなど、VMインスタンスの外からは把握可能です。

しかし例えば、「Computeインスタンスから"{自身の所在するコンパートメント名}_{自身のホスト名}"の名称になっているObject Storageバケットにログファイルやその他のファイルを転送したい」といった用件を考えてみましょう。少数であればインスタンス外で確認したコンパートメント名を設定ファイルなどに書いておいてあげても良いですが、もし複数のインスタンスを作成し、それぞれでこれをやるとなるとけっこう面倒だしミスが起きがちです。

この場合、たぶん正当派のやり方ではTerraformでインスタンスの作成とコンパートメント名のインスタンス環境変数への設定を自動化したうえで同時に行う、という方法になるかなと思いますが、Terraformを使うほどでもないような規模だったり、Terraformを覚えるのもそれはそれで面倒……というケースにここで説明する方法がもしかしたら使えるかもしれません。

やり方

以下コマンド例などはすべてLinux前提です。

oci-metadataでコンパートメントのOCIDを取得する

OCI上でOracle Linux 7以降のプラットフォーム・イメージを用いて作成したComputeインスタンスには、OCIユーティリティといういくつかの便利なコマンドラインツールのセットが標準でインストールされています。含まれるツールや手動でのインストール方法などはこちらを参照ください。なお現在、Oracle Linux以外のディストリビューションでは利用できないようなのでご注意ください。

で、ここではこのOCIユーティリティに含まれるoci-metadataを使います。oci-metadataのドキュメントはこちら*1

実行すると以下の例(公式ドキュメントから引用)のような形式、内容でインスタンスメタデータが取得できます。

$ oci-metadata
Instance details:
  Display Name: my-example-instance
  Region: phx - us-phoenix-1 (Phoenix, AZ, USA)
  Canonical Region Name: us-phoenix-1
  Availability Domain: cumS:PHX-AD-1
  Fault domain: FAULT-DOMAIN-3
  OCID: ocid1.instance.oc1.phx.exampleuniqueID
  Compartment OCID: ocid.compartment.oc1..exampleuniqueID
  Instance shape: VM.Standard2.1
  Image ID: ocid1.image.oc1.phx.exampleuniqueID
  Created at: 1569529065596
  state: Running
  agentConfig:
    managementDisabled: False
    monitoringDisabled: False
  Instance Metadata:
    ssh_authorized_keys: example-key
Networking details:
  VNIC OCID: ocid1.vnic.oc1.phx.exampleuniqueID
  VLAN Tag: 2392
  Private IP address: 10.0.0.16
  MAC address: 02:00:17:03:D8:FE
  Subnet CIDR block: 10.0.0.0/24
  Virtual router IP address: 10.0.0.1

コンパートメント名が取得できれば話は早かったんですが、残念ながらコンパートメントのOCIDしか取得できないようです。仕方ないのでコンパートメント名は後でOCIDからどうにかして引っ張ってくることにして、いったんコンパートメントOCIDを取得しておきましょう。-jオプションでJSON形式で出力させられるので、jqと組み合わせて以下のようにコンパートメントOCIDの値(上記の例ではocid1.instance.oc1.phx.exampleuniqueIDの部分)だけ抜き出します(jqの-rオプションは値を囲うダブルクォートを抜くためのもの)。

oci-metadata -j | jq  .instance.compartmentId -r

oci-metadataの出番はここまでです。

OCI CLIでコンパートメントOCIDからコンパートメント名を引いてくる

コンパートメントのOCIDは判明したので、対応するコンパートメント名をどうにかして取ってきましょう。ここではOCI CLIを使います。OCI CLIはOCIの各種操作、機能をコマンドラインから利用するためのツールです。リファレンスはこちら

OCI CLIを使うにはインストールしたうえで認証関連のセットアップ、設定が必要です(なお、OCIのLinux Developer Imageなどのイメージを作成してインスタンスを作成した場合、既定でインストールまではされています)。以下の記事に説明されています。

www.ashisuto.co.jp

コンパートメントOCIDからコンパートメント名を取得するには、oci iam compartment get -c {コンパートメントOCID}のコマンドを実行します。コマンドリファレンスはこちら

このコマンドの戻りはJSON形式なので、ここでもやはりjqを使い、以下のコマンドでコンパートメント名の値を取り出します。

oci iam compartment get -c {コンパートメントOCID} | jq .data.name -r

というわけでインスタンスの中からコンパートメント名が取得できました。

↑をワンライナーでやる

こんな感じ

oci iam compartment get -c $(oci-metadata -j | jq  .instance.compartmentId -r) | jq .data.name -r

*1:なお、メタデータの更新が反映されるタイミングについてドキュメントに記載がありません。Display Nameを変更して直後にoci-metadataを実行して試してみたところ、変更前の値が出力されました。その後すぐにインスタンスを再起動し、再度oci-metadataを実行したところ変更後の値が出力されました。メタデータインスタンス作成後あまり頻繁に変えるものでもないと思いますが、タイミングによってズレが生じ得る可能性についてご留意ください。