Sentry の費用

アーキテクチャ

Sentry の費用は、Google Cloud の課金予算を超過した場合にリソースをシャットダウンできるスクリプトと構成のセットです。

このスクリプトは、次のコンポーネントで構成されています。

  • イベント - キュー - Pub/Sub
  • 請求 - 費用管理 - 予算
  • イベント - イベント処理 - Cloud Functions
  • コンピューティング - VM - Compute Engine
  • コンピューティング - サーバーレス - Cloud Run

このスクリプトでは、予算、メッセージ キュー、Cloud Function を設定して、すべてを管理します。次に、サンプル VM とシステムによって管理されるコンテナ バックアップ サービスを起動します。


使ってみる

Cloud Shell でソースコードのコピーへの次のリンクをクリックします。その後、1 つのコマンドでプロジェクト内のアプリケーションの作業コピーがスピンアップされます。

Cloud Shell で開く

GitHub でソースコードを見る


Sentry コンポーネントの費用

Sentry の費用のアーキテクチャでは、いくつかのプロダクトを使用しています。 以下に、関連動画、プロダクト ドキュメント、インタラクティブ チュートリアルへのリンクを含めた、コンポーネントの詳細を示します。
動画 ドキュメント チュートリアル
Google Cloud Pub/Sub Google Cloud Pub/Sub は、さまざまなクラウド コンポーネント上のさまざまなサービスのアプリケーションを統合システムに統合するためのメッセージング バスです。
課金の予算 課金の予算を使用すると、設定したしきい値を超えたときに通知を受け取って対処できます。
Cloud Functions Cloud Functions は関数であり、Cloud Storage ファイルのアップロードをリッスンし、コードを実行してそれらのサムネイルを作成することができるサービス プラットフォームです。
Compute Engine Compute Engine は Google Cloud の仮想技術です。VM のさまざまな構成を起動して、どのようなコンピューティング ニーズにも対応できます。
Cloud Run Cloud Run を使用すると、コンテナ内でアプリケーションを実行できますが、サーバーレスで、インスタンス、プロセッサ、メモリの数を構成する必要はありません。コンテナをアップロードし、URL を取得します。

スクリプト

インストール スクリプトでは、go と Terraform CLI ツールで記述された実行ファイルを使用して、空のプロジェクトを作成し、そこにアプリケーションをインストールします。出力は、機能するアプリケーションとロード バランシング IP アドレスの URL になります。

./main.tf

サービスを有効化する

Google Cloud サービスは、デフォルトではプロジェクトで無効になっています。Sentry の費用を使用するには、次のサービスを有効にします。

  • 課金の予算 - 課金を追跡し、料金のアラートを管理します。
  • Cloud Build - コンテナ イメージを作成して Cloud Run にデプロイします。
  • Compute Engine - ロード バランシングなどの仮想マシンとネットワーク サービスを実装します。
  • Cloud Functions - サービス プラットフォームのイベントに応答します
  • Cloud Run - サーバーレス環境でコンテナをホストし、アプリケーションにアクセスするための URL を提供します。
variable "gcp_service_list" {
        description = "The list of apis necessary for the project"
        type        = list(string)
        default = [
            "cloudresourcemanager.googleapis.com",
            "cloudbilling.googleapis.com",
            "billingbudgets.googleapis.com",
            "cloudbuild.googleapis.com",
            "compute.googleapis.com",
            "cloudfunctions.googleapis.com",
            "storage.googleapis.com",
            "run.googleapis.com"
        ]
}

resource "google_project_service" "all" {
    for_each           = toset(var.gcp_service_list)
    project            = var.project_number
    service            = each.key
    disable_on_destroy = false
}

Pub/Sub チャネルを作成する

課金の予算のイベントをリッスンし、Cloud Functions で応答する Pub/Sub チャネルを作成します

resource "google_pubsub_topic" "costsentry" {
    name = "${var.basename}-billing-channel"
    project    = var.project_number
}

適用する Cloud Run サービスを作成する

課金の適用を実行するサンプルの Cloud Run サービスを作成します。

resource "google_cloud_run_service" "app" {
    name     = "${var.basename}-run-service"
    location = var.region
    project  = var.project_id

    metadata {
        labels = {"${var.label}"=true}
    }

    template {
        spec {
            containers {
                image = "us-docker.pkg.dev/cloudrun/container/hello"
            }
        }

        metadata {
            annotations = {
                "autoscaling.knative.dev/maxScale" = "1000"
                "run.googleapis.com/client-name"   = "terraform"
            }
        }
    }
    autogenerate_revision_name = true
    depends_on = [google_project_service.all]
}

VM インスタンスを作成

強制適用を実行するサンプルの Compute Engine インスタンスを作成します。

resource "google_compute_instance" "example" {
    name         = "${var.basename}-example"
    machine_type = "n1-standard-1"
    zone         = var.zone
    project      = var.project_id
    tags                    = ["http-server"]
    labels = {"${var.label}"=true}

    boot_disk {
        auto_delete = true
        device_name = "${var.basename}-example"
        initialize_params {
            image = "family/debian-10"
            size  = 200
            type  = "pd-standard"
        }
    }

    network_interface {
        network = "default"
        access_config {
        // Ephemeral public IP
        }
    }

    depends_on = [google_project_service.all]
}

予算を作成する

プロジェクトの費用をモニタリングするための予算を作成します。

provisioner "local-exec" {
    command = <<-EOT
    gcloud beta billing budgets create --display-name ${var.basename}-budget \
    --billing-account ${var.billing_account} --budget-amount ${var.budgetamount} \
    --all-updates-rule-pubsub-topic=projects/${var.project_id}/topics/${var.basename}-billing-channel
    EOT
}

サービス アカウントを作成して権限を設定する

Cloud Function 関数の呼び出し用のサービス アカウントを作成します。

resource "google_service_account" "functions_accounts" {
    account_id   = local.safunctionuser
    description  = "Service Account for the costsentry to run as"
    display_name = local.safunction
    project      = var.project_number
}

権限を設定

次のコマンドは、Cloud Build で必要なサービスをデプロイできるようにする IAM のロールと権限を設定します。

この一連のコマンドで、以下が実装されます。Cloud Run を管理する権限を Cloud Functions サービス アカウントに付与します。Cloud Functions サービス アカウントに Compute Engine インスタンスを停止する権限を付与します。Cloud Build サービス アカウントに、コンピューティング サービス アカウントに代わって動作する権限を付与します。

variable "build_roles_list" {
        description = "The list of roles that fucntions needs for"
        type        = list(string)
        default = [
            "roles/run.admin",
            "roles/compute.instanceAdmin",
            "roles/iam.serviceAccountUser"
        ]
}

resource "google_project_iam_member" "allbuild" {
    for_each   = toset(var.build_roles_list)
    project    = var.project_number
    role       = each.key
    member     = "serviceAccount:${google_service_account.functions_accounts.email}"
    depends_on = [google_project_service.all,google_service_account.functions_accounts]
}

Cloud Function をデプロイする

次のコマンドは、アラートがトリガーされたときにリソースを無効にする Cloud Functions をデプロイします。

resource "google_storage_bucket" "function_bucket" {
    name     = "${var.project_id}-function-deployer"
    project  = var.project_number
    location = var.location
}

resource "null_resource" "cloudbuild_function" {
    provisioner "local-exec" {
        command = <<-EOT
        cp code/function/function.go .
        cp code/function/go.mod .
        zip index.zip function.go
        zip index.zip go.mod
        rm go.mod
        rm function.go
        EOT
    }

    depends_on = [
        google_project_service.all
    ]
}

resource "google_storage_bucket_object" "archive" {
    name   = "index.zip"
    bucket = google_storage_bucket.function_bucket.name
    source = "index.zip"
    depends_on = [
        google_project_service.all,
        google_storage_bucket.function_bucket,
        null_resource.cloudbuild_function
    ]
}

resource "google_cloudfunctions_function" "function" {
    name    = var.basename
    project = var.project_id
    region  = var.region
    runtime = "go116"
    service_account_email = google_service_account.functions_accounts.email
    available_memory_mb   = 128
    source_archive_bucket = google_storage_bucket.function_bucket.name
    source_archive_object = google_storage_bucket_object.archive.name
    entry_point           = "LimitUsage"
    event_trigger {
        event_type = "google.pubsub.topic.publish"
        resource   = google_pubsub_topic.costsentry.name
    }

    environment_variables = {
        GOOGLE_CLOUD_PROJECT = var.project_id
        LABEL= var.label
    }

    depends_on = [
        google_storage_bucket.function_bucket,
        google_storage_bucket_object.archive,
        google_project_service.all
    ]
}

まとめ

これで、プロジェクト内でコスト管理ソリューションが実行されます。さらに、環境に合わせてソリューションを変更または拡張するためのコードもすべて用意されています。