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 を外し、ログをファイルに書き出します。