Skip to content

Commit

Permalink
terraform config for webapp
Browse files Browse the repository at this point in the history
  • Loading branch information
jamalc committed Jan 28, 2025
1 parent e11a298 commit fcf93bb
Show file tree
Hide file tree
Showing 12 changed files with 517 additions and 50 deletions.
19 changes: 19 additions & 0 deletions terraform/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 40 additions & 47 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,63 @@ terraform {
source = "hashicorp/google"
version = "6.8.0"
}
random = {
source = "hashicorp/random"
version = "3.6.3"
}
}
}

# Configure the Google Cloud provider
provider "google" {
project = var.project
region = var.region
zone = var.zone
}

locals {
institutions = [
{
name = "Example College"
id = "example-college"
},
{
name = "Example University"
id = "example-university"
}
]
}
module "network" {
source = "./modules/network"

resource "google_storage_bucket" "upload_buckets" {
for_each = { for inst in local.institutions : inst.id => inst }
environment = var.environment
region = var.region
}

name = each.value.id
location = "US"
module "iam" {
source = "./modules/iam"

cors {
origin = ["*"]
method = ["POST", "PUT"]
response_header = [
"Content-Type",
"Access-Control-Allow-Origin",
"X-Goog-Content-Length-Range"
]
max_age_seconds = 3600
}
environment = var.environment
}

resource "google_service_account" "webapp_service_acccount" {
account_id = "webapp"
display_name = "Webapp Service Account"
description = "Service account for the webapp"
}
module "database" {
source = "./modules/database"

resource "google_project_iam_member" "webapp_service_acccount" {
project = var.project
role = "roles/storage.objectUser"
member = "serviceAccount:${google_service_account.webapp_service_acccount.email}"
environment = var.environment
region = var.region
zone = var.zone
database_name = var.database_name
database_version = var.database_version

cloud_run_service_account_email = module.iam.cloud_run_service_account_email
network_id = module.network.network_id
}

resource "google_project_iam_member" "token_creator" {
project = var.project
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${google_service_account.webapp_service_acccount.email}"
locals {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}

resource "google_storage_bucket" "default" {
name = "sst-terraform-state"
force_destroy = true
location = "US"
storage_class = "STANDARD"
versioning {
enabled = true
}
module "service" {
source = "./modules/service"

project = var.project
environment = var.environment
region = var.region
image = local.image
database_name = var.database_name

database_password_secret_id = module.database.password_secret_id
database_instance_connection_name = module.database.instance_connection_name
database_instance_private_ip = module.database.instance_private_ip
network_id = module.network.network_id
subnetwork_id = module.network.subnetwork_id
cloud_run_service_account_email = module.iam.cloud_run_service_account_email
}
131 changes: 131 additions & 0 deletions terraform/modules/database/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
resource "google_project_service" "services" {
for_each = toset(var.required_services)

service = each.value
disable_on_destroy = false
}

resource "random_password" "db_password" {
length = 16
special = true
}

resource "google_secret_manager_secret" "db_password_secret" {
secret_id = "${var.environment}-db-password"
replication {
auto {}
}
}

resource "google_secret_manager_secret_version" "db_password_secret_version" {
secret = google_secret_manager_secret.db_password_secret.id
secret_data = random_password.db_password.result
}

data "google_secret_manager_secret_version" "db_password_secret_version" {
secret = google_secret_manager_secret.db_password_secret.id
version = "latest"
}

resource "google_sql_database_instance" "db_instance" {
deletion_protection = false
name = "${var.environment}-db-instance"
database_version = var.database_version
region = var.region
settings {
tier = "db-f1-micro"
location_preference {
zone = var.zone
}
ip_configuration {
ipv4_enabled = false
private_network = var.network_id
ssl_mode = "ENCRYPTED_ONLY"
}
}
timeouts {
create = "1h"
}
}

resource "google_sql_database" "db" {
name = var.database_name
instance = google_sql_database_instance.db_instance.name
}

resource "google_sql_user" "db_user" {
name = "root"
instance = google_sql_database_instance.db_instance.name
password = data.google_secret_manager_secret_version.db_password_secret_version.secret_data
}

resource "google_sql_ssl_cert" "db_ssl_cert" {
instance = google_sql_database_instance.db_instance.name
common_name = "${var.environment}-db-ssl-cert"
}

resource "google_secret_manager_secret" "db_client_cert" {
secret_id = "${var.environment}-db-client-cert"
replication {
auto {}
}
}

resource "google_secret_manager_secret_version" "db_client_cert_version" {
deletion_policy = "DELETE"
enabled = true
secret = google_secret_manager_secret.db_client_cert.id
secret_data = google_sql_ssl_cert.db_ssl_cert.cert
}

resource "google_secret_manager_secret" "db_client_key" {
secret_id = "${var.environment}-db-client-key"
replication {
auto {}
}
}

resource "google_secret_manager_secret_version" "db_client_key_version" {
deletion_policy = "DELETE"
enabled = true
secret = google_secret_manager_secret.db_client_key.id
secret_data = google_sql_ssl_cert.db_ssl_cert.private_key
}

resource "google_secret_manager_secret" "db_server_ca" {
secret_id = "${var.environment}-db-server-ca"
replication {
auto {}
}
}

resource "google_secret_manager_secret_version" "db_server_ca_version" {
deletion_policy = "DELETE"
enabled = true
secret = google_secret_manager_secret.db_server_ca.id
secret_data = google_sql_ssl_cert.db_ssl_cert.server_ca_cert
}

resource "google_secret_manager_secret_iam_member" "cloudrun_sa_db_password_access" {
secret_id = google_secret_manager_secret.db_password_secret.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${var.cloud_run_service_account_email}"
}

resource "google_secret_manager_secret_iam_member" "cloudrun_sa_db_client_cert_access" {
secret_id = google_secret_manager_secret.db_client_cert.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${var.cloud_run_service_account_email}"
}

resource "google_secret_manager_secret_iam_member" "cloudrun_sa_db_client_key_access" {
secret_id = google_secret_manager_secret.db_client_key.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${var.cloud_run_service_account_email}"
}

resource "google_secret_manager_secret_iam_member" "cloudrun_sa_db_server_ca_access" {
secret_id = google_secret_manager_secret.db_server_ca.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${var.cloud_run_service_account_email}"
}
12 changes: 12 additions & 0 deletions terraform/modules/database/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
output "instance_connection_name" {
value = google_sql_database_instance.db_instance.connection_name
}

output "password_secret_id" {
value = google_secret_manager_secret.db_password_secret.id
sensitive = true
}

output "instance_private_ip" {
value = google_sql_database_instance.db_instance.private_ip_address
}
35 changes: 35 additions & 0 deletions terraform/modules/database/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
variable "required_services" {
type = list(string)
default = [
"sqladmin.googleapis.com",
"secretmanager.googleapis.com"
]
}

variable "environment" {
type = string
}

variable "region" {
type = string
}

variable "zone" {
type = string
}

variable "database_version" {
type = string
}

variable "database_name" {
type = string
}

variable "network_id" {
type = string
}

variable "cloud_run_service_account_email" {
type = string
}
26 changes: 26 additions & 0 deletions terraform/modules/iam/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
variable "required_services" {
type = list(string)
default = [
"iam.googleapis.com",
]
}

variable "environment" {
type = string
}

resource "google_project_service" "services" {
for_each = toset(var.required_services)

service = each.value
disable_on_destroy = false
}

resource "google_service_account" "cloudrun_sa" {
account_id = "${var.environment}-cloudrun-sa"
display_name = "${var.environment} Cloud Run Service Account"
}

output "cloud_run_service_account_email" {
value = google_service_account.cloudrun_sa.email
}
32 changes: 32 additions & 0 deletions terraform/modules/network/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
resource "google_project_service" "services" {
for_each = toset(var.required_services)

service = each.value
disable_on_destroy = false
}

resource "google_compute_network" "vpc_network" {
name = "${var.environment}-vpc-network"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "vpc_subnetwork" {
name = "${var.environment}-vpc-subnetwork"
network = google_compute_network.vpc_network.id
region = var.region
ip_cidr_range = "10.0.1.0/24"
}

resource "google_compute_global_address" "vpc_connector_ip" {
name = "${var.environment}-vpc-connector-ip"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.vpc_network.id
}

resource "google_service_networking_connection" "vpc_connection" {
network = google_compute_network.vpc_network.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.vpc_connector_ip.name]
}
7 changes: 7 additions & 0 deletions terraform/modules/network/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "network_id" {
value = google_compute_network.vpc_network.id
}

output "subnetwork_id" {
value = google_compute_subnetwork.vpc_subnetwork.id
}
14 changes: 14 additions & 0 deletions terraform/modules/network/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
variable "required_services" {
type = list(string)
default = [
"compute.googleapis.com",
]
}

variable "region" {
type = string
}

variable "environment" {
type = string
}
Loading

0 comments on commit fcf93bb

Please sign in to comment.