コンテンツにスキップ

Phase 5b:リソース・マネージャ(Resource Manager)

目標

OCI のマネージドな Terraform 実行環境を体験し、ローカル PC での実行と比較します。

リソース・マネージャとは

概念 意味
スタック(Stack) コード(zip / Git など)+ 変数の値
ジョブ(Job) スタックに対して plan / apply / destroy / import を 1 回実行すること

ローカル PC での実行との違い:

ローカル PC の Terraform リソース・マネージャ
state 自分で管理(Phase 3 ではバケット(Bucket)に保存) RM が保管、ロック機能付き
認証 API キー ジョブを実行するユーザーの ID(API キーの発行が不要)
実行記録 ローカル PC のターミナル ジョブのログが OCI に残る
その他 ドリフト(drift)検出、Resource Discovery、コンソール(GUI)のフォーム(schema.yaml)
費用 RM 自体は無料(作成されたリソースは通常どおり課金)

≒ AWS の CloudFormation(ただし構文は Terraform)、または HCP Terraform。

構成

05-resource-manager/
├── build-zip.ps1   stack/ + 04 の network モジュール → build/stack.zip
├── rm.py           OCI Python SDK で RM を操作
└── stack/          VCN + プライベート・サブネット(ゲートウェイは作らない)
  • スタックには backend ブロックがない(state は RM に任せる)。provider には認証を書かない(region だけ書く)
  • モジュール(module)は Git にコピーせず、パッケージング時に zip に入れる(ソースは 1 か所だけ)
  • タグは managed_by = "resource-manager" とし、ローカル PC の Terraform で管理しているもの(terraform)と区別

手順と観察

ステップ 結果 / 観察
サポート・バージョンの確認 RM がサポートする Terraform は最大 1.5.x(ローカル PC は 1.12+)→ コードの required_version を互換にする必要がある
plan ジョブ 4 to add。キュー待ち(ACCEPTED)約 2 分、実行 10 秒
apply ジョブ execution_plan_strategy = FROM_PLAN_JOB_ID:上の plan ジョブで保存された計画を実行(≒ terraform apply xxx.tfplan)
リソースを手動変更 API で VCN 名を tflab5-vcn-changed-by-hand に変更
ドリフト検出 スタックは DRIFTED、VCN は MODIFIED、残り 3 つは IN_SYNC。expected / actual の値を確認できる
ドリフトの修正 再度 plan → ~ display_name(in-place)→ apply → ドリフト検出はすべて IN_SYNC
destroy ジョブ 4 destroyed
スタックの削除 ジョブの記録と RM が保管している state も一緒に削除される

ドリフト検出は報告するだけで、修正はしない

修正方法は 2 つあります:再度 plan → apply で実際のリソースをコードどおりに戻すか、コードを現状に合わせて変更するかです。 ドリフト検出は作業リクエスト(Work Request)であり、ジョブではないため、ジョブ一覧には表示されません。

  • ジョブは毎回まっさらな環境で実行され、ログを見ると毎回 terraform init し直していることがわかります(provider のバージョンは lock file で固定)

ハマりどころ

ローカル PC に OCI CLI をインストールできない:Windows のパス長の上限

pip install oci-cli → FileNotFoundError。原因は Windows のパス長の上限 259 文字(LongPathsEnabled = 0)です。 oci-cli で最も長いファイルの相対パスは 229 文字 → インストール先は 30 文字以内でなければなりません。

  • まず最長パスを調べる:pip download <pkg> --no-deps のあと、Python の zipfile で namelist の中から最も長いものを確認します。エラーになったファイルだけを見ると判断を誤ります
  • 対策:Python SDK(oci パッケージ)に切り替える。CLI 自体が SDK のラッパーなので、できることは同じです
  • その他の選択肢:長いパスを有効にする(管理者権限が必要)/ C:\oci\ のような短いパスにインストールする

SDK のドリフト属性は dict であり、JSON 文字列ではない

expected_properties / actual_properties は SDK の中ですでに dict になっています(値自体は JSON エンコード済みの文字列なので引用符付き)。 これにさらに json.loads を使うと TypeError になります。

PowerShell 5.1 の zip が Linux で展開できない

Compress-Archive のパス区切り文字は \ です。tar.exe -a -c -f x.zip -C <dir> . で zip を作成します。

pip install --quiet が固まったように見える

エラーも表示されません。調査時は --quiet を外し、ログをファイルに書き出します。