Skip to content

Commit cc36952

Browse files
committed
Analysts can access Metabase hosted by Cloud Run
1 parent 602dd4e commit cc36952

File tree

14 files changed

+403
-0
lines changed

14 files changed

+403
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Metabase Docker image
2+
3+
on: [push]
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.ref }}-metabase
7+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
8+
9+
jobs:
10+
build:
11+
name: Build image
12+
13+
runs-on: ubuntu-latest
14+
15+
permissions:
16+
contents: read
17+
packages: write
18+
attestations: write
19+
id-token: write
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Login to GitHub Repository
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ghcr.io
29+
username: ${{ github.actor }}
30+
password: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Build and Push
33+
uses: docker/build-push-action@v6
34+
with:
35+
context: services/metabase
36+
push: true
37+
tags: ghcr.io/${{ github.repository }}/metabase:latest
38+
cache-from: type=registry,ref=ghcr.io/${{ github.repository }}/metabase:latest
39+
cache-to: type=inline

iac/cal-itp-data-infra-staging/iam/us/outputs.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,18 @@ output "google_service_account_cal-bc-service-account_name" {
178178
value = google_service_account.cal-bc-service-account.name
179179
}
180180

181+
output "google_service_account_metabase-service-account_id" {
182+
value = google_service_account.metabase-service-account.id
183+
}
184+
185+
output "google_service_account_metabase-service-account_email" {
186+
value = google_service_account.metabase-service-account.email
187+
}
188+
189+
output "google_service_account_metabase-service-account_name" {
190+
value = google_service_account.metabase-service-account.name
191+
}
192+
181193
output "google_service_account_composer-service-account_id" {
182194
value = google_service_account.composer-service-account.id
183195
}

iac/cal-itp-data-infra-staging/iam/us/project_iam_member.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,16 @@ resource "google_project_iam_member" "cal-bc-service-account" {
279279
project = "cal-itp-data-infra-staging"
280280
}
281281

282+
resource "google_project_iam_member" "metabase-service-account" {
283+
for_each = toset([
284+
"roles/cloudsql.client",
285+
"roles/secretmanager.secretAccessor",
286+
])
287+
role = each.key
288+
member = "serviceAccount:${google_service_account.metabase-service-account.email}"
289+
project = "cal-itp-data-infra-staging"
290+
}
291+
282292
resource "google_project_iam_member" "composer-service-account" {
283293
for_each = toset([
284294
"roles/bigquery.dataOwner",

iac/cal-itp-data-infra-staging/iam/us/service_account.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ resource "google_service_account" "cal-bc-service-account" {
5050
project = "cal-itp-data-infra-staging"
5151
}
5252

53+
resource "google_service_account" "metabase-service-account" {
54+
account_id = "metabase-service-account"
55+
description = "Service account for Metabase"
56+
disabled = "false"
57+
display_name = "metabase"
58+
project = "cal-itp-data-infra-staging"
59+
}
60+
5361
resource "google_service_account" "composer-service-account" {
5462
account_id = "composer-service-account"
5563
description = "Service account for Composer"

iac/cal-itp-data-infra-staging/metabase/us/.terraform.lock.hcl

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
resource "google_compute_global_address" "metabase-staging" {
2+
name = "metabase-staging-address"
3+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
provider "google" {
2+
project = "cal-itp-data-infra-staging"
3+
}
4+
5+
terraform {
6+
required_providers {
7+
google = {
8+
version = "~> 7.10.0"
9+
}
10+
}
11+
12+
backend "gcs" {
13+
bucket = "calitp-staging-gcp-components-tfstate"
14+
prefix = "cal-itp-data-infra-staging/metabase"
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
resource "google_artifact_registry_repository" "ghcr" {
2+
location = "us-west2"
3+
repository_id = "ghcr"
4+
format = "DOCKER"
5+
mode = "REMOTE_REPOSITORY"
6+
cleanup_policy_dry_run = true
7+
8+
remote_repository_config {
9+
description = "GitHub Container Repository"
10+
docker_repository {
11+
custom_repository {
12+
uri = "https://ghcr.io"
13+
}
14+
}
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
resource "google_secret_manager_secret" "metabase-staging-password" {
2+
secret_id = "metabase-staging-password"
3+
replication {
4+
user_managed {
5+
replicas {
6+
location = "us-west2"
7+
}
8+
}
9+
}
10+
}
11+
12+
resource "google_secret_manager_secret_version" "metabase-staging-password" {
13+
secret = google_secret_manager_secret.metabase-staging-password.name
14+
secret_data_wo = random_password.metabase-staging-database.result
15+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
resource "google_cloud_run_v2_service" "metabase-staging" {
2+
name = "metabase-staging"
3+
location = "us-west2"
4+
deletion_protection = false
5+
ingress = "INGRESS_TRAFFIC_ALL"
6+
invoker_iam_disabled = true
7+
8+
traffic {
9+
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
10+
percent = 100
11+
}
12+
13+
scaling {
14+
min_instance_count = 1
15+
}
16+
17+
template {
18+
service_account = data.terraform_remote_state.iam.outputs.google_service_account_metabase-service-account_email
19+
20+
volumes {
21+
name = "cloudsql"
22+
cloud_sql_instance {
23+
instances = [google_sql_database_instance.metabase-staging.connection_name]
24+
}
25+
}
26+
27+
containers {
28+
image = "us-west2-docker.pkg.dev/cal-itp-data-infra-staging/ghcr/cal-itp/data-infra/metabase:latest"
29+
30+
resources {
31+
limits = {
32+
cpu = "1"
33+
memory = "2048Mi"
34+
}
35+
}
36+
37+
ports {
38+
container_port = 3000
39+
}
40+
41+
startup_probe {
42+
timeout_seconds = 2
43+
period_seconds = 5
44+
failure_threshold = 10
45+
initial_delay_seconds = 60
46+
47+
http_get {
48+
path = "/"
49+
port = 3000
50+
}
51+
}
52+
53+
liveness_probe {
54+
http_get {
55+
path = "/"
56+
port = 3000
57+
}
58+
}
59+
60+
volume_mounts {
61+
name = "cloudsql"
62+
mount_path = "/cloudsql"
63+
}
64+
65+
env {
66+
name = "MB_DB_TYPE"
67+
value = "postgres"
68+
}
69+
70+
env {
71+
name = "MB_DB_DBNAME"
72+
value = google_sql_database.metabase-staging.name
73+
}
74+
75+
env {
76+
name = "MB_DB_HOST"
77+
value = "127.0.0.1"
78+
}
79+
80+
env {
81+
name = "MB_DB_USER"
82+
value = google_sql_user.metabase-staging.name
83+
}
84+
85+
env {
86+
name = "MB_DB_PASS"
87+
value_source {
88+
secret_key_ref {
89+
secret = google_secret_manager_secret.metabase-staging-password.secret_id
90+
version = "latest"
91+
}
92+
}
93+
}
94+
95+
env {
96+
name = "JAVA_OPTS"
97+
value = "-Xmx2048m"
98+
}
99+
}
100+
}
101+
}
102+
103+
resource "google_cloud_run_service_iam_binding" "metabase-staging" {
104+
location = google_cloud_run_v2_service.metabase-staging.location
105+
service = google_cloud_run_v2_service.metabase-staging.name
106+
role = "roles/run.invoker"
107+
members = ["allUsers"]
108+
}
109+
110+
resource "google_compute_region_network_endpoint_group" "metabase-staging" {
111+
name = "metabase-staging"
112+
network_endpoint_type = "SERVERLESS"
113+
region = google_cloud_run_v2_service.metabase-staging.location
114+
cloud_run {
115+
service = google_cloud_run_v2_service.metabase-staging.name
116+
}
117+
}
118+
119+
module "lb-http" {
120+
source = "GoogleCloudPlatform/lb-http/google//modules/serverless_negs"
121+
version = "~> 14.0"
122+
123+
name = "metabase-staging"
124+
project = "cal-itp-data-infra-staging"
125+
126+
ssl = true
127+
managed_ssl_certificate_domains = [local.domain]
128+
https_redirect = true
129+
130+
address = google_compute_global_address.metabase-staging.address
131+
create_address = false
132+
133+
backends = {
134+
metabase = {
135+
groups = []
136+
serverless_neg_backends = [
137+
{
138+
"region" : "us-west2",
139+
"type" : "cloud-run",
140+
"service" : {
141+
"name" : google_cloud_run_v2_service.metabase-staging.name
142+
}
143+
}
144+
]
145+
146+
health_check = {
147+
request_path = "/"
148+
protocol = "HTTP"
149+
port = 80
150+
}
151+
152+
enable_cdn = false
153+
154+
iap_config = {
155+
enable = false
156+
}
157+
158+
log_config = {
159+
enable = false
160+
}
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)