Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/terraform-apply.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Terraform Apply

on:
workflow_dispatch:
inputs:
environment:
type: choice
required: true
options: [dev, staging, prod]

jobs:
apply:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment }}
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform -chdir=infra/terraform/environments/${{ github.event.inputs.environment }} init -input=false
- name: Terraform Apply
env:
TF_VAR_project_id: ${{ secrets.GCP_PROJECT_ID }}
TF_VAR_region: ${{ secrets.GCP_REGION }}
TF_VAR_artifact_repository_id: ${{ secrets.GCP_ARTIFACT_REGISTRY_REPOSITORY }}
TF_VAR_service_name: ${{ secrets.GCP_CLOUD_RUN_SERVICE }}
TF_VAR_service_account: ${{ secrets.GCP_RUNTIME_SERVICE_ACCOUNT }}
TF_VAR_image: ${{ secrets.GCP_CLOUD_RUN_IMAGE }}
TF_VAR_redis_name: ${{ secrets.GCP_REDIS_INSTANCE_NAME }}
TF_VAR_anthropic_secret_id: ${{ secrets.GCP_ANTHROPIC_SECRET_ID }}
run: terraform -chdir=infra/terraform/environments/${{ github.event.inputs.environment }} apply -auto-approve -input=false
32 changes: 32 additions & 0 deletions .github/workflows/terraform-plan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Terraform Plan

on:
pull_request:
branches: [main]
paths:
- 'infra/terraform/**'

jobs:
plan:
runs-on: ubuntu-latest
strategy:
matrix:
env: [dev, staging, prod]
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform -chdir=infra/terraform/environments/${{ matrix.env }} init -backend=false
- name: Terraform Validate
run: terraform -chdir=infra/terraform/environments/${{ matrix.env }} validate
- name: Terraform Plan
run: |
terraform -chdir=infra/terraform/environments/${{ matrix.env }} plan -input=false -refresh=false \
-var="project_id=dummy-project" \
-var="region=us-central1" \
-var="artifact_repository_id=openscribe-images" \
-var="service_name=openscribe-web-${{ matrix.env }}" \
-var="service_account=openscribe-runtime@dummy-project.iam.gserviceaccount.com" \
-var="image=us-central1-docker.pkg.dev/dummy-project/openscribe-images/openscribe-web:latest" \
-var="redis_name=openscribe-redis-${{ matrix.env }}" \
-var="anthropic_secret_id=anthropic-api-key"
18 changes: 18 additions & 0 deletions infra/terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Terraform Foundation

This folder contains environment-scoped Terraform entrypoints for `dev`, `staging`, and `prod`.

## Conventions
- Shared modules live in `infra/terraform/modules/`
- Environment roots live in `infra/terraform/environments/<env>/`
- Production changes require PR approval and release tag flow

## Planned resources
- Artifact Registry
- Cloud Run
- Identity Platform
- Firestore
- Memorystore (Redis)
- Secret Manager
- Logging sink + alerts
- Load Balancer + Cloud Armor
41 changes: 41 additions & 0 deletions infra/terraform/environments/dev/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
provider "google" {
project = var.project_id
region = var.region
}

module "artifact_registry" {
source = "../../modules/artifact-registry"
location = var.region
repository_id = var.artifact_repository_id
}

module "secret_anthropic" {
source = "../../modules/secret-manager"
secret_id = var.anthropic_secret_id
}

module "firestore" {
source = "../../modules/firestore"
project_id = var.project_id
location_id = var.firestore_location
create_database = var.create_firestore_database
}

module "redis" {
source = "../../modules/redis"
name = var.redis_name
memory_size_gb = var.redis_memory_size_gb
region = var.region
tier = var.redis_tier
authorized_network = var.redis_authorized_network
}

module "cloud_run" {
source = "../../modules/cloud-run"
service_name = var.service_name
region = var.region
service_account = var.service_account
image = var.image
allow_unauthenticated = var.allow_unauthenticated
env_vars = var.env_vars
}
18 changes: 18 additions & 0 deletions infra/terraform/environments/dev/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
project_id = "your-gcp-project"
region = "us-central1"
artifact_repository_id = "openscribe-images"
service_name = "openscribe-web"
service_account = "openscribe-runtime@your-gcp-project.iam.gserviceaccount.com"
image = "us-central1-docker.pkg.dev/your-gcp-project/openscribe-images/openscribe-web:latest"
allow_unauthenticated = true
firestore_location = "nam5"
create_firestore_database = false
redis_name = "openscribe-redis"
redis_memory_size_gb = 1
redis_tier = "BASIC"
redis_authorized_network = null
anthropic_secret_id = "anthropic-api-key"
env_vars = {
HOSTED_MODE = "true"
TRANSCRIPTION_PROVIDER = "gcp_stt_v2"
}
66 changes: 66 additions & 0 deletions infra/terraform/environments/dev/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
variable "project_id" {
type = string
}

variable "region" {
type = string
}

variable "artifact_repository_id" {
type = string
}

variable "service_name" {
type = string
}

variable "service_account" {
type = string
}

variable "image" {
type = string
}

variable "allow_unauthenticated" {
type = bool
default = false
}

variable "firestore_location" {
type = string
default = "nam5"
}

variable "create_firestore_database" {
type = bool
default = false
}

variable "redis_name" {
type = string
}

variable "redis_memory_size_gb" {
type = number
default = 1
}

variable "redis_tier" {
type = string
default = "BASIC"
}

variable "redis_authorized_network" {
type = string
default = null
}

variable "anthropic_secret_id" {
type = string
}

variable "env_vars" {
type = map(string)
default = {}
}
10 changes: 10 additions & 0 deletions infra/terraform/environments/dev/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.5.0"

required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
41 changes: 41 additions & 0 deletions infra/terraform/environments/prod/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
provider "google" {
project = var.project_id
region = var.region
}

module "artifact_registry" {
source = "../../modules/artifact-registry"
location = var.region
repository_id = var.artifact_repository_id
}

module "secret_anthropic" {
source = "../../modules/secret-manager"
secret_id = var.anthropic_secret_id
}

module "firestore" {
source = "../../modules/firestore"
project_id = var.project_id
location_id = var.firestore_location
create_database = var.create_firestore_database
}

module "redis" {
source = "../../modules/redis"
name = var.redis_name
memory_size_gb = var.redis_memory_size_gb
region = var.region
tier = var.redis_tier
authorized_network = var.redis_authorized_network
}

module "cloud_run" {
source = "../../modules/cloud-run"
service_name = var.service_name
region = var.region
service_account = var.service_account
image = var.image
allow_unauthenticated = var.allow_unauthenticated
env_vars = var.env_vars
}
18 changes: 18 additions & 0 deletions infra/terraform/environments/prod/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
project_id = "your-gcp-project"
region = "us-central1"
artifact_repository_id = "openscribe-images"
service_name = "openscribe-web"
service_account = "openscribe-runtime@your-gcp-project.iam.gserviceaccount.com"
image = "us-central1-docker.pkg.dev/your-gcp-project/openscribe-images/openscribe-web:latest"
allow_unauthenticated = true
firestore_location = "nam5"
create_firestore_database = false
redis_name = "openscribe-redis"
redis_memory_size_gb = 1
redis_tier = "BASIC"
redis_authorized_network = null
anthropic_secret_id = "anthropic-api-key"
env_vars = {
HOSTED_MODE = "true"
TRANSCRIPTION_PROVIDER = "gcp_stt_v2"
}
66 changes: 66 additions & 0 deletions infra/terraform/environments/prod/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
variable "project_id" {
type = string
}

variable "region" {
type = string
}

variable "artifact_repository_id" {
type = string
}

variable "service_name" {
type = string
}

variable "service_account" {
type = string
}

variable "image" {
type = string
}

variable "allow_unauthenticated" {
type = bool
default = false
}

variable "firestore_location" {
type = string
default = "nam5"
}

variable "create_firestore_database" {
type = bool
default = false
}

variable "redis_name" {
type = string
}

variable "redis_memory_size_gb" {
type = number
default = 1
}

variable "redis_tier" {
type = string
default = "BASIC"
}

variable "redis_authorized_network" {
type = string
default = null
}

variable "anthropic_secret_id" {
type = string
}

variable "env_vars" {
type = map(string)
default = {}
}
10 changes: 10 additions & 0 deletions infra/terraform/environments/prod/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.5.0"

required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
Loading