스토리지 이벤트 함수 앱

아키텍처

스토리지 이벤트 함수 앱은 이미지 디렉터리 및 썸네일 제작 도구입니다. 다음 구성요소로 구성됩니다.

  • 사용자가 이미지를 업로드할 수 있는 클라이언트 애플리케이션
    • 컨테이너 호스팅 API 및 정적 사이트 - Golang - Cloud Run
    • 스토리지 - 파일 스토리지 - Cloud Storage
  • 이미지 썸네일을 만드는 이미지 프로세서
    • 서비스로서의 기능 - Golang - Cloud Functions
  • 배포 파이프라인
    • 배포 - Cloud Build

시작하기

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

Cloud Shell에서 열기

GitHub에서 소스 코드 보기


스토리지 이벤트 함수 앱 구성요소

스토리지 이벤트 함수 앱 아키텍처에는 여러 제품이 사용됩니다. 다음은 관련 동영상 링크, 제품 문서 및 대화형 둘러보기를 포함하여 구성 요소에 대한 자세한 정보와 함께 구성요소 목록을 보여줍니다.
동영상 문서 둘러보기
Cloud Run Cloud Run을 사용하면 컨테이너에서 애플리케이션을 실행할 수 있지만 서버리스 방식으로 인스턴스, 프로세스, 메모리 수를 구성할 필요가 없습니다. 컨테이너를 업로드하고 URL을 가져옵니다.
Cloud Storage Cloud Storage는 파일 스토리지 및 http(s)를 통한 공개 이미지 제공을 지원합니다.
Cloud Functions Cloud Functions는 Cloud Storage 파일 업로드를 리슨하고 썸네일 생성 코드를 실행할 수 있는 서비스 플랫폼의 함수입니다.
Cloud Build Cloud Build는 컨테이너를 패키지하고 이를 Cloud Run 서비스로 사용할 수 있도록 배포하는 도구입니다.

스크립트

설치 스크립트는 go 및 Terraform CLI 도구로 작성된 실행 파일을 사용하여 빈 프로젝트를 가져오고 여기에 애플리케이션을 설치합니다. 출력은 작동하는 애플리케이션과 부하 분산 IP 주소의 URL입니다.

./main.tf

서비스 사용 설정

Google Cloud 서비스는 기본적으로 프로젝트에서 사용 중지되어 있습니다. 여기에서 솔루션을 사용하려면 다음을 활성화해야 합니다.

  • Cloud Build - 컨테이너 이미지를 만들고 Cloud Run에 배포합니다.
  • Cloud Storage - 정적 파일을 호스팅합니다.
  • Cloud Functions - 서비스로서의 기능 플랫폼
  • Cloud Run - 컨테이너를 호스팅하는 서버리스 도구이며 애플리케이션에 액세스하기 위한 URL을 제공합니다.
  • Artifact Registry - Cloud Build에 사용할 Docker 이미지를 저장합니다.
variable "gcp_service_list" {
    description = "The list of apis necessary for the project"
    type        = list(string)
    default = [
        "cloudbuild.googleapis.com",
        "storage.googleapis.com",
        "cloudfunctions.googleapis.com",
        "run.googleapis.com",
        "artifactregistry.googleapis.com",
    ]
}

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

권한 설정

Cloud Build가 모든 서비스를 배포하도록 허용하는 IAM 역할 및 권한을 설정합니다.

  • Cloud Run에 배포하도록 Cloud Build 서비스 계정 사용 설정
  • 서비스 계정 활동 수행을 위해 Cloud Build 서비스 계정 사용 설정
  • Cloud Run에 게시하도록 Cloud Build 서비스 계정 사용 설정
  • Artifact Registry에 컨테이너를 저장하도록 Cloud Build 서비스 계정 사용 설정
variable "build_roles_list" {
    description = "The list of roles that build needs for"
    type        = list(string)
    default = [
        "roles/run.developer",
        "roles/iam.serviceAccountUser",
        "roles/run.admin",
        "roles/cloudfunctions.admin",
        "roles/artifactregistry.admin",
    ]
}

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

스토리지 버킷 만들기

업로드된 이미지 및 썸네일에 대한 스토리지 위치를 만들고 Cloud Functions 업로드에 대해 임시 스토리지 위치를 제공합니다.

resource "google_storage_bucket" "target_bucket" {
    name     = var.bucket
    project  = var.project_number
    location = var.location
}

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

Artifact Registry 저장소 만들기

다음 코드는 컨테이너가 저장된 Artifact Registry 저장소의 매개변수를 간략하게 설명합니다.

resource "google_artifact_registry_repository" "app" {
    provider      = google-beta
    format        = "DOCKER"
    location      = var.region
    project       = var.project_id
    repository_id = "${var.basename}-app"
    depends_on    = [google_project_service.all]
}

Cloud Run 애플리케이션용 컨테이너 빌드

다음은 이미지를 빌드하고 Cloud Build에 사용하도록 Artifact Registry에 업로드합니다.

resource "null_resource" "cloudbuild_app" {
    provisioner "local-exec" {
        working_dir = "${path.module}/code/app"
        command     = "gcloud builds submit . --substitutions=_REGION=${var.region},_BASENAME=${var.basename}"
    }

    depends_on = [
        google_artifact_registry_repository.app,
        google_project_service.all
    ]
}

Cloud Run에 배포

다음은 Cloud Build를 사용하여 Cloud Run에 클라이언트 웹 앱을 배포합니다.

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

    template {
        spec {
            containers {
                image = "${var.region}-docker.pkg.dev/${var.project_id}/${var.basename}-app/prod"
                env {
                name  = "BUCKET"
                value = var.bucket
                }
            }
        }

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

data "google_iam_policy" "noauth" {
    binding {
        role = "roles/run.invoker"
        members = [
        "allUsers",
        ]
    }
}

resource "google_cloud_run_service_iam_policy" "noauth_app" {
    location    = google_cloud_run_service.app.location
    project     = google_cloud_run_service.app.project
    service     = google_cloud_run_service.app.name
    policy_data = data.google_iam_policy.noauth.policy_data
}

Cloud Functions에 함수 코드 배포

함수에 직접 푸시하고 활성화합니다.

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"

    available_memory_mb   = 128
    source_archive_bucket = google_storage_bucket.function_bucket.name
    source_archive_object = google_storage_bucket_object.archive.name
    entry_point           = "OnFileUpload"
    event_trigger {
        event_type = "google.storage.object.finalize"
        resource   = google_storage_bucket.target_bucket.name
    }

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

./code/app/cloudbuild.yaml

Build API 컨테이너

다음은 웹 앱용 Docker 이미지를 만듭니다.

- name: "gcr.io/cloud-builders/docker"
  args: [ "build", "-t", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod", ".", ]

API 컨테이너를 Artifact Registry에 푸시

컨테이너를 Artifact Registry에 푸시하면 Cloud Run이 이미지를 가져와서 제공할 수 있습니다.

- name: "gcr.io/cloud-builders/docker"
  args: ["push", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod"]

대체 항목

값을 배포 시에 변경할 수 있도록 기본값을 사용하여 변수를 만듭니다.

substitutions:
  _REGION: us-central1
  _BASENAME: scaler

결론

이제 스토리지 버킷의 변경사항에 따라 Cloud Functions를 사용하여 프로젝트에서 썸네일 제작 솔루션이 실행됩니다. 또한 이 솔루션을 수정하거나 확장할 수 있도록 모든 코드가 준비되었습니다.