mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 14:04:04 +00:00
feat(WHE-28): add terraform baseline for cloud run and scheduler
This commit is contained in:
218
infra/terraform/main.tf
Normal file
218
infra/terraform/main.tf
Normal file
@@ -0,0 +1,218 @@
|
||||
data "google_project" "current" {
|
||||
project_id = var.project_id
|
||||
}
|
||||
|
||||
resource "google_project_service" "enabled" {
|
||||
for_each = local.api_services
|
||||
project = var.project_id
|
||||
service = each.value
|
||||
disable_on_destroy = false
|
||||
disable_dependent_services = false
|
||||
}
|
||||
|
||||
resource "google_artifact_registry_repository" "containers" {
|
||||
location = local.artifact_location
|
||||
project = var.project_id
|
||||
repository_id = var.artifact_repository_id
|
||||
description = "Container images for household bot"
|
||||
format = "DOCKER"
|
||||
|
||||
labels = local.common_labels
|
||||
|
||||
depends_on = [google_project_service.enabled]
|
||||
}
|
||||
|
||||
resource "google_service_account" "bot_runtime" {
|
||||
project = var.project_id
|
||||
account_id = "${var.environment}-bot-runtime"
|
||||
display_name = "${local.name_prefix} bot runtime"
|
||||
}
|
||||
|
||||
resource "google_service_account" "mini_runtime" {
|
||||
project = var.project_id
|
||||
account_id = "${var.environment}-mini-runtime"
|
||||
display_name = "${local.name_prefix} mini runtime"
|
||||
}
|
||||
|
||||
resource "google_service_account" "scheduler_invoker" {
|
||||
project = var.project_id
|
||||
account_id = "${var.environment}-scheduler"
|
||||
display_name = "${local.name_prefix} scheduler invoker"
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "runtime" {
|
||||
for_each = local.runtime_secret_ids
|
||||
|
||||
project = var.project_id
|
||||
secret_id = each.value
|
||||
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
|
||||
labels = local.common_labels
|
||||
|
||||
depends_on = [google_project_service.enabled]
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_iam_member" "bot_runtime_access" {
|
||||
for_each = google_secret_manager_secret.runtime
|
||||
|
||||
project = var.project_id
|
||||
secret_id = each.value.secret_id
|
||||
role = "roles/secretmanager.secretAccessor"
|
||||
member = "serviceAccount:${google_service_account.bot_runtime.email}"
|
||||
}
|
||||
|
||||
module "bot_api_service" {
|
||||
source = "./modules/cloud_run_service"
|
||||
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
name = "${local.name_prefix}-bot-api"
|
||||
service_account_email = google_service_account.bot_runtime.email
|
||||
image = var.bot_api_image
|
||||
allow_unauthenticated = true
|
||||
min_instance_count = var.bot_min_instances
|
||||
max_instance_count = var.bot_max_instances
|
||||
labels = local.common_labels
|
||||
|
||||
env = {
|
||||
NODE_ENV = var.environment
|
||||
}
|
||||
|
||||
secret_env = merge(
|
||||
{
|
||||
TELEGRAM_WEBHOOK_SECRET = var.telegram_webhook_secret_id
|
||||
SCHEDULER_SHARED_SECRET = var.scheduler_shared_secret_id
|
||||
},
|
||||
var.supabase_url_secret_id == null ? {} : {
|
||||
SUPABASE_URL = var.supabase_url_secret_id
|
||||
},
|
||||
var.supabase_publishable_key_secret_id == null ? {} : {
|
||||
SUPABASE_PUBLISHABLE_KEY = var.supabase_publishable_key_secret_id
|
||||
}
|
||||
)
|
||||
|
||||
depends_on = [
|
||||
google_project_service.enabled,
|
||||
google_secret_manager_secret.runtime
|
||||
]
|
||||
}
|
||||
|
||||
module "mini_app_service" {
|
||||
source = "./modules/cloud_run_service"
|
||||
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
name = "${local.name_prefix}-mini-app"
|
||||
service_account_email = google_service_account.mini_runtime.email
|
||||
image = var.mini_app_image
|
||||
allow_unauthenticated = true
|
||||
min_instance_count = var.mini_min_instances
|
||||
max_instance_count = var.mini_max_instances
|
||||
labels = local.common_labels
|
||||
|
||||
env = {
|
||||
NODE_ENV = var.environment
|
||||
}
|
||||
|
||||
depends_on = [google_project_service.enabled]
|
||||
}
|
||||
|
||||
resource "google_cloud_run_v2_service_iam_member" "scheduler_invoker" {
|
||||
project = var.project_id
|
||||
location = var.region
|
||||
name = module.bot_api_service.name
|
||||
role = "roles/run.invoker"
|
||||
member = "serviceAccount:${google_service_account.scheduler_invoker.email}"
|
||||
}
|
||||
|
||||
resource "google_service_account_iam_member" "scheduler_token_creator" {
|
||||
service_account_id = google_service_account.scheduler_invoker.name
|
||||
role = "roles/iam.serviceAccountTokenCreator"
|
||||
member = "serviceAccount:service-${data.google_project.current.number}@gcp-sa-cloudscheduler.iam.gserviceaccount.com"
|
||||
}
|
||||
|
||||
resource "google_cloud_scheduler_job" "reminders" {
|
||||
project = var.project_id
|
||||
region = var.region
|
||||
name = "${local.name_prefix}-reminders"
|
||||
schedule = var.scheduler_cron
|
||||
time_zone = var.scheduler_timezone
|
||||
paused = var.scheduler_paused
|
||||
|
||||
http_target {
|
||||
uri = "${module.bot_api_service.uri}${var.scheduler_path}"
|
||||
http_method = var.scheduler_http_method
|
||||
|
||||
headers = {
|
||||
"Content-Type" = "application/json"
|
||||
}
|
||||
|
||||
body = base64encode(var.scheduler_body_json)
|
||||
|
||||
oidc_token {
|
||||
service_account_email = google_service_account.scheduler_invoker.email
|
||||
audience = module.bot_api_service.uri
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
module.bot_api_service,
|
||||
google_service_account_iam_member.scheduler_token_creator
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_service_account" "github_deployer" {
|
||||
count = var.create_workload_identity ? 1 : 0
|
||||
|
||||
project = var.project_id
|
||||
account_id = var.github_deploy_service_account_id
|
||||
display_name = "${local.name_prefix} GitHub deployer"
|
||||
}
|
||||
|
||||
resource "google_iam_workload_identity_pool" "github" {
|
||||
count = var.create_workload_identity ? 1 : 0
|
||||
|
||||
project = var.project_id
|
||||
workload_identity_pool_id = var.workload_identity_pool_id
|
||||
display_name = "GitHub Actions Pool"
|
||||
}
|
||||
|
||||
resource "google_iam_workload_identity_pool_provider" "github" {
|
||||
count = var.create_workload_identity ? 1 : 0
|
||||
|
||||
project = var.project_id
|
||||
workload_identity_pool_id = google_iam_workload_identity_pool.github[0].workload_identity_pool_id
|
||||
workload_identity_pool_provider_id = var.workload_identity_provider_id
|
||||
display_name = "GitHub Actions Provider"
|
||||
|
||||
attribute_mapping = {
|
||||
"google.subject" = "assertion.sub"
|
||||
"attribute.actor" = "assertion.actor"
|
||||
"attribute.repository" = "assertion.repository"
|
||||
}
|
||||
|
||||
attribute_condition = "assertion.repository == \"${var.github_repository}\""
|
||||
|
||||
oidc {
|
||||
issuer_uri = "https://token.actions.githubusercontent.com"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_service_account_iam_member" "github_oidc" {
|
||||
count = var.create_workload_identity ? 1 : 0
|
||||
|
||||
service_account_id = google_service_account.github_deployer[0].name
|
||||
role = "roles/iam.workloadIdentityUser"
|
||||
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github[0].name}/attribute.repository/${var.github_repository}"
|
||||
}
|
||||
|
||||
resource "google_project_iam_member" "github_deployer_roles" {
|
||||
for_each = var.create_workload_identity ? local.github_deploy_roles : toset([])
|
||||
|
||||
project = var.project_id
|
||||
role = each.value
|
||||
member = "serviceAccount:${google_service_account.github_deployer[0].email}"
|
||||
}
|
||||
Reference in New Issue
Block a user