|
terraform { |
|
required_version = ">= 1.3.1" |
|
required_providers { |
|
google = { |
|
source = "hashicorp/google" |
|
version = "4.38.0" |
|
} |
|
} |
|
} |
|
|
|
provider "google" { |
|
project = var.project |
|
region = var.region |
|
} |
|
|
|
resource "google_sql_database_instance" "postgres" { |
|
name = "teamfeed-pgdb-3" |
|
database_version = "POSTGRES_14" |
|
region = var.region |
|
|
|
settings { |
|
tier = "db-f1-micro" |
|
availability_type = "ZONAL" |
|
|
|
backup_configuration { |
|
binary_log_enabled = false |
|
enabled = true |
|
location = "us" |
|
point_in_time_recovery_enabled = true |
|
start_time = "08:00" |
|
transaction_log_retention_days = 7 |
|
|
|
backup_retention_settings { |
|
retained_backups = 7 |
|
retention_unit = "COUNT" |
|
} |
|
} |
|
|
|
insights_config { |
|
query_insights_enabled = true |
|
query_string_length = 1024 |
|
record_application_tags = false |
|
record_client_address = false |
|
} |
|
|
|
ip_configuration { |
|
ipv4_enabled = true |
|
require_ssl = false |
|
|
|
authorized_networks { |
|
name = "teamfeed-cron" |
|
value = google_compute_address.cron.address |
|
} |
|
} |
|
|
|
maintenance_window { |
|
day = 6 |
|
hour = 10 |
|
} |
|
} |
|
} |
|
|
|
locals { |
|
web_secrets = [ |
|
"NEXTAUTH_SECRET", |
|
"NEXTAUTH_URL", |
|
"POSTGRES_URL", |
|
] |
|
} |
|
|
|
resource "google_secret_manager_secret" "web" { |
|
for_each = toset(local.web_secrets) |
|
secret_id = each.value |
|
|
|
replication { |
|
automatic = true |
|
} |
|
} |
|
|
|
resource "google_service_account" "teamfeed_runner" { |
|
account_id = "teamfeed-runner" |
|
display_name = "Teamfeed app Cloud Run account" |
|
} |
|
|
|
resource "google_project_iam_member" "teamfeed_runner" { |
|
for_each = toset([ |
|
"roles/cloudsql.client", |
|
"roles/logging.logWriter", |
|
"roles/secretmanager.secretAccessor", |
|
]) |
|
project = var.project |
|
role = each.key |
|
member = "serviceAccount:${google_service_account.teamfeed_runner.email}" |
|
} |
|
|
|
resource "google_cloud_run_service" "teamfeed" { |
|
name = "teamfeed" |
|
location = var.region |
|
|
|
lifecycle { |
|
ignore_changes = [ |
|
template[0].metadata[0].annotations["client.knative.dev/user-image"], |
|
template[0].metadata[0].annotations["run.googleapis.com/client-name"], |
|
template[0].metadata[0].annotations["run.googleapis.com/client-version"], |
|
template[0].metadata[0].labels |
|
] |
|
} |
|
template { |
|
metadata { |
|
annotations = { |
|
"autoscaling.knative.dev/maxScale" = "10" |
|
"autoscaling.knative.dev/minScale" = "1" |
|
"run.googleapis.com/cloudsql-instances" = "teamfeed:us-west1:teamfeed-pgdb-3" |
|
} |
|
} |
|
spec { |
|
container_concurrency = 80 |
|
timeout_seconds = 300 |
|
service_account_name = google_service_account.teamfeed_runner.email |
|
containers { |
|
image = "us-west1-docker.pkg.dev/teamfeed/docker/teamfeed/teamfeed:latest" |
|
# Environment variable as a secret for all values in local.web_secrets |
|
dynamic "env" { |
|
for_each = local.web_secrets |
|
content { |
|
name = env.value |
|
value_from { |
|
secret_key_ref { |
|
key = "latest" |
|
name = env.value |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
depends_on = [ |
|
google_project_iam_member.teamfeed_runner, |
|
google_secret_manager_secret.web, |
|
] |
|
} |
|
|
|
resource "google_cloud_run_service_iam_binding" "teamfeed" { |
|
location = google_cloud_run_service.teamfeed.location |
|
service = google_cloud_run_service.teamfeed.name |
|
role = "roles/run.invoker" |
|
members = [ |
|
"allUsers" |
|
] |
|
} |
|
|
|
resource "google_cloud_run_domain_mapping" "teamfeed_dev" { |
|
name = "teamfeed.dev" |
|
location = var.region |
|
|
|
metadata { |
|
namespace = "teamfeed" |
|
} |
|
|
|
spec { |
|
route_name = google_cloud_run_service.teamfeed.name |
|
} |
|
} |
|
|
|
resource "google_cloudbuild_trigger" "deploy" { |
|
description = "Build and deploy to Cloud Run service teamfeed on push to \"^master$\"" |
|
|
|
substitutions = { |
|
"_DEPLOY_REGION" = var.region |
|
"_GCR_HOSTNAME" = format("us-west1-docker.pkg.dev/%s/docker", var.project) |
|
"_LABELS" = "gcb-trigger-id=8bd1307e-f700-40e6-b6aa-885538c71038" |
|
"_PLATFORM" = "managed" |
|
"_SERVICE_NAME" = "teamfeed" |
|
"_TRIGGER_ID" = "8bd1307e-f700-40e6-b6aa-885538c71038" |
|
} |
|
tags = [ |
|
"gcp-cloud-build-deploy-cloud-run", |
|
"gcp-cloud-build-deploy-cloud-run-managed", |
|
"teamfeed", |
|
] |
|
|
|
build { |
|
images = [ |
|
"$_GCR_HOSTNAME/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA", |
|
"$_GCR_HOSTNAME/$REPO_NAME/$_SERVICE_NAME:latest", |
|
] |
|
|
|
tags = [ |
|
"gcp-cloud-build-deploy-cloud-run", |
|
"gcp-cloud-build-deploy-cloud-run-managed", |
|
"teamfeed", |
|
] |
|
|
|
step { |
|
args = [ |
|
"build", |
|
"--no-cache", |
|
"-t", |
|
"$_GCR_HOSTNAME/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA", |
|
"-t", |
|
"$_GCR_HOSTNAME/$REPO_NAME/$_SERVICE_NAME:latest", |
|
".", |
|
] |
|
id = "Build" |
|
name = "gcr.io/cloud-builders/docker" |
|
} |
|
step { |
|
args = [ |
|
"push", |
|
"--all-tags", |
|
"$_GCR_HOSTNAME/$REPO_NAME/$_SERVICE_NAME", |
|
] |
|
id = "Push" |
|
name = "gcr.io/cloud-builders/docker" |
|
} |
|
step { |
|
args = [ |
|
"run", |
|
"services", |
|
"update", |
|
"$_SERVICE_NAME", |
|
"--platform=managed", |
|
"--image=$_GCR_HOSTNAME/$REPO_NAME/$_SERVICE_NAME:latest", |
|
"--labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID,$_LABELS", |
|
"--region=$_DEPLOY_REGION", |
|
"--quiet", |
|
] |
|
entrypoint = "gcloud" |
|
id = "Deploy" |
|
name = "gcr.io/google.com/cloudsdktool/cloud-sdk:slim" |
|
} |
|
} |
|
|
|
github { |
|
name = "teamfeed" |
|
owner = "your_github_here" |
|
push { |
|
branch = "^master$" |
|
} |
|
} |
|
} |
|
|
|
resource "google_compute_address" "cron" { |
|
name = "teamfeed-db-ip" |
|
} |
|
|
|
resource "google_compute_instance" "cron" { |
|
name = "teamfeed-cron-1" |
|
machine_type = "e2-small" |
|
|
|
network_interface { |
|
network = "default" |
|
access_config { |
|
nat_ip = google_compute_address.cron.address |
|
network_tier = "PREMIUM" |
|
} |
|
} |
|
|
|
boot_disk { |
|
initialize_params { |
|
image = "debian-11-bullseye-v20220822" |
|
} |
|
} |
|
|
|
service_account { |
|
email = google_service_account.teamfeed_runner.email |
|
# Compute instances have scopes in addition to to IAM roles? |
|
# https://cloud.google.com/compute/docs/access/service-accounts |
|
scopes = [ |
|
"https://www.googleapis.com/auth/devstorage.read_only", |
|
"https://www.googleapis.com/auth/logging.write", |
|
"https://www.googleapis.com/auth/monitoring.write", |
|
"https://www.googleapis.com/auth/service.management.readonly", |
|
"https://www.googleapis.com/auth/servicecontrol", |
|
"https://www.googleapis.com/auth/trace.append", |
|
] |
|
} |
|
|
|
# TODO: Add a startup script to install the worker so you don't have to start it manually |
|
} |
|
|
|
resource "google_artifact_registry_repository" "docker" { |
|
location = var.region |
|
repository_id = "docker" |
|
format = "DOCKER" |
|
} |
|
|
|
# TODO: Move terraform state to Google Cloud Storage when there are multiple employees |