OCIインスタンス作成失敗「A1.Flexの容量が不足しています」の対処方法

マイクラ
この記事は約27分で読めます。

記事を書くきっかけの出来事

OCIの無料枠のインスタンスを作成する際に、シェイプとしてAmpere(Armベースのプロセッサ)シリーズの「VM.Standard.A1.Flex」を選択したところ、次のエラーが発生してインスタンス作成に失敗。

どうやら、OCIが用意するリソースが枯渇したことを示すメッセージの模様。無料枠なので仕方ないと、ここであきらめたくもなかったので、対処方法を調べました。

対処の過程で非常に効率的で有用な方法が確立できたので、本記事で手順を解説します。

本記事で登場する主なキーワード:terraform、oci-utils、tmux、oci-notify


対処方法とは

一言でいうと、トライ&エラーです。

誰かがリソースを手放すまで、機械的に無限トライを行います。シンプルな方法ですが、この先無料枠のリソースが大幅に増えることは期待薄なので、今後もリソースを使う上で必要となる方法とも言えます。

ただ、機械的な無限トライとは言え、その間自宅のPCを使い続けることになるので、これを獲得容易なOCIのMicroインスタンスで実行します(OCIのMicroインスタンスを持ってFlexインスタンスを制す)。

且つ、Flexインスタンス構築連絡を電子メールで受けるようにします。

これらのことを無料で実現します。


この記事を読んでできること

・需要増で入手しずらいA1.Flexインスタンスの獲得手段の確立。
・入手困難なインスタンスを別の入手容易なインスタンスから獲得実行。
・インスタンス獲得時に電子メールを受信。


大まかな流れ

1.踏み台インスタンスの構築
2.terraformのインストールと設定
3.無限トライ用スクリプトの作成
4.tmuxのインストール
5.メール受信の設定

ここから具体的な手順になります。それでは、どうぞ。

A1.Flexインスタンス獲得の手順

事前確認

一連の手順の中で何度か入力が必要となる、1.ユーザーOCID、2.テナンシOCID、3.リージョン情報を確認します。各情報はOCI管理画面から確認します。

1.ユーザーOCID(自分のプロファイルから確認)

2.テナンシOCID(テナンシから確認)

3.リージョン(リージョンの管理から確認)

手順1.踏み台用インスタンス構築

a1.flexインスタンス獲得の踏み台として入手が容易なe2.microインスタンスを構築します。

インスタンスの構築については以下の記事が参考になりますが、一部異なる点を記載します。

・OSイメージは「Oracle Linux 8」を選択します。
 理由は、電子メール送信に「OCIユーティリティ」パッケージを使用しますが、パッケージが使えるのがOracle系OSであるためです。

・シェイプはデフォルトの「VM.Standard.E2.1.Micro」を選択します。

手順2.獲得対象インスタンス設定

terraformで使用するインスタンス構成ファイルを作成します。
インスタンス構成ファイルはOCI管理画面の「インスタンスの作成」から行います。

イメージとシェイプ・・・イメージは仮に「ubuntu」を選択、シェイプはA1.Flex(仮に「1 core OCPU/6GB memory」)を選択します。
ネットワーキング・・・仮に既存のネットワークを選択します。
SSHキーの追加・・・インスタンス獲得時に接続用に使用する為、PCに保存します。

インスタンス構成をコード化する為「スタックとして保存」ボタンを押下します。

そのまま「次」ボタン押下します。

そのまま「次」ボタン押下します。

そのまま「作成」ボタン押下します。

「ダウンロード」をクリックすると、以下の形式のインスタンス構成ファイル(main.tf)がダウンロードされます(zipファイルからmain.tfを解凍)

provider "oci" {}

resource "oci_core_instance" "generated_oci_core_instance" {
	agent_config {
		is_management_disabled = "false"
		is_monitoring_disabled = "false"
		plugins_config {
			desired_state = "DISABLED"
			name = "Vulnerability Scanning"
		}
		plugins_config {
			desired_state = "ENABLED"
			name = "Compute Instance Monitoring"
		}
		plugins_config {
			desired_state = "DISABLED"
			name = "Bastion"
		}
	}
	availability_config {
		recovery_action = "RESTORE_INSTANCE"
	}
	availability_domain = "kVKW:AP-OSAKA-1-AD-1"
	compartment_id = "ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	create_vnic_details {
		assign_private_dns_record = "true"
		assign_public_ip = "true"
		subnet_id = "ocid1.subnet.oc1.ap-osaka-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	}
	display_name = "instance-A1.Flex"
	instance_options {
		are_legacy_imds_endpoints_disabled = "false"
	}
	is_pv_encryption_in_transit_enabled = "true"
	shape = "VM.Standard.A1.Flex"
	shape_config {
		memory_in_gbs = "6"
		ocpus = "1"
	}
	source_details {
		source_id = "ocid1.image.oc1.ap-osaka-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		source_type = "image"
	}
}

ダウンロードされたファイルの1行目を編集します(2行目以降はそのまま)

provider "oci" {
	tenancy_ocid = "ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxx"
	user_ocid = "ocid1.user.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxx"
	fingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
	private_key_path = "/home/opc/terraform/api-key.pem"
	region = "ap-osaka-1"
	}

入力項目(tenancy_ocid、user_ocid、region)は冒頭の「事前確認」を参照下さい。
入力項目(private_key_path)は、手順4のterraform作業フォルダを指定します。
入力項目(fingerprint)は、以下の手順で作成したAPIキー情報になります。

APIキー作成はOCI管理画面の「自分のプロファイル」から行います。

左下の「APIキー」をクリックします。

「APIキーの追加」ボタンを押下します。

「APIキー・ペアの作成」選択を確認して「秘密キーのダウンロード」ボタンを押下します。(ダウンロードした秘密キーファイルは短いファイル名「api-key.pem」に変更しておきます【任意】)、「追加」ボタンを押下します。

main.tfファイルの入力項目(fingerprint)が作成できました。

(注意)以降の手順で行うコマンド実行は全てe2.microインスタンスで行います。

手順3.terraformのインストール

手順1で作成したe2.microインスタンスにterraformをインストールします。
(terraformツールを使うことで、手順1で行ったようなインスタンス構築をツールが実行してくれます。a1.flexインスタンス構築はこのツールで行います)

コマンド実行

sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

実行結果

[opc@work ~]$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
Adding repo from: https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

コマンド実行

sudo yum -y install terraform

実行結果

[opc@work ~]$ sudo yum -y install terraform
・・・
省略
・・・
Installed:
  terraform-1.3.9-1.x86_64

Complete!
[opc@work ~]$

手順4.terraformの実行

terraform作業フォルダを作成します(フォルダの場所と名前は任意ですが、ここでは「/home/opc/terraform」とします)

コマンド実行

mkdir /home/opc/terraform

編集済み「main.tf」と手順2のAPIキー作成でダウンロードした「秘密キーファイル・・・api-key.pem」をterraform作業フォルダにアップロードします。

アップロードはWinSCP等のファイル転送ソフトを使用して実行します。

terraformを実行しインスタンス構築を行います。1.init、2.plan、3.applyの順に実行します。

コマンド実行(terraformフォルダに移動)

cd /home/opc/terraform

コマンド実行

terraform init

実行結果

[opc@work terraform]$ terraform init
Initializing the backend...
・・・
省略
・・・
Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

コマンド実行

terraform plan

実行結果

[opc@work terraform]$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create
・・・
省略
・・・
Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you
run "terraform apply" now.
[opc@work terraform]$

コマンド実行

terraform apply

実行結果

[opc@work terraform]$ terraform apply
・・・
省略
・・・
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

oci_core_instance.generated_oci_core_instance: Creating...
oci_core_instance.generated_oci_core_instance: Still creating... [10s elapsed]
oci_core_instance.generated_oci_core_instance: Still creating... [20s elapsed]
oci_core_instance.generated_oci_core_instance: Still creating... [30s elapsed]
oci_core_instance.generated_oci_core_instance: Creation complete after 36s [id=ocid1.instance.oc1.ap-osaka-1.xxxxxxxxxxxxxxxxxxxx]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
[opc@work terraform]$

上記実行時の以下項目については「yes」を入力します。
Enter a value:

実行結果で「Apply complete! Resources: 1 added, 0 changed, 0 destroyed.」と出力されていればインスタンス構築が成功しています。

ちなみにインスタンス構築済みで再度「terraform apply」を実行した場合は「Apply complete! Resources: added, 0 changed, 0 destroyed.」と出力されます。

又、リソース不足によるインスタンス構築失敗時は「Error: 500-InternalError, Out of host capacity.」と出力されます。

インスタンス構築失敗がリリース不足である場合は、スクリプト化することで実行を無限トライすることができます。

手順5.terraform実行の無限トライ化

スクリプトを作成します(ここでは仮に「script.sh」のファイル名とします)

コマンド実行(スクリプトファイル作成)

sudo vi script.sh

編集内容

count=0 # カウンタ初期値
while true
do
    count=`expr $count + 1` # カウンタ更新
    terraform apply -auto-approve
    if [ $? -eq 0 ]; then
        echo $count回目でインスタンス獲得に成功
        exit 0
    fi
    sleep 10 # 10秒後にトライ
done

コマンド実行(実行権限付与)

chmod +x script.sh

コマンド実行(スクリプト実行)

./script.sh

これで無限トライできるようになりましたが、e2.microインスタンスとの接続を切るとスクリプトが終了してしまいます。接続を切った後もスクリプトを実行し続けるにはtmuxをインストールする必要があります。

手順6.tmuxのインストール

e2.microインスタンスにtmuxをインストールします。

コマンド実行

sudo dnf install -y tmux

実行結果

[opc@work ~]$ sudo dnf install -y tmux
・・・
省略
・・・
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                    1/1
  Installing       : tmux-2.7-1.el8.x86_64                                                                              1/1
  Running scriptlet: tmux-2.7-1.el8.x86_64                                                                              1/1
  Verifying        : tmux-2.7-1.el8.x86_64                                                                              1/1

Installed:
  tmux-2.7-1.el8.x86_64

Complete!
[opc@work ~]$

tmuxがインストールできました。

コマンド実行(tmuxの起動)

tmux

実行結果

tmuxコマンド実行後、最下行がハイライト表示に変わりました。この状態でスクリプト実行すると、e2.microインスタンスとの接続を切ってもスクリプトが停止しません。

ただ、接続を切るとa1.flexインスタンスを構築できたかどうかわからないので、成功した時点で電子メールが届くようにします。

メール通知までは不要という場合は、以上で終了です。

手順7.電子メール受信の設定

1.OCI cliのインストール

コマンド実行

sudo yum install -y python36-oci-cli

実行結果

[opc@work ~]$ sudo yum install -y python36-oci-cli
・・・
省略
・・・
Upgraded:
  python36-oci-sdk-2.93.1-1.el8.x86_64
Installed:
  python3-arrow-1.1.1-1.el8.noarch                              python3-jmespath-0.10.0-1.el8.noarch
  python3-prompt-toolkit-3.0.29-1.0.2.el8.noarch                python3-terminaltables-3.1.0-1.0.1.el8.noarch
  python3-typing-extensions-3.7.4.2-1.el8.noarch                python3-wcwidth-0.2.5-3.el8.noarch
  python36-oci-cli-3.23.2-1.el8.noarch
Complete!

[opc@work ~]$

2.OCI cliの構成ファイル作成

コマンド実行

sudo oci setup config

実行結果

[opc@work ~]$ sudo oci setup config
    This command provides a walkthrough of creating a valid CLI config file.

    The following links explain where to find the information required by this
    script:

    User API Signing Key, OCID and Tenancy OCID:

        https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#Other

    Region:

        https://docs.cloud.oracle.com/Content/General/Concepts/regions.htm

    General config documentation:

        https://docs.cloud.oracle.com/Content/API/Concepts/sdkconfig.htm

Enter a location for your config [/root/.oci/config]:
Enter a user OCID: ocid1.user.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Enter a tenancy OCID: ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Enter a region by index or name(e.g.
1: af-johannesburg-1, 2: ap-chiyoda-1, 3: ap-chuncheon-1, 4: ap-dcc-canberra-1, 5: ap-hyderabad-1,
6: ap-ibaraki-1, 7: ap-melbourne-1, 8: ap-mumbai-1, 9: ap-osaka-1, 10: ap-seoul-1,
11: ap-singapore-1, 12: ap-sydney-1, 13: ap-tokyo-1, 14: ca-montreal-1, 15: ca-toronto-1,
16: eu-amsterdam-1, 17: eu-dcc-dublin-1, 18: eu-dcc-dublin-2, 19: eu-dcc-milan-1, 20: eu-dcc-milan-2,
21: eu-dcc-rating-1, 22: eu-dcc-rating-2, 23: eu-frankfurt-1, 24: eu-madrid-1, 25: eu-marseille-1,
26: eu-milan-1, 27: eu-paris-1, 28: eu-stockholm-1, 29: eu-zurich-1, 30: il-jerusalem-1,
31: me-abudhabi-1, 32: me-dcc-muscat-1, 33: me-dubai-1, 34: me-jeddah-1, 35: mx-queretaro-1,
36: sa-santiago-1, 37: sa-saopaulo-1, 38: sa-vinhedo-1, 39: uk-cardiff-1, 40: uk-gov-cardiff-1,
41: uk-gov-london-1, 42: uk-london-1, 43: us-ashburn-1, 44: us-chicago-1, 45: us-gov-ashburn-1,
46: us-gov-chicago-1, 47: us-gov-phoenix-1, 48: us-langley-1, 49: us-luke-1, 50: us-phoenix-1,
51: us-sanjose-1): 9
Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to an existing key.) [Y/n]: Y
Enter a directory for your keys to be created [/root/.oci]:
Enter a name for your key [oci_api_key]:
Public key written to: /root/.oci/oci_api_key_public.pem
Enter a passphrase for your private key (empty for no passphrase):
Private key written to: /root/.oci/oci_api_key.pem
Fingerprint: 62:a2:4a:59:72:31:7b:4a:42:88:ce:13:eb:1f:47:ba
Config written to /root/.oci/config

    If you haven't already uploaded your API Signing public key through the
    console, follow the instructions on the page linked below in the section
    'How to upload the public key':

        https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#How2

[opc@work ~]$

上記実行時の以下入力項目については、冒頭の「事前確認」を参考に入力します。
Enter a user OCID: 
Enter a tenancy OCID:
Enter a region by index or name
上記以外のEnter ・・・はそのままリターンキーを押下します。
Do you want to generate a new API Signing RSA key pair? は「Y」を入力します。

3.OCI通知機能用APIキー作成

コマンド実行(公開キーの表示)

sudo vi /root/.oci/oci_api_key_public.pem

実行結果(表示内容を以降の「APIキー追加」で入力)

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZW5f7X2vrThAw8BLZEX
NKMdW1AwXsuKf6Y6Uf8Gr0JGAuS4SwEnWx46FETVOxRJ9GosszTdnWFzBuP5BKj+
Mu5rMWuh2AJPgBfT0e+SwUIYRKHMFrC07SuzpgBfXDjFHADoyXJzWfBEs/DbywVy
I5SxHaHocX/XM1AhUPQPV+UoXnBacObE51uONww1GyXhzwEsaepJFJGicr4gppZ+
XcoeGLtyLwOCJ1lfE38Q3aMN+JwgY9yE4nTFksjf39Qp1iBtjI19+wDnicja9Qu7
lfgH/dFgBkI9g5PGdmX+pPW3jwuiSs133+w73byJLMnwHKCmLyp0c6jHDlfJJANg
mQIDAQAB
-----END PUBLIC KEY-----

APIキー作成はOCI管理画面から行います。

左下の「APIキー」をクリックします。

「APIキーの追加」ボタンを押下します。

「公開キーの貼付け」を選択して先程の公開キーを「公開キー欄」に張り付けます。

4.OCI通知機能の設定

OCI管理画面の「開発者サービス」>「通知」をクリックします。

「トピックの作成」ボタンを押下します。

任意の名前(例では「oci-notify」)を入力し「作成」ボタンを押下します。

右のトピックOCIDはコマンド実行時の引数として使用する為にメモしておきます(後から参照もできます)
左の「サブスクリプション」をクリックします。

「サブスクリプションの作成」ボタンを押下します。

サブスクリプション・トピックがトピックの作成で入力した名前であるのを確認します。電子メール送信先のメールアドレスを入力後に「作成」ボタンを押下します。

登録したメールアドレスにメールが届いているのを確認し、届いたメール本文の「Confirm subscription」をクリックします。

状態が「Pending」から「Active」に変わっていることを確認します。

コマンド実行(OCI CLI構成ファイルをoci-utilsの構成ファイルの場所にコピー)

sudo cp /root/.oci/config /etc/oci-utils/oci_cli.conf

コマンド実行(-cオプションの引数には先程メモした「トピックOCID」を指定)

sudo oci-notify -c ocid1.onstopic.oc1.ap-osaka-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

実行結果

[opc@work ~]$ sudo oci-notify -c ocid1.onstopic.oc1.ap-osaka-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Configured OCI notification service topic OCID.
Publishing message 'work: oci-utils: Notification enabled on instance work'
Published message 'work: oci-utils: Notification enabled on instance work'
[opc@work ~]$

登録したメールアドレスに通知サービスが有効になった旨のメールが届きます。

手順5で作成したスクリプトを修正します(8行目を追加)

count=0 # カウンタ初期値
while true
do
    count=`expr $count + 1` # カウンタ更新
    terraform apply -auto-approve
    if [ $? -eq 0 ]; then
        echo $count回目でインスタンス獲得に成功 > result.txt
        sudo oci-notify -t "oci notification" -f result.txt # 電子メール送信
        exit 0
    fi
    sleep 10 # 10秒後にトライ
done

手順8.tmux上でのスクリプト実行

修正したスクリプトを使ってtmux上で実行します。
実行開始後は右上の「x」ボタンを押下してe2.microインスタンスとの接続を切り、登録したメールアドレスにメールを届くのを待ちます。

以上です。