|
| 1 | +terraform { |
| 2 | + backend "gcs" {} |
| 3 | + |
| 4 | + required_providers { |
| 5 | + google = { |
| 6 | + source = "registry.terraform.io/hashicorp/google" |
| 7 | + version = "6.12.0" |
| 8 | + } |
| 9 | + } |
| 10 | +} |
| 11 | + |
| 12 | +# Cloud Build |
| 13 | + |
| 14 | +locals { |
| 15 | + cloudbuild_service_account = "cloudbuild-${var.env}-sa@${var.project_id}.iam.gserviceaccount.com" |
| 16 | + scheduler_service_account = "scheduler-${var.env}-sa@${var.project_id}.iam.gserviceaccount.com" |
| 17 | +} |
| 18 | + |
| 19 | +resource "google_project_service" "cloudbuild_api" { |
| 20 | + service = "cloudbuild.googleapis.com" |
| 21 | + disable_on_destroy = false |
| 22 | +} |
| 23 | + |
| 24 | +## Service usage API is required on the project to enable APIs. |
| 25 | +## https://cloud.google.com/apis/docs/getting-started#enabling_apis |
| 26 | +## serviceusage.googleapis.com acts as a central point for managing the API |
| 27 | +## lifecycle within your project. By ensuring the required APIs are enabled |
| 28 | +## and accessible, it allows Cloud Build to function seamlessly and interact |
| 29 | +## with other Google Cloud services as needed. |
| 30 | +## |
| 31 | +## The Cloud Build service account also needs roles/serviceusage.serviceUsageViewer. |
| 32 | +resource "google_project_service" "serviceusage_api" { |
| 33 | + service = "serviceusage.googleapis.com" |
| 34 | + disable_on_destroy = false |
| 35 | +} |
| 36 | + |
| 37 | +resource "google_cloudbuild_trigger" "preloader_trigger" { |
| 38 | + name = "preloader-${var.env}" |
| 39 | + service_account = "projects/${var.project_id}/serviceAccounts/${local.cloudbuild_service_account}" |
| 40 | + location = var.location |
| 41 | + |
| 42 | + # TODO(phboneff): use a better mechanism to trigger releases that re-uses Docker containters, or based on branches rather. |
| 43 | + # This is a temporary mechanism to speed up development. |
| 44 | + github { |
| 45 | + owner = var.github_owner |
| 46 | + name = "static-ct" |
| 47 | + push { |
| 48 | + tag = "^staging-deploy-(.+)$" |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + build { |
| 53 | + ## Since TesseraCT's infrastructure is not publicly accessible, we need to use |
| 54 | + ## bearer tokens for the test to access them. |
| 55 | + ## This step creates those, and stores them for later use. |
| 56 | + step { |
| 57 | + id = "bearer_token" |
| 58 | + name = "gcr.io/cloud-builders/gcloud" |
| 59 | + script = <<EOT |
| 60 | + gcloud auth print-access-token > /workspace/cb_access |
| 61 | + curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/${local.cloudbuild_service_account}/identity?audience=${var.submission_url}" > /workspace/cb_identity |
| 62 | + EOT |
| 63 | + } |
| 64 | + |
| 65 | + ## TODO(phboneff): move to its own container / cloudrun / batch job. |
| 66 | + ## Preload entries. |
| 67 | + ## Leave enough time for the preloader to run, until the token expires. |
| 68 | + ## Stop after 360k entries, this is what gets copied within 60 minutes. |
| 69 | + timeout = "4200s" // 60 minutes |
| 70 | + step { |
| 71 | + id = "ct_preloader" |
| 72 | + name = "golang" |
| 73 | + script = <<EOT |
| 74 | + START_INDEX=$(curl -H "Authorization: Bearer $(cat /workspace/cb_access)" ${var.monitoring_url}/checkpoint | head -2 | tail -1) |
| 75 | + END_INDEX=$(($START_INDEX+360000)) |
| 76 | + echo "Will run preloader between $START_INDEX and $END_INDEX" |
| 77 | + go run github.com/google/certificate-transparency-go/preload/preloader@master \ |
| 78 | + --target_log_uri=${var.submission_url}/ \ |
| 79 | + --target_bearer_token="$(cat /workspace/cb_identity)" \ |
| 80 | + --source_log_uri=${var.source_log_uri} \ |
| 81 | + --start_index=$START_INDEX \ |
| 82 | + --end_index=$END_INDEX \ |
| 83 | + --num_workers=20 \ |
| 84 | + --parallel_fetch=20 \ |
| 85 | + --parallel_submit=20 |
| 86 | + EOT |
| 87 | + wait_for = ["bearer_token"] |
| 88 | + timeout = "3420s" // 57 minutes, since token validity if of 60 min. |
| 89 | + } |
| 90 | + |
| 91 | + options { |
| 92 | + logging = "CLOUD_LOGGING_ONLY" |
| 93 | + machine_type = "E2_HIGHCPU_8" |
| 94 | + } |
| 95 | + } |
| 96 | +} |
| 97 | + |
| 98 | +// TODO(phboneff): replace with a long running job once the log is public. |
| 99 | +resource "google_cloud_scheduler_job" "deploy_cron" { |
| 100 | + paused = false |
| 101 | + project = var.project_id |
| 102 | + region = var.location |
| 103 | + name = "deploy-cron" |
| 104 | + |
| 105 | + schedule = "50 * * * *" |
| 106 | + time_zone = "America/Los_Angeles" |
| 107 | + |
| 108 | + attempt_deadline = "120s" |
| 109 | + |
| 110 | + http_target { |
| 111 | + http_method = "POST" |
| 112 | + uri = "https://cloudbuild.googleapis.com/v1/projects/${var.project_id}/locations/${var.location}/triggers/${google_cloudbuild_trigger.preloader_trigger.trigger_id}:run" |
| 113 | + body = base64encode(jsonencode({ |
| 114 | + source = { |
| 115 | + branchName = "main" |
| 116 | + } |
| 117 | + })) |
| 118 | + headers = { |
| 119 | + "Content-Type" = "application/json" |
| 120 | + } |
| 121 | + |
| 122 | + oauth_token { |
| 123 | + service_account_email = local.scheduler_service_account |
| 124 | + } |
| 125 | + } |
| 126 | +} |
0 commit comments