1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TerraformでCloud Runを管理する際はcpu_idleは明示的に書くべき

Posted at

はじめに

Cloud Run サービスには、次の 2 つの課金設定があります。

  • リクエスト ベースの課金(デフォルト): Cloud Run インスタンスは、リクエストの処理、起動、シャットダウン時にのみ課金されます。詳細については、インスタンスのライフサイクルをご覧ください。この設定は、以前は「リクエストの処理中にのみ CPU を割り当てる」と呼ばれていました。
  • インスタンス ベースの課金: Cloud Run インスタンスは、受信リクエストがない場合でも、インスタンスのライフサイクル全体に対して課金されます。インスタンスベースの課金は、短期のバックグラウンド タスクやその他の非同期処理タスクの実行に役立ちます。この設定は以前は [CPU を常に割り当てる] と呼ばれていました。

Ref: サービスの課金設定

デフォルトではRequest-based billingが使われるので、リクエストが少ない社内ツールや個人開発のツールなどは、少しくらい起動が遅くてもコスト重視でRequest-basedを使っているケースが多いと思います。

Cloud Runの課金方式の詳細

Request-based billing(リクエストベースの課金)

特徴:

  • リクエストの処理中にのみCPUが割り当てられる
  • アイドル時間中は課金されない
  • コールドスタートが発生する可能性がある

適用場面:

  • アクセス頻度が低いサービス(社内ツール、個人開発など)
  • コスト最適化を重視する場合
  • 少々のレスポンス遅延が許容できる場合

コスト例:

  • 月に数回しかアクセスされないサービス:月額数十円〜数百円

Instance-based billing(インスタンスベースの課金)

特徴:

  • インスタンスが起動している間は常にCPUが割り当てられる
  • リクエストがない時間も課金される
  • コールドスタートが発生しない
  • バックグラウンド処理が可能

適用場面:

  • 高いレスポンス性能が必要なサービス
  • バックグラウンドタスクを実行するサービス
  • 常時リクエストがあるサービス

コスト例:

  • 1vCPU、512MiBメモリで24時間稼働:月額約3,000円〜5,000円

課金方式の選択指針

項目 Request-based Instance-based
コスト 低(アイドル時無料) 高(常時課金)
レスポンス 遅い(コールドスタート有) 速い(常時起動)
バックグラウンド処理 不可 可能
適用例 社内ツール、個人サイト API、プロダクション

落とし穴

Request-based billingで2年以上動かしているCloud Run serviceがありました。このCloud Run serviceはTerraformで管理していました。
ずっとRequest-based billingだったので一ヶ月に100円程度しかかかっていませんでした。

Resourceが足りなくなったので、resourceを増強する機会がありました。

resource "google_cloud_run_v2_service" "default" {
  name     = "my-service"
  location = "asia-northeast1"
  ingress  = "INGRESS_TRAFFIC_ALL"

  template {
    containers {
      image = "gcr.io/my-project/my-app:latest"
    }
    
    # CPU/メモリを増強
    resources {
      cpu_count = "2"
      memory    = "2Gi"
    }
  }
}

この変更をapplyしたところ、翌月の請求が10倍以上に跳ね上がりました。調べてみると、課金方式がInstance-based billingに変わっていました。

原因

Terraform providerのドキュメントを確認すると、以下のような記載がありました (Terraform Google Provider - cloud_run_v2_service):

cpu_idle - (Optional) Determines whether CPU is only allocated during requests. True by default if the parent resources field is not set. However, if resources is set, this field must be explicitly set to true to preserve the default behavior.

つまり、resourcesフィールドを設定すると、cpu_idleのデフォルト動作が変わってしまうのです:

  • resourcesが未設定の場合:cpu_idle = true(Request-based billing)
  • resourcesが設定されている場合:cpu_idle = false(Instance-based billing)

これは直感的ではない動作で、CPUやメモリの設定を変更しただけで課金方式まで変わってしまうという罠があります。

解決方法

resourcesを設定する際は、cpu_idleを明示的に指定することで、意図しない課金方式の変更を防げます:

resource "google_cloud_run_v2_service" "default" {
  name     = "my-service"
  location = "asia-northeast1"
  ingress  = "INGRESS_TRAFFIC_ALL"

  template {
    containers {
      image = "gcr.io/my-project/my-app:latest"
    }
    
    resources {
      cpu_count = "2"
      memory    = "2Gi"
      cpu_idle  = true  # Request-based billingを維持
    }
  }
}

教訓

  1. cpu_idleは常に明示的に設定する:デフォルト動作に依存せず、意図を明確にする
  2. 課金方式の変更は大きなコスト影響がある:特に常時稼働するサービスでは注意が必要
  3. Terraform planの結果を注意深く確認する:設定変更時は予期しない変更がないかチェックする

まとめ

TerraformでCloud Runを管理する際は、resourcesフィールドの有無に関わらず、cpu_idleを明示的に設定することをお勧めします。これにより、意図しない課金方式の変更によるコスト増加を防ぐことができます。

特に個人開発や社内ツールなど、コストを抑えたいサービスでは、この設定ミスが大きな影響を与える可能性があるため、注意が必要です。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?