mirror of https://github.com/snachodog/mybuddy.git
Add CGP Cloud Run deployment documentation
* Add docs for gcp cloud run * terraform gcp cloud run * Edit GCP Clound Run documentation for clarity --------- Co-authored-by: Christopher Charbonneau Wells <10456740+cdubz@users.noreply.github.com>
This commit is contained in:
parent
9d3501d366
commit
d053050ed5
|
@ -89,6 +89,27 @@ for your instance of babybuddy.
|
|||
After that, you just have to push babybuddy code repository to the Git
|
||||
deployment URL of your Clever Cloud Python application.
|
||||
|
||||
## GCP Cloud Run
|
||||
|
||||
Baby Buddy can be hosted serverless in GCP Cloud Run using configuration provided at
|
||||
`terraform/gcp-cloud-run`. The configuration scales down to zero for cost effectiveness.
|
||||
With this approach initial requests to the service after a long period will be slow but
|
||||
subsequent requests will be much faster. A [billing account](https://cloud.google.com/billing/docs/how-to/create-billing-account)
|
||||
mut be configured in GCP to use the configuration.
|
||||
|
||||
The terraform code isn't production ready and is meant to be a good way of getting started.
|
||||
No state strage is configured. See [storage options](https://cloud.google.com/run/docs/storage-options)
|
||||
for information about how to configure persistant storage.
|
||||
|
||||
Run `terraform init` from the configurtion directory to get started:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/babybuddy/babybuddy.git
|
||||
cd babybuddy/terraform/gcp-cloud-run
|
||||
terraform init
|
||||
terraform apply -var project_id=<project-id> -var project_name=<project-name> -var billing_account=<billing-account-id>
|
||||
```
|
||||
|
||||
## Manual
|
||||
|
||||
There are many ways to deploy Baby Buddy manually to any server/VPS. The basic
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/google" {
|
||||
version = "5.6.0"
|
||||
hashes = [
|
||||
"h1:eZMUVtLYrZMNb5QeqWpWfeQv5wNWQMRhzVtr/Fo5Wis=",
|
||||
"zh:102b6a2672fade82114eb14ed46923fb1b74be2aaca3a50b4f35f7057a9a94b9",
|
||||
"zh:1a56b63175068c67efbe7d130986ba2839a938f5ffc96a14fd450153174dbfa3",
|
||||
"zh:1ba1c5e0c86e8aaa8037406390846e78c89b63faf9e527c7874641f35d436e1b",
|
||||
"zh:3f7161b9288b47cbe89d2f9675f78d83b58ad5880c793b01f50a71ee2583844b",
|
||||
"zh:66912d6e4180dac37185d17424b345a9d4e3c3c791d45e0737b35e32c9536b35",
|
||||
"zh:6f06f56e9fac2e55b50e74ffac42d9522bb379394e51dca1eddd4c3b7a68545c",
|
||||
"zh:8741861ebfa13bb1ed74ea7f4865388a0725ca3a781b6d873ce45e6a4630fe41",
|
||||
"zh:ae89a9c538665fbc30bb83aa3b13acb18d8380e551ccf242e1c0ab4d626089ab",
|
||||
"zh:c510f8321c7599aa601b1870fdc0c76cbad3054ed5cc70fe8e37a13a8046a71f",
|
||||
"zh:cf143a53d5a25c6216d09a9c0b115bb473ffcebd5c4c62b2b2594b1ebc13e662",
|
||||
"zh:de05b957e5dfdbaf92db47cd9b3ef46a0f8d94599eea6d472928f33058856add",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/random" {
|
||||
version = "3.5.1"
|
||||
hashes = [
|
||||
"h1:VSnd9ZIPyfKHOObuQCaKfnjIHRtR7qTw19Rz8tJxm+k=",
|
||||
"zh:04e3fbd610cb52c1017d282531364b9c53ef72b6bc533acb2a90671957324a64",
|
||||
"zh:119197103301ebaf7efb91df8f0b6e0dd31e6ff943d231af35ee1831c599188d",
|
||||
"zh:4d2b219d09abf3b1bb4df93d399ed156cadd61f44ad3baf5cf2954df2fba0831",
|
||||
"zh:6130bdde527587bbe2dcaa7150363e96dbc5250ea20154176d82bc69df5d4ce3",
|
||||
"zh:6cc326cd4000f724d3086ee05587e7710f032f94fc9af35e96a386a1c6f2214f",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:b6d88e1d28cf2dfa24e9fdcc3efc77adcdc1c3c3b5c7ce503a423efbdd6de57b",
|
||||
"zh:ba74c592622ecbcef9dc2a4d81ed321c4e44cddf7da799faa324da9bf52a22b2",
|
||||
"zh:c7c5cde98fe4ef1143bd1b3ec5dc04baf0d4cc3ca2c5c7d40d17c0e9b2076865",
|
||||
"zh:dac4bad52c940cd0dfc27893507c1e92393846b024c5a9db159a93c534a3da03",
|
||||
"zh:de8febe2a2acd9ac454b844a4106ed295ae9520ef54dc8ed2faf29f12716b602",
|
||||
"zh:eab0d0495e7e711cca367f7d4df6e322e6c562fc52151ec931176115b83ed014",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
provider "google" {
|
||||
region = var.region
|
||||
}
|
||||
|
||||
resource "google_project" "baby_buddy" {
|
||||
name = var.project_name
|
||||
project_id = var.project_id
|
||||
billing_account = var.billing_account
|
||||
auto_create_network = false
|
||||
}
|
||||
|
||||
locals {
|
||||
services = toset(["run.googleapis.com",
|
||||
"sqladmin.googleapis.com",
|
||||
"sql-component.googleapis.com",
|
||||
"secretmanager.googleapis.com"
|
||||
])
|
||||
}
|
||||
|
||||
resource "google_project_service" "project_services" {
|
||||
for_each = local.services
|
||||
project = google_project.baby_buddy.project_id
|
||||
service = each.value
|
||||
disable_on_destroy = true
|
||||
disable_dependent_services = true
|
||||
}
|
||||
|
||||
resource "random_password" "root_password" {
|
||||
min_lower = 1
|
||||
min_numeric = 1
|
||||
min_upper = 1
|
||||
length = 19
|
||||
special = true
|
||||
min_special = 1
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
min_lower, min_upper, min_numeric, special, min_special, length
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "random_password" "django_secret_key" {
|
||||
min_lower = 1
|
||||
min_numeric = 1
|
||||
min_upper = 1
|
||||
length = 20
|
||||
special = true
|
||||
min_special = 1
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
min_lower, min_upper, min_numeric, special, min_special, length
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_sql_database_instance" "baby_buddy" {
|
||||
name = "babybuddy"
|
||||
database_version = "POSTGRES_15"
|
||||
root_password = random_password.root_password.result
|
||||
settings {
|
||||
tier = "db-f1-micro"
|
||||
disk_autoresize = false
|
||||
deletion_protection_enabled = false
|
||||
insights_config {
|
||||
query_insights_enabled = false
|
||||
}
|
||||
maintenance_window {
|
||||
day = 1
|
||||
hour = 0
|
||||
}
|
||||
}
|
||||
|
||||
deletion_protection = "true"
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "postgres_password" {
|
||||
secret_id = "postgres-password"
|
||||
project = google_project.baby_buddy.project_id
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "postgres_password" {
|
||||
secret = google_secret_manager_secret.postgres_password.name
|
||||
secret_data = google_sql_database_instance.baby_buddy.root_password
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_iam_member" "postgres_password" {
|
||||
secret_id = google_secret_manager_secret.postgres_password.id
|
||||
role = "roles/secretmanager.secretAccessor"
|
||||
member = "serviceAccount:${google_project.baby_buddy.number}-compute@developer.gserviceaccount.com"
|
||||
depends_on = [google_secret_manager_secret.postgres_password]
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "django_secret_key" {
|
||||
secret_id = "django-secret-key"
|
||||
project = google_project.baby_buddy.project_id
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "django_secret_key" {
|
||||
secret = google_secret_manager_secret.django_secret_key.name
|
||||
secret_data = random_password.django_secret_key.result
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_iam_member" "django_secret_key" {
|
||||
secret_id = google_secret_manager_secret.django_secret_key.name
|
||||
role = "roles/secretmanager.secretAccessor"
|
||||
member = "serviceAccount:${google_project.baby_buddy.number}-compute@developer.gserviceaccount.com"
|
||||
depends_on = [google_secret_manager_secret.django_secret_key]
|
||||
}
|
||||
|
||||
resource "google_cloud_run_v2_service" "baby_buddy" {
|
||||
name = "babybuddy"
|
||||
location = var.region
|
||||
ingress = "INGRESS_TRAFFIC_ALL"
|
||||
project = google_project.baby_buddy.project_id
|
||||
|
||||
template {
|
||||
scaling {
|
||||
max_instance_count = 2
|
||||
}
|
||||
|
||||
volumes {
|
||||
name = "cloudsql"
|
||||
cloud_sql_instance {
|
||||
instances = [google_sql_database_instance.baby_buddy.connection_name]
|
||||
}
|
||||
}
|
||||
|
||||
containers {
|
||||
name = "babybuddy-1"
|
||||
image = "docker.io/linuxserver/babybuddy:latest"
|
||||
|
||||
env {
|
||||
name = "DB_HOST"
|
||||
value = "/cloudsql/${google_project.baby_buddy.project_id}:${var.region}:${google_sql_database_instance.baby_buddy.name}"
|
||||
}
|
||||
env {
|
||||
name = "DB_USER"
|
||||
value = "postgres"
|
||||
}
|
||||
env {
|
||||
name = "DB_NAME"
|
||||
value = "postgres"
|
||||
}
|
||||
env {
|
||||
name = "DB_ENGINE"
|
||||
value = "django.db.backends.postgresql"
|
||||
}
|
||||
env {
|
||||
name = "DB_PASSWORD"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = google_secret_manager_secret.postgres_password.secret_id
|
||||
version = google_secret_manager_secret_version.postgres_password.version
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "SECRET_KEY"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = google_secret_manager_secret.django_secret_key.secret_id
|
||||
version = google_secret_manager_secret_version.django_secret_key.version
|
||||
}
|
||||
}
|
||||
}
|
||||
volume_mounts {
|
||||
name = "cloudsql"
|
||||
mount_path = "/cloudsql"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
annotations = {
|
||||
"foo" = "bar"
|
||||
}
|
||||
traffic {
|
||||
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
|
||||
percent = 100
|
||||
}
|
||||
depends_on = [google_secret_manager_secret_version.postgres_password, google_secret_manager_secret_version.django_secret_key]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
output "url" {
|
||||
value = google_cloud_run_v2_service.baby_buddy.uri
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
variable "project_name" {
|
||||
description = "project name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "project id, remember the project id has to be unique"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "billing_account" {
|
||||
description = "value of the billing account id"
|
||||
type = string
|
||||
|
||||
}
|
||||
variable "region" {
|
||||
description = "which region to deploy to"
|
||||
type = string
|
||||
default = "europe-north1"
|
||||
}
|
Loading…
Reference in New Issue