스토리지 이벤트 함수 앱

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

아키텍처

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

  • 사용자가 이미지를 업로드할 수 있는 클라이언트 애플리케이션
    • 컨테이너 호스팅 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 Run에 사용하도록 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를 사용하여 프로젝트에서 썸네일 제작 솔루션이 실행됩니다. 또한 이 솔루션을 수정하거나 확장할 수 있도록 모든 코드가 준비되었습니다.