Cost Sentry adalah serangkaian skrip dan konfigurasi yang dapat Anda gunakan untuk mematikan resource saat Anggaran Penagihan Google Cloud terlampaui.
Skrip ini terdiri dari komponen berikut :
- Peristiwa - Antrean - Pub/Sub
- Penagihan - Kontrol Biaya - Anggaran
- Peristiwa - Penanganan Peristiwa - Cloud Functions
- Komputasi - VM - Compute Engine
- Komputasi - Serverless - Cloud Run
Skrip ini akan menyiapkan anggaran, antrean pesan, dan Cloud Function untuk mengelola semua ini. Kemudian, VM sampel dan layanan yang didukung container dan dikelola oleh sistem akan dijalankan.
Mulai
Klik link berikut untuk mendapatkan salinan kode sumber di Cloud Shell. Setelah ada, satu perintah akan menjalankan salinan aplikasi yang berfungsi di project Anda..
Komponen Cost Sentry
Arsitektur Cost Sentry menggunakan beberapa produk. Berikut ini daftar komponen, beserta informasi selengkapnya tentang komponen, termasuk link ke video terkait, dokumentasi produk, dan panduan interaktif.Skrip
Skrip penginstalan menggunakan file yang dapat dieksekusi yang ditulis di alat CLI Terraform dan go
untuk mengambil project kosong dan menginstal aplikasi di dalamnya. Output harus berupa aplikasi yang berfungsi dan URL untuk alamat IP load balancing.
./main.tf
Aktifkan Layanan
Layanan Google Cloud dinonaktifkan dalam project secara default. Untuk menggunakan Cost Sentry, aktifkan layanan berikut:
- Anggaran Penagihan - melacak penagihan dan mengelola pemberitahuan penagihan.
- Cloud Build - membuat image container dan men-deploy ke Cloud Run.
- Compute Engine - mengimplementasikan mesin virtual dan layanan jaringan, seperti load balancing.
- Cloud Functions - merespons peristiwa platform layanan.
- Cloud Run - menghosting container di lingkungan tanpa server, dan menyediakan URL untuk mengakses aplikasi.
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
}
Buat saluran Pub/Sub
Membuat saluran Pub/Sub untuk memproses peristiwa anggaran penagihan dan merespons dengan Cloud Functions
resource "google_pubsub_topic" "costsentry" {
name = "${var.basename}-billing-channel"
project = var.project_number
}
Membuat Layanan Cloud Run yang akan diterapkan
Membuat contoh layanan Cloud Run yang akan digunakan untuk menjalankan penerapan penagihan.
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]
}
Membuat instance VM
Buat contoh instance Compute Engine tempat penerapan akan dijalankan.
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]
}
Buat Anggaran
Membuat anggaran untuk memantau pengeluaran dalam proyek Anda.
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
}
Membuat akun layanan dan menetapkan izin
Membuat akun layanan untuk panggilan 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
}
Tetapkan izin
Perintah berikut menetapkan peran dan izin IAM yang memungkinkan Cloud Build men-deploy layanan yang diperlukan.
Rangkaian perintah ini menerapkan hal berikut: Memberikan izin ke Akun Layanan Cloud Function untuk mengelola Cloud Run. Memberikan izin ke Akun Layanan Cloud Function untuk menghentikan instance Compute Engine. Memberikan izin ke Akun Layanan Cloud Build untuk bertindak atas nama akun layanan Compute.
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]
}
Men-deploy Cloud Function
Perintah berikut men-deploy Cloud Function yang menonaktifkan resource saat pemberitahuan dipicu.
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
]
}
Kesimpulan
Setelah dijalankan, sekarang Anda akan memiliki solusi kontrol biaya yang berjalan di project Anda. Selain itu, Anda harus memiliki semua kode untuk memodifikasi atau memperluas solusi ini agar sesuai dengan lingkungan Anda.