Skip to content

Commit

Permalink
GCP Cloud SQL terraform module (USEPA#619)
Browse files Browse the repository at this point in the history
* rename backend to version to be more terraform idiomatic

* local SQL module for provisioning GCP Cloud SQL instances and accompanying databases 

* add options for enabling private IP and VPC connections to our Cloud SQL instance
  • Loading branch information
dpgraham4401 authored Oct 26, 2023
1 parent 1f7af3b commit c434b70
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 5 deletions.
1 change: 0 additions & 1 deletion infra/gcp/dev/.terraform.lock.hcl

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

3 changes: 2 additions & 1 deletion infra/gcp/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ for purposes of this demonstration, a pre-configured project and access is neces
- `gcloud iam service-accounts create <sa_name> --display-name "Terraform Service Account"`
- The account will need the following permissions
```shell
gcloud projects add-iam-policy-binding <project_id> -dev-test-123 \
gcloud projects add-iam-policy-binding <project_id> \
--member="serviceAccount:<sa_name>@<project_id>.iam.gserviceaccount.com" \
--role=roles/storage.objectAdmin \
--role=roles/serviceusage.serviceUsageAdmin \
Expand All @@ -37,6 +37,7 @@ for purposes of this demonstration, a pre-configured project and access is neces
--role=roles/compute.viewer \
--role=roles/compute.securityAdmin \
--role=roles/container.clusterAdmin \
--role=roles/cloudsql.admin \
--role=roles/container.developer
```
- You can check that all the roles were successfully added to our service account with the following command:
Expand Down
22 changes: 20 additions & 2 deletions infra/gcp/dev/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module "gcp_apis" {
project = var.project
services = [
"compute.googleapis.com",
"container.googleapis.com"
"container.googleapis.com",
"sqladmin.googleapis.com",
"servicenetworking.googleapis.com"
]
}

Expand Down Expand Up @@ -43,7 +45,7 @@ module "vpc" {
module "k8" {
source = "../modules/k8"
name = "haztrak-gke"
network = module.vpc.network
network = module.vpc.name
project = var.project
region = var.region
zones = [var.zone]
Expand All @@ -52,3 +54,19 @@ module "k8" {
service_ip_range_name = local.k8_subnet_service_ip_range
depends_on = [module.gcp_apis, module.vpc]
}


module "sql" {
source = "../modules/sql"
environment = var.environment
project = var.project
vpc = module.vpc.id
depends_on = [module.vpc, module.gcp_apis]
name = "haztrak"
region = var.region
databases = [
{
"name" = "haztrak_db"
}
]
}
File renamed without changes.
6 changes: 5 additions & 1 deletion infra/gcp/modules/network/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
output "network" {
output "id" {
value = module.vpc.network_id
}

output "name" {
value = module.vpc.network_name
}
81 changes: 81 additions & 0 deletions infra/gcp/modules/sql/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
locals {
# database tiers follow legacy sets of "db-custom-<VCPUs>-<RAM in MB>"
database_tier = var.environment == "prod" ? "db-custom-1-3840" : "db-f1-micro"
disk_size = var.environment == "prod" ? 10 : 10 # in GB, 10 GB is the minimum
availability = var.environment == "prod" ? "ZONAL" : "ZONAL"
instance_name = var.environment == "prod" ? "${replace(var.name, "_", "-")}-postgres" : "${replace(var.name, "_", "-")}-postgres-dev"
ip_range_name = "${replace(var.name, "_", "-")}-ip-range"
backup_enabled = var.environment == "prod" ? true : false
deletion_protection = var.environment == "prod" ? true : false
private_vpc_connection = var.enable_private_ip ? 1 : 0
}


resource "google_sql_database_instance" "primary" {
database_version = "POSTGRES_15"
name = var.name
project = var.project
region = var.region
deletion_protection = local.deletion_protection
lifecycle {
ignore_changes = [settings.0.activation_policy]
}

settings {
activation_policy = "ALWAYS"
availability_type = local.availability

backup_configuration {
backup_retention_settings {
retained_backups = 3
retention_unit = "COUNT"
}

enabled = local.backup_enabled
# location = "us"
point_in_time_recovery_enabled = local.backup_enabled
start_time = "12:00"
transaction_log_retention_days = 3
}

disk_autoresize = true
disk_autoresize_limit = 0
disk_size = 10
disk_type = "PD_SSD"

ip_configuration {
ipv4_enabled = true
private_network = var.vpc
}
pricing_plan = "PER_USE"
tier = local.database_tier
}
depends_on = [google_service_networking_connection.sql_vpc_connection]
}

resource "google_sql_database" "primary" {
for_each = { for o in var.databases : o.name => o }

name = each.value.name
instance = google_sql_database_instance.primary.name
depends_on = [google_sql_database_instance.primary]
}

resource "google_compute_global_address" "private_ip_range" {
count = local.private_vpc_connection
name = "${var.name}-ip-range"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = var.vpc
}

resource "google_service_networking_connection" "sql_vpc_connection" {
count = local.private_vpc_connection
network = var.vpc
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [
google_compute_global_address.private_ip_range[0].name
]
depends_on = [google_compute_global_address.private_ip_range]
}
7 changes: 7 additions & 0 deletions infra/gcp/modules/sql/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "instance" {
value = google_sql_database_instance.primary.name
}

output "private_ip" {
value = google_compute_global_address.private_ip_range[0].address
}
41 changes: 41 additions & 0 deletions infra/gcp/modules/sql/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
variable "region" {
description = "The GCP region the database will be hosted in"
type = string
}

variable "project" {
description = "The project id to deploy to"
type = string
}

variable "name" {
description = "The name of the database to create"
type = string
}

variable "databases" {
description = "The names of the databases to create"
type = list(object({
name = string
}))
}

variable "environment" {
description = "The environment to deploy to"
type = string
validation {
condition = contains(["dev", "prod"], var.environment)
error_message = "Environment must be one of [dev, prod]"
}
}

variable "vpc" {
description = "The ID of vpc the database is deployed to"
type = string
}

variable "enable_private_ip" {
description = "Whether to enable private IP for the sql instance to connect to the provided VPC"
type = bool
default = true
}

0 comments on commit c434b70

Please sign in to comment.