비용 관리

아키텍처

비용 관리는 Google Cloud Billing 예산이 초과될 때 리소스를 종료할 수 있게 해주는 스크립트 및 구성 집합입니다.

이 스크립트는 다음 구성요소로 구성됩니다.

  • 이벤트 - 큐 - Pub/Sub
  • 결제 - 비용 관리 - 예산
  • 이벤트 - 이벤트 처리 - Cloud Functions
  • 컴퓨팅 - VM - Compute Engine
  • 컴퓨팅 - 서버리스 - Cloud Run

이 스크립트는 이 모든 것을 관리하기 위해 예산, 메시징 큐, Cloud 함수를 설정합니다. 그런 다음 샘플 VM과 시스템에서 관리되는 컨테이너 지원 서비스를 가동합니다.


시작하기

Cloud Shell에서 소스 코드의 복사본에 대해 다음 링크를 클릭합니다. 링크에 도착한 다음 단일 명령어로 프로젝트에서 애플리케이션의 작업 복사본이 작동합니다.

Cloud Shell에서 열기

GitHub에서 소스 코드 보기


비용 관리 구성요소

비용 관리 아키텍처에는 여러 제품이 사용됩니다. 다음은 관련 동영상 링크, 제품 문서 및 대화형 둘러보기를 포함하여 구성 요소에 대한 자세한 정보와 함께 구성요소 목록을 보여줍니다.
동영상 문서 둘러보기
Google Cloud Pub/Sub Google Cloud Pub/Sub는 여러 클라우드 구성요소에서 여러 다른 서비스의 애플리케이션을 통합 시스템으로 통합하기 위한 메시징 버스입니다.
Billing Budgets Billing Budgets를 사용하면 결제가 설정된 임곗값을 초과할 때 알림을 받고 조치를 취할 수 있습니다.
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 서비스는 기본적으로 프로젝트에서 사용 중지되어 있습니다. 비용 관리를 사용하려면 다음 서비스를 활성화합니다.

  • Billing Budgets - 결제를 추적하고 결제 알림을 관리합니다.
  • 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 함수 호출을 위한 서비스 계정을 만듭니다.

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 Function 서비스 계정에 권한을 부여합니다. Compute Engine 인스턴스를 중지하도록 Cloud 함수 서비스 계정에 권한을 부여합니다. Compute 서비스 계정 대신 작동하도록 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 함수 배포하기

다음 명령어는 경고가 트리거될 때 리소스를 비활성화하는 Cloud 함수를 배포합니다.

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
    ]
}

결론

실행이 완료되면 이제 프로젝트에서 비용 관리 솔루션이 실행됩니다. 또한 환경에 맞게 이 솔루션을 수정하거나 확장할 수 있도록 모든 코드가 준비되었습니다.