Skip to content

Commit 6933156

Browse files
author
James Belchamber
authored
Turning GCP Terraform/Tofu into a module (#2)
Also adding pre-commit and a devcontainer
1 parent 2e485aa commit 6933156

File tree

16 files changed

+260
-227
lines changed

16 files changed

+260
-227
lines changed

.devcontainer/Dockerfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Dockerfile
2+
FROM docker.io/golang:latest
3+
4+
RUN apt-get update &&\
5+
apt-get upgrade -y &&\
6+
apt-get install -y apt-transport-https ca-certificates curl wget gnupg &&\
7+
apt-get clean
8+
9+
RUN install -m 0755 -d /etc/apt/keyrings &&\
10+
curl -fsSL https://get.opentofu.org/opentofu.gpg | tee /etc/apt/keyrings/opentofu.gpg >/dev/null &&\
11+
curl -fsSL https://packages.opentofu.org/opentofu/tofu/gpgkey | gpg --no-tty --batch --dearmor -o /etc/apt/keyrings/opentofu-repo.gpg >/dev/null &&\
12+
chmod a+r /etc/apt/keyrings/opentofu.gpg /etc/apt/keyrings/opentofu-repo.gpg &&\
13+
echo "deb [signed-by=/etc/apt/keyrings/opentofu.gpg,/etc/apt/keyrings/opentofu-repo.gpg] https://packages.opentofu.org/opentofu/tofu/any/ any main" | tee /etc/apt/sources.list.d/opentofu.list > /dev/null &&\
14+
chmod a+r /etc/apt/sources.list.d/opentofu.list &&\
15+
apt-get update &&\
16+
apt-get install -y tofu &&\
17+
apt-get clean
18+
19+
RUN mkdir -p /usr/local/bin && apt-get update && apt-get install -y unzip && curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
20+
21+
RUN wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | tee /usr/share/keyrings/trivy.gpg > /dev/null &&\
22+
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | tee -a /etc/apt/sources.list.d/trivy.list &&\
23+
apt-get update &&\
24+
apt-get install -y trivy &&\
25+
apt-get clean

.devcontainer/devcontainer.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "Juicebox Software Realm",
3+
"dockerFile": "Dockerfile",
4+
"features": {
5+
"ghcr.io/devcontainers-extra/features/pre-commit:2": {},
6+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
7+
"ghcr.io/devcontainers/features/common-utils": {
8+
"installZsh": true,
9+
"installOhMyZsh": true,
10+
"installOhMyZshConfig": true,
11+
"configureZshAsDefaultShell": true,
12+
"upgradePackages": true
13+
}
14+
},
15+
"postCreateCommand": "bash .devcontainer/post-create.sh"
16+
}

.devcontainer/post-create.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
# Install pre-commit hooks
4+
pre-commit install

.pre-commit-config.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # v5.0.0
4+
hooks:
5+
- id: end-of-file-fixer
6+
- id: trailing-whitespace
7+
- id: check-case-conflict
8+
- id: check-merge-conflict
9+
- id: detect-private-key
10+
- repo: https://github.com/antonbabenko/pre-commit-terraform
11+
rev: 2f8bda194a420ad77a050a9de627d77a74841fdc # v1.99.4
12+
hooks:
13+
- id: terraform_fmt
14+
- id: terraform_validate
15+
- id: terraform_tflint
16+
- id: terraform_trivy

README.md

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -76,48 +76,26 @@ The realm software will determine which tenant key to validate on a request by a
7676

7777
## GCP
7878

79-
The following instructions will help you quickly deploy a realm to Google's App Engine Flex.
80-
81-
Before you begin, setup a project for your realm to run in on [console.cloud.google.com](https://console.cloud.google.com) and make note of its ID.
82-
83-
Next, setup your project environment with terraform as follows:
84-
```sh
85-
cd gcp
86-
terraform init
87-
terraform plan -var='tenant_secrets={"acme":"acme-tenant-key","anotherTenant":"another-tenant-key"}'
88-
terraform apply -var='tenant_secrets={"acme":"acme-tenant-key","anotherTenant":"another-tenant-key"}'
89-
```
90-
91-
Note: you should update the tenant secrets `var` to reflect the actual secrets you wish to support.
92-
93-
After terraform has finished configuring your project environment, you should see an output like follows:
94-
```sh
95-
BIGTABLE_INSTANCE_ID = "jb-sw-realms"
96-
GCP_PROJECT_ID = "your-project-id"
97-
REALM_ID = "99b2da84-b707-6203-dc35-804bbbcb8cba"
98-
SERVICE_ACCOUNT = "[email protected]"
99-
```
100-
101-
Open the `cmd/jb-sw-realm/app.yaml` file and configure it with these values where appropriate, for example:
102-
Replace `{{YOUR_BIGTABLE_INSTANCE_ID}}` with `jb-sw-realms`.
103-
104-
Finally, you can deploy the realm software by running the following command from the `cmd/jb-sw-realm` directory of the repo:
105-
```sh
106-
gcloud app deploy --project {{YOUR_GCP_PROJECT_ID}}
107-
```
108-
109-
Note: you will need to have the `gcloud` command line tools installed to execute this command. You can find instructions on installing these [here](https://cloud.google.com/sdk/docs/install).
110-
111-
This may take a few minutes, but upon success you should be able to access your realm at:
112-
https://{{YOUR_GCP_PROJECT_ID}}.wl.r.appspot.com
113-
114-
If all was successful, you'll see a page render that looks something like:
115-
```json
116-
{"realmID":"99b2da84-b707-6203-dc35-804bbbcb8cba"}
79+
The `gcp/` directory is now a Terraform module which can be leveraged in your own Terraform codebase. For example:
80+
81+
```terraform
82+
module "juicebox-software-realm" {
83+
source = "github.com/rpcpool/juicebox-software-realm.git//gcp"
84+
85+
project_id = "your-project-id"
86+
realm_id = "99b2da84b7076203dc35804bbbcb8cba"
87+
region = "europe-west3"
88+
zone = "c"
89+
tenant_secrets = {"acme":"acme-tenant-key","anotherTenant":"another-tenant-key"}
90+
juicebox_image_url = "path/to/juicebox/container/image"
91+
juicebox_image_version = "latest"
92+
otelcol_image_url = "path/to/otel/collector/container/image"
93+
otelcol_image_version = "latest"
94+
otelcol_config_b64 = filebase64("otel-collector-config.yaml")
95+
}
11796
```
11897

119-
If you wish to configure a custom domain for your new realm, visit:
120-
https://console.cloud.google.com/appengine/settings/domains
98+
This will deploy an instance of Juicebox Software Realm along with the necessary infrastructure that supports it. Please note that you will either need to deploy the Juicebox and OpenTelemetry Collector containers to a repository in GCP, or else use a remote repository which caches them from GitHub.
12199

122100
## AWS
123101

cmd/jb-sw-realm/app.yaml

Lines changed: 0 additions & 20 deletions
This file was deleted.

gcp/.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ crash.log
1010
crash.*.log
1111

1212
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
13-
# password, private keys, and other secrets. These should not be part of version
14-
# control as they are data points which are potentially sensitive and subject
13+
# password, private keys, and other secrets. These should not be part of version
14+
# control as they are data points which are potentially sensitive and subject
1515
# to change depending on the environment.
1616
*.tfvars
1717
*.tfvars.json
@@ -32,3 +32,6 @@ override.tf.json
3232
# Ignore CLI configuration files
3333
.terraformrc
3434
terraform.rc
35+
36+
# This is a module, so ignore .lock.hcl
37+
.terraform.lock.hcl

gcp/.terraform.lock.hcl

Lines changed: 0 additions & 22 deletions
This file was deleted.

gcp/bigtable.tf

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
resource "google_bigtable_instance" "instance" {
2+
name = "jb-sw-realms"
3+
display_name = "Juicebox Software Realms"
4+
5+
cluster {
6+
cluster_id = "jb-sw-realms-cluster"
7+
zone = "${var.region}-${var.zone}"
8+
autoscaling_config {
9+
min_nodes = 1
10+
max_nodes = 5
11+
cpu_target = 80
12+
}
13+
}
14+
}
15+
16+
resource "google_bigtable_instance_iam_binding" "access" {
17+
instance = google_bigtable_instance.instance.name
18+
role = "roles/bigtable.admin"
19+
20+
members = [
21+
"serviceAccount:${google_service_account.service_account.email}"
22+
]
23+
}

gcp/main.tf

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,4 @@
1-
# Configure the Google Cloud provider
2-
provider "google" {
3-
project = var.project_id
4-
region = var.region
5-
}
6-
7-
# Enable required APIs
8-
resource "google_project_service" "app_engine" {
9-
service = "appengine.googleapis.com"
10-
}
11-
12-
resource "google_project_service" "secrets_manager" {
13-
project = var.project_id
14-
service = "secretmanager.googleapis.com"
15-
}
16-
17-
resource "google_project_service" "pub_sub" {
18-
project = var.project_id
19-
service = "pubsub.googleapis.com"
20-
}
21-
22-
# Create app engine service account
231
resource "google_service_account" "service_account" {
242
account_id = "jb-sw-realms"
253
display_name = "Juicebox Software Realms"
264
}
27-
28-
# Create each tenant secret
29-
resource "google_secret_manager_secret" "secret" {
30-
for_each = var.tenant_secrets
31-
project = var.project_id
32-
secret_id = "jb-sw-tenant-${each.key}"
33-
replication {
34-
automatic = true
35-
}
36-
}
37-
38-
# Add the secret data for each tenant secret
39-
resource "google_secret_manager_secret_version" "secret" {
40-
for_each = var.tenant_secrets
41-
secret = google_secret_manager_secret.secret[each.key].id
42-
secret_data = each.value
43-
}
44-
45-
# Grant access to the app engine for each tenant secret
46-
resource "google_secret_manager_secret_iam_binding" "access" {
47-
for_each = var.tenant_secrets
48-
project = var.project_id
49-
secret_id = google_secret_manager_secret.secret[each.key].id
50-
role = "roles/secretmanager.secretAccessor"
51-
52-
members = [
53-
"serviceAccount:${google_service_account.service_account.email}"
54-
]
55-
}
56-
57-
# Create Bigtable instance
58-
resource "google_bigtable_instance" "instance" {
59-
project = var.project_id
60-
name = "jb-sw-realms"
61-
display_name = "Juicebox Software Realms"
62-
63-
cluster {
64-
cluster_id = "jb-sw-realms-cluster"
65-
zone = var.zone
66-
autoscaling_config {
67-
min_nodes = 1
68-
max_nodes = 5
69-
cpu_target = 80
70-
}
71-
}
72-
}
73-
74-
# Grant access to the app engine for the Bigtable instance
75-
resource "google_bigtable_instance_iam_binding" "access" {
76-
project = var.project_id
77-
instance = google_bigtable_instance.instance.name
78-
role = "roles/bigtable.admin"
79-
80-
members = [
81-
"serviceAccount:${google_service_account.service_account.email}"
82-
]
83-
}
84-
85-
# Create App Engine application
86-
resource "google_app_engine_application" "app" {
87-
project = var.project_id
88-
location_id = var.region
89-
}
90-
91-
# Grant log writer permissions to app engine
92-
resource "google_project_iam_binding" "logs_writer_binding" {
93-
project = var.project_id
94-
role = "roles/logging.logWriter"
95-
members = [
96-
"serviceAccount:${google_service_account.service_account.email}"
97-
]
98-
}
99-
100-
# Grant object reader permissions to app engine so it can access Google Container Registry
101-
resource "google_project_iam_binding" "storage_object_viewer_binding" {
102-
project = var.project_id
103-
role = "roles/storage.objectViewer"
104-
members = [
105-
"serviceAccount:${google_service_account.service_account.email}"
106-
]
107-
}
108-
109-
# Define a custom role with the specific pub/sub perms needed.
110-
resource "google_project_iam_custom_role" "pubsub_role" {
111-
project = var.project_id
112-
role_id = "pubsub_role"
113-
title = "Role for managing pub/sub from a software realm"
114-
description = "Role for managing pub/sub from a software realm"
115-
permissions = ["pubsub.subscriptions.create",
116-
"pubsub.topics.attachSubscription",
117-
"pubsub.topics.create",
118-
"pubsub.topics.publish",
119-
"pubsub.subscriptions.consume",
120-
]
121-
}
122-
123-
# Grant pub/sub access to the service account
124-
resource "google_project_iam_binding" "pubsub_binding" {
125-
project = var.project_id
126-
role = google_project_iam_custom_role.pubsub_role.name
127-
members = [
128-
"serviceAccount:${google_service_account.service_account.email}"
129-
]
130-
}

0 commit comments

Comments
 (0)