Skip to content

Commit 43dbbbe

Browse files
authored
Add Cloud Run for GCP CI env (#56)
* Add Cloud Run for GCP CI env * Add .terraform.lock.hcl * Build conformance Docker image on top of base image * Fix circular dependency on stage in Dockerfile * Add `roles/monitoring.metricWriter` to Cloud Run service account * Add missing configure-docker command * Remove leading slash in path * Replace us-central1 with ${GOOGLE_REGION} * Add `unset TESSERA_BASE_NAME` * Update to `GCP SCTFE Test Environment` in README * Add `env` to GCS bucket labels * Update the Cloud Run resources limit to align with the measurement unit
1 parent 98b495a commit 43dbbbe

File tree

18 files changed

+422
-31
lines changed

18 files changed

+422
-31
lines changed

cmd/gcp/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ RUN go build -o bin/sctfe-gcp ./cmd/gcp
2121
FROM alpine:3.20.2@sha256:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5
2222

2323
COPY --from=builder /build/bin/sctfe-gcp /bin/sctfe-gcp
24+
2425
ENTRYPOINT ["/bin/sctfe-gcp"]

cmd/gcp/ci/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM sctfe-gcp:latest AS base
2+
3+
# Build release image
4+
FROM alpine:3.20.2@sha256:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5
5+
6+
# Copy the fake CA certificate into the container
7+
COPY ./testdata/fake-ca.cert /bin/
8+
9+
# Copy the sctfe-gcp binary
10+
COPY --from=base /bin/sctfe-gcp /bin/
11+
12+
ENTRYPOINT ["/bin/sctfe-gcp"]

deployment/live/gcp/ci/.terraform.lock.hcl

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deployment/live/gcp/ci/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# GCP SCTFE CI Environment
2+
3+
## Overview
4+
5+
This config uses the [gcp/conformance](/deployment/modules/gcp/conformance) module to
6+
define a CI environment to run the SCTFE, backed by Trillian Tessera.
7+
8+
At a high level, this environment consists of:
9+
- One Spanner instance with two databases:
10+
- one for Tessera
11+
- one for deduplication
12+
- A GCS Bucket
13+
- Secret Manager
14+
- Cloud Run
15+
16+
### Manual Deployment
17+
18+
First authenticate via `gcloud` as a principle with sufficient ACLs for
19+
the project:
20+
21+
```sh
22+
gcloud auth application-default login
23+
```
24+
25+
Set the required environment variables:
26+
27+
```sh
28+
export GOOGLE_PROJECT={VALUE}
29+
export GOOGLE_REGION={VALUE} # e.g: us-central1
30+
unset TESSERA_BASE_NAME
31+
```
32+
33+
TODO: Add the Artifact Registry which is in the Cloud Build pull request. The expected repository is `${GOOGLE_REGION}-docker.pkg.dev/${GOOGLE_PROJECT}/docker-ci`.
34+
35+
Build and push the Docker image to Artifact Registry repository:
36+
37+
```sh
38+
gcloud auth configure-docker ${GOOGLE_REGION}-docker.pkg.dev
39+
docker build -f ./cmd/gcp/Dockerfile -t sctfe-gcp:latest .
40+
docker build -f ./cmd/gcp/ci/Dockerfile -t conformance-gcp:latest .
41+
docker tag conformance-gcp:latest ${GOOGLE_REGION}-docker.pkg.dev/${GOOGLE_PROJECT}/docker-ci/conformance-gcp:latest
42+
docker push ${GOOGLE_REGION}-docker.pkg.dev/${GOOGLE_PROJECT}/docker-ci/conformance-gcp
43+
```
44+
45+
Terraforming the project can be done by:
46+
1. `cd` to the relevant directory (deployment/live/gcp/ci/) for the environment to deploy/change.
47+
2. Run `terragrunt apply`.
48+

deployment/live/gcp/ci/terragrunt.hcl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
terraform {
2+
source = "${get_repo_root()}/deployment/modules/gcp//conformance"
3+
}
4+
5+
locals {
6+
env = "ci"
7+
base_name = "${local.env}-conformance"
8+
server_docker_image = "us-central1-docker.pkg.dev/${include.root.locals.project_id}/docker-${local.env}/conformance-gcp:latest"
9+
}
10+
11+
include "root" {
12+
path = find_in_parent_folders()
13+
expose = true
14+
}
15+
16+
inputs = merge(
17+
local,
18+
include.root.locals,
19+
)

deployment/live/gcp/terragrunt.hcl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
locals {
2+
env = path_relative_to_include()
3+
project_id = get_env("GOOGLE_PROJECT", "phboneff-dev")
4+
location = get_env("GOOGLE_REGION", "us-central1")
5+
base_name = get_env("TESSERA_BASE_NAME", "${local.env}-static-ct")
6+
}
7+
8+
remote_state {
9+
backend = "gcs"
10+
11+
config = {
12+
project = local.project_id
13+
location = local.location
14+
bucket = "${local.project_id}-${local.base_name}-terraform-state"
15+
prefix = "terraform.tfstate"
16+
17+
gcs_bucket_labels = {
18+
name = "terraform_state"
19+
env = "${local.env}"
20+
}
21+
}
22+
}

deployment/live/gcp/test/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# GCP SCTFE Configs
1+
# GCP SCTFE Test Environment
22

33
## Prerequisites
44
You'll need to have a VM running in the same GCP project that you can SSH to,
@@ -8,14 +8,15 @@ installed, and your favourite terminal multiplexer.
88

99
## Overview
1010

11-
This config uses the [gcp/storage](/deployment/modules/gcp/conformance) module to
11+
This config uses the [gcp/test](/deployment/modules/gcp/test) module to
1212
define a test environment to run the SCTFE, backed by Trillian Tessera.
1313

1414
At a high level, this environment consists of:
1515
- One Spanner instance with two databases:
1616
- one for Tessera
1717
- one for deduplication
1818
- A GCS Bucket
19+
- Secret Manager
1920

2021
## Manual deployment
2122

@@ -31,12 +32,12 @@ Set the required environment variables:
3132
```bash
3233
export GOOGLE_PROJECT={VALUE}
3334
export GOOGLE_REGION={VALUE} # e.g: us-central1
34-
export TESSERA_BASE_NAME={VALUE} # e.g: staticct
35+
export TESSERA_BASE_NAME={VALUE} # e.g: test-static-ct
3536
```
3637

3738
Terraforming the project can be done by:
38-
1. `cd` to the relevant directory for the environment to deploy/change (e.g. `ci`)
39-
2. Run `terragrunt apply`
39+
1. `cd` to the relevant directory for the environment to deploy/change (e.g. `ci`)
40+
2. Run `terragrunt apply`
4041

4142
Store the Secret Manager resource ID of signer key pair into the environment variables:
4243

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
terraform {
2-
source = "${get_repo_root()}/deployment/modules/gcp//conformance"
2+
source = "${get_repo_root()}/deployment/modules/gcp//test"
33
}
44

55
locals {
6-
project_id = get_env("GOOGLE_PROJECT", "phboneff-dev")
7-
location = get_env("GOOGLE_REGION", "us-central1")
8-
base_name = get_env("TESSERA_BASE_NAME", "tessera-staticct")
6+
env = "test"
7+
base_name = get_env("TESSERA_BASE_NAME", "${local.env}-static-ct")
98
}
109

11-
inputs = local
12-
13-
remote_state {
14-
backend = "gcs"
15-
16-
config = {
17-
project = local.project_id
18-
location = local.location
19-
bucket = "${local.project_id}-${local.base_name}-terraform-state"
20-
prefix = "terraform.tfstate"
21-
22-
gcs_bucket_labels = {
23-
name = "terraform_state_conformance"
24-
}
25-
}
10+
include "root" {
11+
path = find_in_parent_folders()
12+
expose = true
2613
}
14+
15+
inputs = merge(
16+
local,
17+
include.root.locals,
18+
)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
terraform {
2+
required_providers {
3+
google = {
4+
source = "registry.terraform.io/hashicorp/google"
5+
version = "6.1.0"
6+
}
7+
}
8+
}
9+
10+
# Cloud Run
11+
12+
resource "google_project_service" "cloudrun_api" {
13+
service = "run.googleapis.com"
14+
disable_on_destroy = false
15+
}
16+
17+
resource "google_service_account" "cloudrun_service_account" {
18+
account_id = "cloudrun-${var.env}-sa"
19+
display_name = "Service Account for Cloud Run (${var.env})"
20+
}
21+
22+
resource "google_project_iam_member" "monitoring_metric_writer" {
23+
project = var.project_id
24+
role = "roles/monitoring.metricWriter"
25+
member = "serviceAccount:${google_service_account.cloudrun_service_account.email}"
26+
}
27+
28+
resource "google_storage_bucket_iam_member" "member" {
29+
bucket = var.bucket
30+
role = "roles/storage.objectUser"
31+
member = "serviceAccount:${google_service_account.cloudrun_service_account.email}"
32+
}
33+
34+
resource "google_project_iam_member" "iam_secret_accessor" {
35+
project = var.project_id
36+
role = "roles/secretmanager.secretAccessor"
37+
member = "serviceAccount:${google_service_account.cloudrun_service_account.email}"
38+
}
39+
40+
resource "google_spanner_database_iam_member" "iam_log_spanner_database_user" {
41+
instance = var.log_spanner_instance
42+
database = var.log_spanner_db
43+
role = "roles/spanner.databaseUser"
44+
member = "serviceAccount:${google_service_account.cloudrun_service_account.email}"
45+
}
46+
47+
resource "google_spanner_database_iam_member" "iam_dedup_spanner_database_user" {
48+
instance = var.log_spanner_instance
49+
database = var.dedup_spanner_db
50+
role = "roles/spanner.databaseUser"
51+
member = "serviceAccount:${google_service_account.cloudrun_service_account.email}"
52+
}
53+
54+
locals {
55+
spanner_log_db_path = "projects/${var.project_id}/instances/${var.log_spanner_instance}/databases/${var.log_spanner_db}"
56+
spanner_dedup_db_path = "projects/${var.project_id}/instances/${var.log_spanner_instance}/databases/${var.dedup_spanner_db}"
57+
}
58+
59+
resource "google_cloud_run_v2_service" "default" {
60+
name = var.base_name
61+
location = var.location
62+
launch_stage = "GA"
63+
64+
template {
65+
service_account = google_service_account.cloudrun_service_account.account_id
66+
max_instance_request_concurrency = 700
67+
timeout = "5s"
68+
69+
scaling {
70+
max_instance_count = 3
71+
}
72+
73+
containers {
74+
image = var.server_docker_image
75+
name = "conformance"
76+
args = [
77+
"--logtostderr",
78+
"--v=1",
79+
"--http_endpoint=:6962",
80+
"--project_id=${var.project_id}",
81+
"--bucket=${var.bucket}",
82+
"--spanner_db_path=${local.spanner_log_db_path}",
83+
"--spanner_dedup_db_path=${local.spanner_dedup_db_path}",
84+
"--roots_pem_file=/bin/fake-ca.cert",
85+
"--origin=${var.base_name}",
86+
"--signer_public_key_secret_name=${var.signer_public_key_secret_name}",
87+
"--signer_private_key_secret_name=${var.signer_private_key_secret_name}",
88+
]
89+
ports {
90+
container_port = 6962
91+
}
92+
93+
resources {
94+
limits = {
95+
cpu = "2000m"
96+
memory = "1Gi"
97+
}
98+
}
99+
100+
startup_probe {
101+
initial_delay_seconds = 1
102+
timeout_seconds = 1
103+
period_seconds = 10
104+
failure_threshold = 6
105+
tcp_socket {
106+
port = 6962
107+
}
108+
}
109+
}
110+
}
111+
112+
deletion_protection = false
113+
114+
client = "terraform"
115+
116+
depends_on = [
117+
google_project_service.cloudrun_api,
118+
]
119+
}

0 commit comments

Comments
 (0)