| # Copyright 2021 The Go Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style |
| # license that can be found in the LICENSE file. |
| |
| # Terraform configuration for GCP components from this repo. |
| |
| terraform { |
| required_version = ">= 1.0.9, < 2.0.0" |
| # Store terraform state in a GCS bucket, so all team members share it. |
| backend "gcs" { |
| bucket = "go-ecosystem" |
| } |
| required_providers { |
| google = { |
| version = "~> 4.55.0" |
| source = "hashicorp/google" |
| } |
| } |
| } |
| |
| locals { |
| region = "us-central1" |
| } |
| |
| provider "google" { |
| region = local.region |
| } |
| |
| # Inputs for values that should not appear in the repo. |
| # Terraform will prompt for these when you run it, or |
| # you can put them in a local file that is only readable |
| # by you, and pass them to terraform. |
| # See https://www.terraform.io/docs/language/values/variables.html#variable-definitions-tfvars-files. |
| |
| |
| variable "prod_project" { |
| description = "GCP project where resources live" |
| type = string |
| } |
| |
| variable "dev_project" { |
| description = "GCP project where resources live" |
| type = string |
| } |
| |
| variable "team_group" { |
| description = "GCP group for the entire team" |
| type = string |
| } |
| |
| variable "deployers_group" { |
| description = "GCP group for deployers" |
| type = string |
| } |
| |
| variable "pkgsite_db_project" { |
| description = "project containing pkgsite DB" |
| type = string |
| } |
| |
| variable "pkgsite_db_name" { |
| description = "name of pkgsite DB" |
| type = string |
| } |
| |
| variable "vulndb_bucket_project" { |
| description = "project ID for vuln DB bucket logs" |
| type = string |
| } |
| |
| # Enabled APIs |
| |
| resource "google_project_service" "apis" { |
| for_each = toset([ |
| "bigquery", |
| "cloudbuild", |
| "clouderrorreporting", |
| "cloudscheduler", |
| "cloudtasks", |
| "cloudtrace", |
| "compute", |
| "containerregistry", |
| "firestore", |
| "iap", |
| "logging", |
| "monitoring", |
| "oslogin", |
| "pubsub", |
| "run", |
| "secretmanager", |
| "sql-component", |
| "sqladmin", |
| "storage-api", |
| "storage-component" |
| ]) |
| service = "${each.key}.googleapis.com" |
| disable_on_destroy = false |
| } |
| |
| # Service accounts |
| |
| resource "google_service_account" "worker" { |
| account_id = "worker" |
| display_name = "ecosystem metrics worker service account" |
| description = "Service account used by ecosystem metrics services." |
| } |
| |
| resource "google_service_account_iam_policy" "worker" { |
| service_account_id = google_service_account.worker.name |
| policy_data = data.google_iam_policy.worker.policy_data |
| } |
| |
| # Permissions on the worker service account. |
| # These grant other identities (like users and groups) permissions |
| # to do things to/with the service account. |
| # In IAM terms, the service account is acting as a resource here, not an identity. |
| # The permissions *for* the service account (those that let the service account |
| # do things, that treat the service account as an identity) are not represented |
| # in terraform because they are on the project resource, which is managed |
| # by an iam_policy file internal to Google. |
| |
| data "google_iam_policy" "worker" { |
| binding { |
| # Let any ecosystem deployer act as this service account. |
| role = "roles/iam.serviceAccountUser" |
| members = [var.deployers_group] |
| } |
| } |
| |
| |
| resource "google_service_account" "impersonate" { |
| account_id = "impersonate" |
| display_name = "impersonate service account" |
| description = "Users can act as this service account." |
| } |
| |
| resource "google_service_account_iam_policy" "impersonate" { |
| service_account_id = google_service_account.impersonate.name |
| policy_data = data.google_iam_policy.impersonate.policy_data |
| } |
| |
| # Permissions on the impersonate service account. |
| data "google_iam_policy" "impersonate" { |
| binding { |
| # Let anyone in the ecosystem and golang group get an access token for this service account. |
| role = "roles/iam.serviceAccountTokenCreator" |
| members = [ |
| var.team_group, |
| "group:golang-eng-policy@twosync.google.com" |
| ] |
| } |
| binding { |
| # Let anyone in the ecosystem and golang group act as this service account. |
| role = "roles/iam.serviceAccountUser" |
| members = [ |
| var.team_group, |
| "group:golang-eng-policy@twosync.google.com" |
| ] |
| } |
| binding { |
| # Let anyone in the ecosystem and golang group view most of Cloud resources, including permissions. |
| role = "roles/viewer" |
| members = [ |
| var.team_group, |
| "group:golang-eng-policy@twosync.google.com" |
| ] |
| } |
| } |
| |
| resource "google_logging_metric" "scheduler_errors" { |
| name = "cloud-scheduler-errors" |
| description = "Number of errors from Cloud Scheduler jobs" |
| filter = "resource.type=cloud_scheduler_job AND severity>=ERROR" |
| metric_descriptor { |
| metric_kind = "DELTA" |
| unit = "1" |
| value_type = "INT64" |
| } |
| } |
| |
| resource "google_logging_metric" "build_errors" { |
| name = "cloud-build-errors" |
| description = "Errors from Cloud Build" |
| filter = "resource.type=build AND textPayload=ERROR" |
| metric_descriptor { |
| metric_kind = "DELTA" |
| unit = "1" |
| value_type = "INT64" |
| } |
| } |
| |
| |
| |
| resource "google_monitoring_notification_channel" "email" { |
| display_name = "Go Ecosystem Team Alerts" |
| type = "email" |
| labels = { |
| email_address = "go-ecosystem-team+alerts@google.com" |
| } |
| } |
| |
| resource "google_monitoring_alert_policy" "scheduler_job_failing" { |
| display_name = "Cloud Scheduler Job Failing" |
| |
| conditions { |
| display_name = "Instance Count" |
| |
| condition_threshold { |
| filter = <<-EOT |
| metric.type="logging.googleapis.com/user/cloud-scheduler-errors" |
| EOT |
| comparison = "COMPARISON_GT" |
| threshold_value = 1 |
| aggregations { |
| alignment_period = "600s" |
| cross_series_reducer = "REDUCE_SUM" |
| per_series_aligner = "ALIGN_DELTA" |
| } |
| duration = "0s" |
| trigger { count = 1 } |
| } |
| } |
| |
| combiner = "OR" |
| |
| notification_channels = [google_monitoring_notification_channel.email.name] |
| |
| } |
| |
| resource "google_monitoring_alert_policy" "build_job_failing" { |
| display_name = "Cloud Build Job Failing" |
| |
| conditions { |
| display_name = "Instance Count" |
| |
| condition_threshold { |
| filter = <<-EOT |
| metric.type="logging.googleapis.com/user/cloud-build-errors" |
| EOT |
| comparison = "COMPARISON_GT" |
| threshold_value = 1 |
| aggregations { |
| alignment_period = "600s" |
| cross_series_reducer = "REDUCE_SUM" |
| per_series_aligner = "ALIGN_DELTA" |
| } |
| duration = "0s" |
| trigger { count = 1 } |
| } |
| } |
| |
| combiner = "OR" |
| |
| notification_channels = [google_monitoring_notification_channel.email.name] |
| |
| } |
| |
| |
| # Cloud Build trigger to deploy the prod worker on every push to master. |
| resource "google_cloudbuild_trigger" "deploy_prod_worker" { |
| name = "Deploy-Prod-Ecosystem-Worker" |
| trigger_template { |
| branch_name = "master" |
| repo_name = "pkgsite-metrics" |
| } |
| filename = "deploy/worker.yaml" |
| |
| substitutions = { |
| "_ENV" = "prod" |
| "_BQ_DATASET" = "prod" |
| } |
| } |
| |
| # Secret for computing HMACs to obfuscate VulnDB request IPs. |
| resource "google_secret_manager_secret" "vulndb-hmac-key" { |
| secret_id = "vulndb-hmac-key" |
| replication { |
| automatic = true |
| } |
| } |
| |
| # Deployment environments |
| |
| module "prod" { |
| source = "./environment" |
| env = "prod" |
| project = var.prod_project |
| region = local.region |
| pkgsite_db_project = var.pkgsite_db_project |
| pkgsite_db_name = var.pkgsite_db_name |
| vulndb_bucket_project = var.vulndb_bucket_project |
| use_profiler = true |
| } |
| |
| |
| module "dev" { |
| source = "./environment" |
| env = "dev" |
| project = var.dev_project |
| region = local.region |
| pkgsite_db_project = var.pkgsite_db_project |
| pkgsite_db_name = var.pkgsite_db_name |
| vulndb_bucket_project = var.vulndb_bucket_project |
| use_profiler = false |
| } |
| |