mcpField
I
infrastructure-as-code

infrastructure-as-code

github.com/acedergrenクラウド・DevOps22100 回インストール33 週間前に更新
リポジトリ

infrastructure-as-code について

Claude向けのOCI Terraformスキルです。OCI固有のプロバイダーの注意点、状態管理、リソースのライフサイクル安全策を扱い、OCI Landing Zoneモジュールの利用場面も説明します。

主な機能

  1. 01OCIプロバイダー認証のガイダンス
  2. 02状態ドリフトと破損からの復旧
  3. 03リソースのライフサイクルと依存関係
  4. 04Landing Zoneモジュールの利用指針
  5. 05コストとタグ付けの実践

活用シーン

  1. 01OCIリソース向けTerraformの設定
  2. 02認証やインポートのエラー調査
  3. 03状態ドリフトや破棄失敗への対処
  4. 04ガバナンスを考慮したOCIテナンシーの計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/acedergren/oci-agent-skills --skill infrastructure-as-code

インストール後、Claude Code で/infrastructure-as-codeを入力して読み込まれたか確認します。

同梱ファイルmetadata.jsonreferences/oci-terraform-patterns.md

詳細

OCI Infrastructure as Code - エキスパート知識

🏗️ 重要:OCI Landing Zone Terraform モジュールを使用してください

一から作り直さないでください

❌ 間違ったアプローチ:

# Writing Terraform from scratch for every resource
resource "oci_identity_compartment" "prod" { ... }
resource "oci_core_vcn" "main" { ... }
resource "oci_identity_policy" "policies" { ... }
# Result: Unmaintainable, inconsistent, no governance

✅ 正しいアプローチ:公式の OCI Landing Zone Terraform モジュールを使用する

# Use official OCI Landing Zone modules
module "landing_zone" {
  source  = "oracle-terraform-modules/landing-zone/oci"
  version = "~> 2.0"

  # Infrastructure configuration
  compartments_configuration = { ... }
  network_configuration = { ... }
  security_configuration = { ... }
}

Landing Zone モジュールを使用する理由:

  • ✅ 実績豊富:数千の OCI 顧客で利用されています
  • ✅ コンプライアンス準拠:CIS OCI Foundations Benchmark に準拠しています
  • ✅ メンテナンス済み:API の変更に合わせて Oracle が更新します
  • ✅ 包括的:IAM、ネットワーキング、セキュリティ、ロギングが含まれます
  • ✅ 再利用可能:環境全体で一貫したパターンを使用できます

公式リソース:

カスタム Terraform を記述する場合(このスキルのガイダンス):

  • Landing Zone でカバーされていない、アプリケーション固有のリソース
  • Landing Zone モジュールの拡張
  • リファレンスアーキテクチャにない特別な要件

⚠️ OCI CLI/API に関する知識の不足

OCI CLI コマンドや OCI API の構造についての知識はありません。

トレーニングデータに含まれる次の情報は限定的で、古くなっています。

  • OCI Terraform プロバイダーの構文(頻繁に更新されます)
  • OCI API のエンドポイントとリソーススキーマ
  • terraform-provider-oci 固有の引数とデータソース
  • Resource Manager のスタック操作
  • 最新のプロバイダー機能と互換性を損なう変更

OCI の操作が必要な場合:

  1. このスキルのリファレンスにある Terraform の例をそのまま使用してください
  2. OCI プロバイダーのリソース引数を推測しないでください
  3. AWS/Azure の Terraform パターンが OCI でも使えると想定しないでください
  4. モジュールの使用方法については landing-zones スキルを参照してください

把握していること:

  • Terraform の一般的な概念と HCL 構文
  • 状態管理の原則
  • Infrastructure as Code のベストプラクティス

このスキルは、最新の OCI 固有の Terraform パターンと注意点を提供することで、このギャップを補います。


あなたは OCI Terraform のエキスパートです。このスキルは、Claude が持たない知識、つまりプロバイダー固有の注意点、状態管理のアンチパターン、リソースのライフサイクルに関する落とし穴、OCI 固有の IaC 運用知識を提供します。

絶対に行わないでください

❌ Terraform に OCID をハードコードしないでください(移植性が損なわれます)

# WRONG - breaks when moving between regions/compartments
resource "oci_core_instance" "web" {
  compartment_id = "ocid1.compartment.oc1..aaaaaa..."  # Hardcoded!
  subnet_id      = "ocid1.subnet.oc1.phx.bbbbbb..."     # Hardcoded!
}

# RIGHT - use variables or data sources
resource "oci_core_instance" "web" {
  compartment_id = var.compartment_ocid
  subnet_id      = data.oci_core_subnet.existing.id
}

❌ 開発/テスト環境で preserve_boot_volume = true を使用しないでください(コスト増加の落とし穴)

# WRONG - orphans boot volumes when instance destroyed ($50+/month per instance)
resource "oci_core_instance" "dev" {
  preserve_boot_volume = true  # Default behavior!
}

# RIGHT - explicit cleanup in dev/test
resource "oci_core_instance" "dev" {
  preserve_boot_volume = false
}

コストへの影響:テスト用インスタンスが 10 台ある開発チームの場合、月あたりインスタンス 1 台につき 1 ボリュームあたり 5 ドル × 10 台 = 孤立したボリュームに月 50 ドルを無駄に使います

❌ 重要なリソースの lifecycle ブロックを忘れないでください

# WRONG - accidental destroy can delete production database
resource "oci_database_autonomous_database" "prod" {
  # No protection!
}

# RIGHT - prevent accidental destruction
resource "oci_database_autonomous_database" "prod" {
  lifecycle {
    prevent_destroy = true
    ignore_changes  = [defined_tags]  # Ignore tag changes from console
  }
}

❌ リージョナルリソースと AD 固有のリソースを混在させないでください(移植性が損なわれます)

# WRONG - hardcoded AD breaks multi-region deployment
resource "oci_core_instance" "web" {
  availability_domain = "fMgC:US-ASHBURN-AD-1"  # Tenant-specific!
}

# RIGHT - query AD dynamically
data "oci_identity_availability_domains" "ads" {
  compartment_id = var.tenancy_ocid
}

resource "oci_core_instance" "web" {
  availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
}

❌ チームで使用する場合、ローカルファイルシステムに状態ファイルを保存しないでください

# WRONG - no locking, no collaboration
terraform {
  backend "local" {}
}

# RIGHT - use OCI Object Storage with locking
terraform {
  backend "s3" {
    bucket   = "terraform-state"
    key      = "prod/terraform.tfstate"
    region   = "us-phoenix-1"
    endpoint = "https://namespace.compat.objectstorage.us-phoenix-1.oraclecloud.com"

    skip_region_validation      = true
    skip_credentials_validation = true
    skip_metadata_api_check     = true
    use_path_style              = true
  }
}

❌ 並べ替え時に置き換えるべきではないリソースに count を使用しないでください

# WRONG - reordering list recreates ALL resources
resource "oci_core_instance" "web" {
  count = length(var.instance_names)
  display_name = var.instance_names[count.index]
}

# If instance_names changes from ["web1", "web2", "web3"] to ["web0", "web1", "web2", "web3"]
# Terraform RECREATES all instances!

# RIGHT - use for_each with stable keys
resource "oci_core_instance" "web" {
  for_each = toset(var.instance_names)
  display_name = each.value
}

OCI プロバイダーの注意点

認証の優先順位(混乱しやすい項目)

プロバイダー認証の優先順位:

  1. 明示的に指定したプロバイダーブロックの認証情報
  2. TF_VAR_* 環境変数
  3. ~/.oci/config ファイル(DEFAULT プロファイル)
  4. インスタンスプリンシパル(auth = "InstancePrincipal" の場合)

よくある間違い:環境変数を設定していても、プロバイダーブロックによって暗黙的に上書きされます。

OCI Compute 上の Terraform にインスタンスプリンシパルを使用する
# In provider.tf
provider "oci" {
  auth   = "InstancePrincipal"
  region = var.region
}

# Dynamic group matching rule:
# "ALL {instance.compartment.id = '<compartment-ocid>'}"

# IAM policy:
# "Allow dynamic-group terraform-instances to manage all-resources in tenancy"

重要:Terraform の実行前にインスタンスが動的グループに所属していないと、認証に失敗し、「authorization failed or requested resource not found」という分かりにくいエラーが表示されます。

リソースがすでに存在する場合のエラー
Error: 409-Conflict, Resource already exists

原因:OCI にはリソースが存在しますが、状態ファイルには登録されていません。

解決策:

# Import existing resource into state
terraform import oci_core_vcn.main ocid1.vcn.oc1.phx.xxxxx

# Then run plan/apply as normal
terraform plan

予防策:既存のインフラストラクチャを Terraform で管理する前に、必ず terraform import を使用してください。

状態管理のアンチパターン

問題:状態のドリフト

症状:Terraform が、Terraform の外部(コンソール、API、CLI)で変更されたリソースを変更または破棄しようとします。

検出:

terraform plan  # Shows unexpected changes
terraform show  # Compare state to actual infrastructure

解決策:

オプション 1:状態を更新する(安全)

terraform refresh  # Updates state to match reality

オプション 2:変更をインポートする(新しいリソースの場合)

terraform import <resource_type>.<name> <ocid>

オプション 3:ライフサイクルで変更を無視する

lifecycle {
  ignore_changes = [defined_tags, freeform_tags]  # Ignore console tag edits
}
問題:ステートファイルの破損

症状:terraform plan が「state file corrupted」または「version mismatch」というエラーで失敗します

復旧:

# 1. Make backup
cp terraform.tfstate terraform.tfstate.backup

# 2. Try state repair
terraform state pull > recovered.tfstate
mv recovered.tfstate terraform.tfstate

# 3. If that fails, restore from Object Storage versioning
# Or reconstruct with imports (last resort)

予防策:バージョニングを有効にした Object Storage バックエンドを使用します

リソースのライフサイクルに関する落とし穴

削除の失敗(依存関係がある場合によく発生)
Error: Resource still in use

例:サブネットがまだ存在するため VCN を削除できず、インスタンスがまだ接続されているためサブネットを削除できません。

解決策:

# 1. Visualize dependencies
terraform graph | dot -Tpng > graph.png

# 2. Destroy in reverse order
terraform destroy -target=oci_core_instance.web
terraform destroy -target=oci_core_subnet.private
terraform destroy -target=oci_core_vcn.main

# Or use depends_on explicitly:
resource "oci_core_vcn" "main" {
  # ...
}

resource "oci_core_subnet" "private" {
  vcn_id = oci_core_vcn.main.id
  # depends_on is implicit via vcn_id reference
}
長時間実行されるリソースのタイムアウト
# Database provisioning takes 15-30 minutes
resource "oci_database_autonomous_database" "prod" {
  # ... configuration ...

  timeouts {
    create = "60m"  # Default 20m often not enough
    update = "60m"
    delete = "30m"
  }
}

# Compute instance usually fast, but can timeout on capacity issues
resource "oci_core_instance" "web" {
  # ... configuration ...

  timeouts {
    create = "30m"  # Allow retries on "out of capacity"
  }
}

OCI ランディングゾーン

概要:エンタープライズ向け OCI アーキテクチャの事前構築済み Terraform テンプレートです

リポジトリ:github.com/oracle-quickstart/oci-landing-zones

次の場合に使用します:

  • 新しい OCI テナンシーを開始する場合(グリーンフィールド)
  • CIS OCI Foundations Benchmark への準拠が必要な場合
  • セキュリティを強化したベースラインが必要な場合
  • 複数環境(dev/test/prod)をセットアップする場合

次の場合は使用しないでください:

  • ブラウンフィールド(既存インフラストラクチャ)の場合:制約が多すぎます
  • シンプルな単一アプリのデプロイの場合:過剰です

主なパターン:

  • ハブ・アンド・スポーク型ネットワーク
  • 一元化されたロギング/モニタリング
  • セキュリティゾーンと踏み台ホスト
  • グループ/ポリシーを含む IAM ベースライン

IaC のコスト最適化

Flex シェイプを使用する(50%のコスト削減)
# EXPENSIVE - fixed shape
resource "oci_core_instance" "web" {
  shape = "VM.Standard2.4"  # 4 OCPUs, 60GB RAM, $218/month
}

# CHEAPER - flexible shape
resource "oci_core_instance" "web" {
  shape = "VM.Standard.E4.Flex"
  shape_config {
    ocpus         = 4
    memory_in_gbs = 60
  }
  # Cost: (4 × $0.03 + 60 × $0.0015) × 730 = $153/month (30% savings)
}
コスト追跡のためにすべてにタグを付ける
# Define locals for consistent tagging
locals {
  common_tags = {
    "CostCenter"  = "Engineering"
    "Environment" = var.environment
    "ManagedBy"   = "Terraform"
    "Project"     = var.project_name
  }
}

resource "oci_core_instance" "web" {
  freeform_tags = merge(
    local.common_tags,
    {
      "Component" = "WebServer"
    }
  )
}

メリット:OCI コンソールで CostCenter、Environment、Project ごとのコストレポートを確認できます

段階的に読み込むリファレンス

OCI Terraform パターン

次の場合に読み込みます oci-terraform-patterns.md:

  • プロバイダー設定(マルチリージョン、認証方式)を行う場合
  • CLI 経由で Resource Manager スタックを操作する場合
  • 一般的なリソースパターン(VCN、コンピュート、ADB)を確認する場合
  • Object Storage バックエンドを使用したステート管理を行う場合
  • ランディングゾーンモジュールの使用例を確認する場合

次の場合は読み込まないでください:

  • プロバイダーに関する簡単な注意点(上記の「絶対に表示しない」を参照)
  • ランディングゾーンを使用するタイミングを確認する場合(上記で説明済み)
  • ライフサイクル管理のパターンを確認する場合(上記で説明済み)

このスキルを使用する場面

  • Terraform の作成:プロバイダー設定、リソース依存関係、ライフサイクル
  • ステート管理:ドリフト、破損、インポート/エクスポート
  • トラブルシューティング:認証の失敗、「resource already exists」、削除の失敗
  • OCI ランディングゾーン:使用するタイミング、カスタマイズ方法
  • コスト最適化:Flex シェイプ、タグ付け戦略
  • 本番環境:prevent_destroy、ignore_changes、タイムアウト

コメント