Deploy Metabase to production

Closes https://github.com/firezone/firezone/issues/2527
This commit is contained in:
Andrew Dryga
2023-11-15 17:04:04 -06:00
parent 95bfd5bb02
commit ce7c5198fa
4 changed files with 226 additions and 69 deletions

View File

@@ -0,0 +1,174 @@
# Deploy our Metabase instance
locals {
metabase_region = local.region
metabase_zone = local.availability_zone
}
resource "random_password" "metabase_db_password" {
length = 16
min_lower = 1
min_upper = 1
min_numeric = 1
min_special = 1
}
# This user can also be used to connect to the Firezone database,
# but following SQL should be run manually using the Cloud SQL Proxy:
#
# GRANT SELECT ON ALL TABLES IN SCHEMA public TO metabase;
# GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO metabase;
#
resource "google_sql_user" "metabase" {
project = module.google-cloud-project.project.project_id
instance = module.google-cloud-sql.master_instance_name
name = "metabase"
password = random_password.metabase_db_password.result
}
resource "google_sql_database" "metabase" {
project = module.google-cloud-project.project.project_id
name = "metabase"
instance = module.google-cloud-sql.master_instance_name
}
module "metabase" {
source = "../../modules/metabase-app"
project_id = module.google-cloud-project.project.project_id
compute_network = module.google-cloud-vpc.id
compute_subnetwork = google_compute_subnetwork.tools.self_link
compute_instance_type = "n1-standard-1"
compute_region = local.metabase_region
compute_instance_availability_zone = local.metabase_zone
image_repo = "metabase"
image = "metabase"
image_tag = var.metabase_image_tag
application_name = "metabase"
application_version = replace(replace(var.metabase_image_tag, ".", "-"), "v", "")
application_environment_variables = [
{
name = "MB_DB_TYPE"
value = "postgres"
},
{
name = "MB_DB_TYPE"
value = "postgres"
},
{
name = "MB_DB_DBNAME"
value = google_sql_database.metabase.name
},
{
name = "MB_DB_PORT"
value = "5432"
},
{
name = "MB_DB_USER"
value = google_sql_user.metabase.name
},
{
name = "MB_DB_PASS"
value = random_password.metabase_db_password.result
},
{
# TODO: create a read replica for analytics
name = "MB_DB_HOST"
value = module.google-cloud-sql.bi_instance_ip_address
},
{
name = "MB_SITE_NAME"
value = module.google-cloud-project.project.project_id
},
{
name = "MB_ANON_TRACKING_ENABLED"
value = "false"
},
# {
# name = "MB_JETTY_PORT"
# value = "80"
# }
]
health_check = {
name = "health"
protocol = "TCP"
port = 3000
initial_delay_sec = 60
check_interval_sec = 15
timeout_sec = 10
healthy_threshold = 1
unhealthy_threshold = 3
http_health_check = {
request_path = "/healthz"
}
}
}
# Allow outbound traffic
resource "google_compute_firewall" "egress-ipv4" {
project = module.google-cloud-project.project.project_id
name = "metabase-egress-ipv4"
network = module.google-cloud-vpc.id
direction = "EGRESS"
target_tags = module.metabase.target_tags
destination_ranges = ["0.0.0.0/0"]
allow {
protocol = "udp"
}
}
resource "google_compute_firewall" "egress-ipv6" {
project = module.google-cloud-project.project.project_id
name = "metabase-egress-ipv6"
network = module.google-cloud-vpc.id
direction = "EGRESS"
target_tags = module.metabase.target_tags
destination_ranges = ["::/0"]
allow {
protocol = "udp"
}
}
resource "google_compute_firewall" "metabase-ssh-ipv4" {
project = module.google-cloud-project.project.project_id
name = "metabase-ssh-ipv4"
network = module.google-cloud-vpc.id
allow {
protocol = "tcp"
ports = [22]
}
allow {
protocol = "udp"
ports = [22]
}
allow {
protocol = "sctp"
ports = [22]
}
# Only allows connections using IAP
source_ranges = local.iap_ipv4_ranges
target_tags = module.metabase.target_tags
}

View File

@@ -1,34 +1,7 @@
# Deploy our dogfood gateways
locals {
gateways_region = "us-central1"
gateways_zones = ["us-central1-b"]
}
resource "google_compute_network" "gateways" {
project = module.google-cloud-project.project.project_id
name = "gateways"
routing_mode = "GLOBAL"
auto_create_subnetworks = false
depends_on = [
module.api
]
}
resource "google_compute_subnetwork" "gateways" {
project = module.google-cloud-project.project.project_id
name = "gateways"
region = local.gateways_region
network = google_compute_network.gateways.self_link
stack_type = "IPV4_IPV6"
ip_cidr_range = "10.101.0.0/24"
ipv6_access_type = "EXTERNAL"
private_ip_google_access = true
gateways_region = local.region
gateways_zones = [local.availability_zone]
}
module "gateways" {
@@ -37,8 +10,8 @@ module "gateways" {
source = "../../modules/gateway-google-cloud-compute"
project_id = module.google-cloud-project.project.project_id
compute_network = google_compute_network.gateways.self_link
compute_subnetwork = google_compute_subnetwork.gateways.self_link
compute_network = module.google-cloud-vpc.id
compute_subnetwork = google_compute_subnetwork.tools.self_link
compute_instance_type = "n1-standard-1"
compute_region = local.gateways_region
@@ -78,50 +51,34 @@ module "gateways" {
token = var.gateway_token
}
# Allow gateways to access the Metabase
resource "google_compute_firewall" "gateways-metabase-access" {
count = var.gateway_token != null ? 1 : 0
# Allow inbound traffic
# resource "google_compute_firewall" "ingress-ipv4" {
# count = var.gateway_token != null ? 1 : 0
project = module.google-cloud-project.project.project_id
# project = module.google-cloud-project.project.project_id
name = "gateways-metabase-access"
network = module.google-cloud-vpc.id
direction = "INGRESS"
# name = "gateways-ingress-ipv4"
# network = google_compute_network.network.self_link
# direction = "INGRESS"
source_tags = module.gateways[0].target_tags
target_tags = module.metabase.target_tags
# target_tags = module.gateways[0].target_tags
# source_ranges = ["0.0.0.0/0"]
allow {
protocol = "tcp"
}
}
# allow {
# protocol = "udp"
# }
# }
# resource "google_compute_firewall" "ingress-ipv6" {
# count = var.gateway_token != null ? 1 : 0
# project = module.google-cloud-project.project.project_id
# name = "gateways-ingress-ipv6"
# network = google_compute_network.network.self_link
# direction = "INGRESS"
# target_tags = module.gateways[0].target_tags
# source_ranges = ["::/0"]
# allow {
# protocol = "udp"
# }
# }
# curl "http://metabase.c.firezone-prod.internal:3000/" -v
# Allow outbound traffic
resource "google_compute_firewall" "egress-ipv4" {
resource "google_compute_firewall" "gateways-egress-ipv4" {
count = var.gateway_token != null ? 1 : 0
project = module.google-cloud-project.project.project_id
name = "gateways-egress-ipv4"
network = google_compute_network.gateways.self_link
network = module.google-cloud-vpc.id
direction = "EGRESS"
target_tags = module.gateways[0].target_tags
@@ -132,13 +89,13 @@ resource "google_compute_firewall" "egress-ipv4" {
}
}
resource "google_compute_firewall" "egress-ipv6" {
resource "google_compute_firewall" "gateways-egress-ipv6" {
count = var.gateway_token != null ? 1 : 0
project = module.google-cloud-project.project.project_id
name = "gateways-egress-ipv6"
network = google_compute_network.gateways.self_link
network = module.google-cloud-vpc.id
direction = "EGRESS"
target_tags = module.gateways[0].target_tags
@@ -155,7 +112,7 @@ resource "google_compute_firewall" "gateways-ssh-ipv4" {
project = module.google-cloud-project.project.project_id
name = "gateways-ssh-ipv4"
network = google_compute_network.gateways.self_link
network = module.google-cloud-vpc.id
allow {
protocol = "tcp"
@@ -173,6 +130,6 @@ resource "google_compute_firewall" "gateways-ssh-ipv4" {
}
# Only allows connections using IAP
source_ranges = ["35.235.240.0/20"]
source_ranges = local.iap_ipv4_ranges
target_tags = module.gateways[0].target_tags
}

View File

@@ -11,6 +11,10 @@ locals {
availability_zone = "us-east1-d"
tld = "firezone.dev"
iap_ipv4_ranges = [
"35.235.240.0/20"
]
}
terraform {
@@ -206,6 +210,23 @@ resource "google_compute_subnetwork" "apps" {
private_ip_google_access = true
}
# Create VPN subnet for tooling instances
resource "google_compute_subnetwork" "tools" {
project = module.google-cloud-project.project.project_id
name = "tooling"
stack_type = "IPV4_IPV6"
ip_cidr_range = "10.129.0.0/20"
region = local.region
network = module.google-cloud-vpc.id
ipv6_access_type = "EXTERNAL"
private_ip_google_access = true
}
# Create SQL user and database
resource "random_password" "firezone_db_password" {
length = 16
@@ -753,7 +774,7 @@ resource "google_compute_firewall" "portal-ssh-ipv4" {
}
# Only allows connections using IAP
source_ranges = ["35.235.240.0/20"]
source_ranges = local.iap_ipv4_ranges
target_tags = concat(module.web.target_tags, module.api.target_tags)
}
@@ -781,7 +802,7 @@ resource "google_compute_firewall" "relays-ssh-ipv4" {
}
# Only allows connections using IAP
source_ranges = ["35.235.240.0/20"]
source_ranges = local.iap_ipv4_ranges
target_tags = module.relays[0].target_tags
}

View File

@@ -3,6 +3,11 @@ variable "image_tag" {
description = "Image tag for all services. Notice: we assume all services are deployed with the same version"
}
variable "metabase_image_tag" {
type = string
default = "v0.47.6"
}
variable "relay_token" {
type = string
default = null