terraform/lab2/main.tf (110 lines of code) (raw):

/** * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ provider "google" { project = var.project_id region = var.region } locals { service_src = "thumbnails" service_name = "${local.service_src}-service" bucket_name = "${local.service_src}-${var.project_id}" bucket_pictures = "uploaded-pictures-${var.project_id}" topic_name = "gcs-events" service_account = "${local.topic_name}-sa" } # Enable services resource "google_project_service" "run" { service = "run.googleapis.com" disable_on_destroy = false } # Create a multi-region bucket with uniform bucket level access resource "google_storage_bucket" "bucket" { name = local.bucket_name location = var.bucket_location force_destroy = true uniform_bucket_level_access = true } # Make the bucket public resource "google_storage_bucket_iam_member" "member" { bucket = google_storage_bucket.bucket.name role = "roles/storage.objectViewer" member = "allUsers" } # Assume that the container is already built with build.sh # Deploy to Cloud Run resource "google_cloud_run_service" "default" { name = local.service_name location = var.region autogenerate_revision_name = true template { spec { containers { image = "gcr.io/${var.project_id}/${local.service_name}" env { name = "BUCKET_THUMBNAILS" value = local.bucket_name } } } } traffic { percent = 100 latest_revision = true } depends_on = [google_project_service.run] } # Create a Pub/Sub topic as the communication pipeline resource "google_pubsub_topic" "default" { name = local.topic_name } # Create Pub/Sub notifications when files are stored in the bucket resource "google_storage_notification" "default" { bucket = local.bucket_pictures payload_format = "JSON_API_V1" topic = google_pubsub_topic.default.id depends_on = [google_pubsub_topic.default] } # Enable notifications by giving the correct IAM permission to the unique service account. data "google_storage_project_service_account" "gcs_account" { } resource "google_pubsub_topic_iam_binding" "binding" { topic = google_pubsub_topic.default.id role = "roles/pubsub.publisher" members = ["serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"] } # Create a service account to represent the Pub/Sub subscription identity resource "google_service_account" "service_account" { account_id = local.service_account display_name = "Cloud Run Pub/Sub Invoker" } # Give the service account permission to invoke the service data "google_iam_policy" "default" { binding { role = "roles/run.invoker" members = [ "serviceAccount:${local.service_account}@${var.project_id}.iam.gserviceaccount.com" ] } depends_on = [google_service_account.service_account] } resource "google_cloud_run_service_iam_policy" "policy" { location = google_cloud_run_service.default.location project = google_cloud_run_service.default.project service = google_cloud_run_service.default.name policy_data = data.google_iam_policy.default.policy_data depends_on = [google_cloud_run_service.default] } # Finally, create a Pub/Sub subscription with the service account resource "google_pubsub_subscription" "default" { name = "${local.topic_name}-subscription" topic = google_pubsub_topic.default.name push_config { push_endpoint = google_cloud_run_service.default.status[0].url oidc_token { service_account_email = "${local.service_account}@${var.project_id}.iam.gserviceaccount.com" } } depends_on = [google_cloud_run_service.default, google_pubsub_topic.default, google_service_account.service_account] }