Skip to content

Commit

Permalink
gcp: add gce deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
Altonhe committed Jul 2, 2024
1 parent 1a28283 commit e7f4e8d
Show file tree
Hide file tree
Showing 11 changed files with 422 additions and 5 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ This repo is using [Opentofu](https://opentofu.org/) and other tools to create c

| | VM | Docker | K8s |
|-----------------------|-------------|-----------------|--------------|
| Microsoft Azure | VM ✅ | ACI 🔲 | AKS 🔲 |
| Amazon Web Services | EC2 ✅ | ECS 🔲 | EKS 🔲 |
| Google Cloud Platform | GCE 🚧 | GAE 🔲 | GKE 🔲 |
| Microsoft Azure | VM ✅ | ACI 🚧 | AKS 🔲 |
| Amazon Web Services | EC2 ✅ | ECS 🚧 | EKS 🔲 |
| Google Cloud Platform | GCE | GAE 🚧 | GKE 🔲 |
| Render || DOCKER ✅(See 1) ||
| Heroku || HCR 🔲 ||
| DigitalOcean | Droplets 🔲 | CR 🔲 | DOKS 🔲 |
Expand Down
4 changes: 2 additions & 2 deletions modules/aws-ec2/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ resource "null_resource" "remove_ssh_keys" {
always_run = timestamp()
}

# replace `rm` with `del` if you are using Windows
# replace with `del ${path.module}\\ssh\\id_rsa ${path.module}\\ssh\\id_rsa.pub` if you are using Windows
provisioner "local-exec" {
command = "rm ${path.module}\\ssh\\id_rsa ${path.module}\\ssh\\id_rsa.pub"
command = "rm -f ${path.module}/ssh/id_rsa ${path.module}/ssh/id_rsa.pub"
when = destroy
}
}
Expand Down
16 changes: 16 additions & 0 deletions modules/gcp-gce/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
GTFS_URL=https://api.cityofkingston.ca/gtfs/gtfs.zip
TEST_API_KEY=test
VEHICLE_POSITIONS_URL=https://api.cityofkingston.ca/gtfs-realtime/vehicleupdates.pb
TRIP_UPDATES_URL=https://api.cityofkingston.ca/gtfs-realtime/tripupdates.pb
ALERTS_URL=https://api.cityofkingston.ca/gtfs-realtime/alerts.pb
REFRESH_INTERVAL=30
AGENCY_ID=Kingston Transit
TZ=America/Toronto
GOOGLE_MAPS_API_KEY=<YOUR_GOOGLE_MAPS_API_KEY>
GOOGLE_MAPS_CHANNEL_ID=<YOUR_GOOGLE_MAPS_CHANNEL_ID>
GOOGLE_MAPS_CLIENT_ID=<YOUR_GOOGLE_MAPS_CLIENT_ID>
# Your Domain Name, leave blank if you don't have one
DOMAIN=oba.example.com
# OBA image version. You can find the available versions at:
# https://hub.docker.com/r/opentransitsoftwarefoundation/onebusaway-api-webapp/tags
OBA_VERSION=latest
99 changes: 99 additions & 0 deletions modules/gcp-gce/.terraform.lock.hcl

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

15 changes: 15 additions & 0 deletions modules/gcp-gce/docker-compose.caddy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3'

services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- caddy_data:/data
restart: unless-stopped

volumes:
caddy_data: {}
37 changes: 37 additions & 0 deletions modules/gcp-gce/init.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# install Docker Compose
curl -L "https://github.com/docker/compose/releases/download/v2.27.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

cd /home/${user}

# clone repo
git clone https://github.com/onebusaway/onebusaway-docker.git

cd /home/${user}/onebusaway-docker

# create .env file
echo "${docker_env}" > .env


# onebusaway-api-webapp depends on mysql, normally this will handle by docker-compose
# but in Azure, the mysql container will not be ready when onebusaway-api-webapp starts
# which leads to the error `Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set`
# so we need to start mysql container first
docker-compose -f docker-compose.prod.yml up -d oba_database

sleep 5s

# start Docker Compose
docker-compose -f docker-compose.prod.yml up -d

if [ -n "${caddy}" ]; then
# create docker-compose.caddy.yml
echo "${docker_compose}" > docker-compose.caddy.yml
# start Caddy
docker-compose -f docker-compose.caddy.yml up -d
fi
111 changes: 111 additions & 0 deletions modules/gcp-gce/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
provider "google" {
project = var.project_id
region = var.region
}


resource "google_compute_network" "main" {
name = var.network_name
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "main" {
name = var.subnet_name
ip_cidr_range = "10.0.1.0/24"
region = var.region
network = google_compute_network.main.id
}

resource "google_compute_address" "main" {
name = var.public_ip_name
region = var.region
}

resource "google_compute_firewall" "main" {
name = var.firewall_name
network = google_compute_network.main.self_link

allow {
protocol = "tcp"
ports = ["80", "443", "8080", "22"]
}

source_ranges = ["0.0.0.0/0"]
}

resource "tls_private_key" "ssh_key" {
algorithm = "RSA"
rsa_bits = 4096
}

resource "local_sensitive_file" "private_key" {
content = tls_private_key.ssh_key.private_key_pem
filename = "${path.module}/ssh/id_rsa"
}

resource "local_file" "public_key" {
content = tls_private_key.ssh_key.public_key_openssh
filename = "${path.module}/ssh/id_rsa.pub"
}

data "template_file" "main" {
template = file("${path.module}/init.tpl")
vars = {
user = var.admin_username,
caddy = var.caddy,
docker_compose = file("${path.module}/docker-compose.caddy.yml"),
docker_env = file("${path.module}/.env")
}
}

resource "google_compute_instance" "main" {
name = var.vm_name
machine_type = var.machine_type
zone = var.zone

boot_disk {
initialize_params {
image = "projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts"
type = "pd-standard"
}
}

network_interface {
network = google_compute_network.main.id
subnetwork = google_compute_subnetwork.main.id
access_config {
nat_ip = google_compute_address.main.address
}
}

metadata_startup_script = "${data.template_file.main.rendered}"

metadata = {
ssh-keys = "${var.admin_username}:${tls_private_key.ssh_key.public_key_openssh}"
}


service_account {
email = google_service_account.main.email
scopes = ["https://www.googleapis.com/auth/cloud-platform"]
}

tags = ["onebusaway"]
}

resource "google_service_account" "main" {
account_id = "onebusaway-sa"
display_name = "Onebusaway Service Account"
}

resource "null_resource" "remove_ssh_keys" {
triggers = {
always_run = timestamp()
}

# replace with `del ${path.module}\\ssh\\id_rsa ${path.module}\\ssh\\id_rsa.pub` if you are using Windows
provisioner "local-exec" {
command = "rm -f ${path.module}/ssh/id_rsa ${path.module}/ssh/id_rsa.pub"
when = destroy
}
}
9 changes: 9 additions & 0 deletions modules/gcp-gce/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "private_ip_address" {
description = "The private IP address of the instance"
value = google_compute_instance.main.network_interface[0].network_ip
}

output "public_ip_address" {
description = "The public IP address of the instance"
value = google_compute_address.main.address
}
64 changes: 64 additions & 0 deletions modules/gcp-gce/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Deployment Guide for Google Cloud Platform (GCP) Compute Engine

Google Cloud Platform (GCP) Compute Engine is a good choice for deploying the Onebusaway server. It provides a wide range of instance types and sizes, and you can choose the best one for your use case. This guide will show you how to deploy the Onebusaway server on GCP Compute Engine.

## Prerequisites

1. A GCP account, if you don't have one, you can create a free account [here](https://cloud.google.com/free).

2. Google Cloud SDK, you can install it by following the instructions [here](https://cloud.google.com/sdk/docs/install).

3. Opentofu, an open-source Terraform alternative, you can install it by following the instructions [here](https://opentofu.org/docs/intro/install/).

4. Make sure you install *ALL* the prerequisites before you start the deployment.

## Steps

1. Clone this repository to your local machine, you can run
```bash
git clone https://github.com/OneBusAway/onebusaway-deployment.git
```

2. Change the directory to `modules/gcp-gce`, you can use the command
```bash
cd onebusaway-deployment/modules/gcp-gce
```

3. Configure your GCP credentials using the Google Cloud SDK, you can find the guide [here](https://cloud.google.com/docs/authentication/provide-credentials-adc).
```bash
gcloud auth application-default login
```

4. Initialize the project, this will download the necessary plugins and providers for the project
```bash
tofu init
```

5. Create your custom `.env` file by copying the `.env.example` file, you can find parameters meaning in [onebusaway-docker](https://github.com/OneBusAway/onebusaway-docker/)
```bash
cp .env.example .env
```

6. Modify the `.env` and `variables.tf` file according to your needs. You can modify `DOMAIN` to your own domain, this will be used to generate an SSL certificate by [Caddy](https://caddyserver.com/). If you want to configure your own certs instead of automatic HTTPS, you can leave `caddy` blank. You should also check the `main.tf` file to make sure it works with your OS.

7. Deploy the project
```bash
tofu apply
```

8. Tofu will automatically generate SSH key pairs in the `ssh` folder, you can connect to the server using `ssh -i ./ssh/id_rsa <username>@<instance_ip>`.

9. After the deployment is finished, you need to wait a few minutes to let the server start. You can access the Onebusaway server by visiting `http://<instance_ip>:8080`. You can find the instance IP in the GCP Management Console.

10. (optional) If you configured your own domain, you should go to your domain provider and add an A record pointing to the instance IP. For example, if you use Cloudflare, you can follow the instructions [here](https://support.cloudflare.com/hc/en-us/articles/360019093151-Managing-DNS-records-in-Cloudflare). Caddy will configure certs based on the record. You should be able to visit your server by visiting `https://<your_domain>` after a few minutes.

## Clean up
If you want to shut down the server and clean up the resources, you can run the following command
```bash
tofu destroy
```

Opentofu will destroy all resources created by this project, including the Compute Engine instance, network, SSH key pairs, and other resources.

## Conclusion
This guide shows you how to deploy the Onebusaway server on GCP Compute Engine using Opentofu. If you have any questions or suggestions, feel free to open an issue in this repository.
Empty file added modules/gcp-gce/ssh/.gitkeep
Empty file.
Loading

0 comments on commit e7f4e8d

Please sign in to comment.