Add Terraform infrastructure for Wiki.js deployment

pull/7952/head
lokokun1 2 months ago
parent f0f71536ab
commit a21503253e

@ -0,0 +1,42 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/google" {
version = "5.45.2"
constraints = "~> 5.0"
hashes = [
"h1:A8h5KUdnCeKRf+g0vhCEpPYICOiU0O3+1uybZVl8+tg=",
"zh:0d09c8f20b556305192cdbe0efa6d333ceebba963a8ba91f9f1714b5a20c4b7a",
"zh:117143fc91be407874568df416b938a6896f94cb873f26bba279cedab646a804",
"zh:16ccf77d18dd2c5ef9c0625f9cf546ebdf3213c0a452f432204c69feed55081e",
"zh:3e555cf22a570a4bd247964671f421ed7517970cd9765ceb46f335edc2c6f392",
"zh:688bd5b05a75124da7ae6e885b2b92bd29f4261808b2b78bd5f51f525c1052ca",
"zh:6db3ef37a05010d82900bfffb3261c59a0c247e0692049cb3eb8c2ef16c9d7bf",
"zh:70316fde75f6a15d72749f66d994ccbdde5f5ed4311b6d06b99850f698c9bbf9",
"zh:84b8e583771a4f2bd514e519d98ed7fd28dce5efe0634e973170e1cfb5556fb4",
"zh:9d4b8ef0a9b6677935c604d94495042e68ff5489932cfd1ec41052e094a279d3",
"zh:a2089dd9bd825c107b148dd12d6b286f71aa37dfd4ca9c35157f2dcba7bc19d8",
"zh:f03d795c0fd9721e59839255ee7ba7414173017dc530b4ce566daf3802a0d6dd",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/random" {
version = "3.8.1"
constraints = "~> 3.5"
hashes = [
"h1:osH3aBqEARwOz3VBJKdpFKJJCNIdgRC6k8vPojkLmlY=",
"zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4",
"zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae",
"zh:229665ddf060aa0ed315597908483eee5b818a17d09b6417a0f52fd9405c4f57",
"zh:2469d2e48f28076254a2a3fc327f184914566d9e40c5780b8d96ebf7205f8bc0",
"zh:37d7eb334d9561f335e748280f5535a384a88675af9a9eac439d4cfd663bcb66",
"zh:741101426a2f2c52dee37122f0f4a2f2d6af6d852cb1db634480a86398fa3511",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:a902473f08ef8df62cfe6116bd6c157070a93f66622384300de235a533e9d4a9",
"zh:b85c511a23e57a2147355932b3b6dce2a11e856b941165793a0c3d7578d94d05",
"zh:c5172226d18eaac95b1daac80172287b69d4ce32750c82ad77fa0768be4ea4b8",
"zh:dab4434dba34aad569b0bc243c2d3f3ff86dd7740def373f2a49816bd2ff819b",
"zh:f49fd62aa8c5525a5c17abd51e27ca5e213881d58882fd42fec4a545b53c9699",
]
}

@ -0,0 +1,83 @@
# Wiki.js Deployment on GCP using Terraform
## Overview
This repository contains Infrastructure as Code (Terraform) for deploying Wiki.js on Google Cloud.
The goal of this implementation is to provide a simple, secure, and scalable deployment using managed GCP services.
Main components:
- Cloud Run for running the Wiki.js container
- Cloud SQL (PostgreSQL) as the application database
- Cloud Storage for assets and file storage
- Secret Manager for database credentials
- Cloud Logging and Monitoring for observability
## Architecture
The system is built using managed services to reduce operational overhead.
Users access the Wiki.js application through Cloud Run, which runs the containerized service.
The application connects to a PostgreSQL database hosted on Cloud SQL.
Sensitive data such as database credentials are stored in Secret Manager.
Logs and metrics are automatically collected using Cloud Logging and Cloud Monitoring.
## Security Considerations
- Database credentials are stored in Secret Manager
- Cloud SQL is managed by GCP with automated backups
- Service accounts are used instead of static credentials
- Secrets are injected into the container securely
## Scalability
Cloud Run automatically scales the number of instances based on incoming traffic.
The database tier can be vertically scaled if needed.
Cloud Storage provides virtually unlimited storage capacity.
## Observability
Logs from the application are automatically collected in Cloud Logging.
Metrics from Cloud Run and Cloud SQL are available in Cloud Monitoring and can be used to configure alerts.
## Prerequisites
- Terraform >= 1.5
- gcloud CLI installed
- GCP project with billing enabled
Authenticate with:
gcloud auth application-default login
## Deployment
Initialize Terraform:
terraform init
Validate configuration:
terraform validate
Preview infrastructure changes:
terraform plan -var-file="terraform.tfvars"
Apply infrastructure:
terraform apply -var-file="terraform.tfvars"
## Destroy
To remove all resources:
terraform destroy -var-file="terraform.tfvars"
## Notes
This solution focuses on simplicity and managed services to reduce operational complexity.
Future improvements could include:
- Global Load Balancer
- Cloud Armor for additional security
- Private networking between Cloud Run and Cloud SQL
- Alert policies in Cloud Monitoring

@ -0,0 +1,68 @@
resource "google_cloud_run_v2_service" "wikijs" {
name = "${local.name_prefix}-service"
location = var.region
template {
service_account = google_service_account.wikijs.email
scaling {
min_instance_count = 1
max_instance_count = 5
}
containers {
image = var.container_image
ports {
container_port = 3000
}
env {
name = "DB_TYPE"
value = "postgres"
}
env {
name = "DB_HOST"
value = google_sql_database_instance.postgres.public_ip_address
}
env {
name = "DB_PORT"
value = "5432"
}
env {
name = "DB_NAME"
value = var.db_name
}
env {
name = "DB_USER"
value = var.db_user
}
env {
name = "DB_PASS"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.db_password.secret_id
version = "latest"
}
}
}
}
}
ingress = "INGRESS_TRAFFIC_ALL"
}
resource "google_cloud_run_service_iam_member" "public_access" {
location = google_cloud_run_v2_service.wikijs.location
service = google_cloud_run_v2_service.wikijs.name
role = "roles/run.invoker"
member = "allUsers"
}

@ -0,0 +1,23 @@
Users
|
v
HTTPS Endpoint
|
v
Cloud Run
(Wiki.js App)
|
-----------------------
| |
v v
Cloud SQL Cloud Storage
PostgreSQL Assets / files
|
v
Secret Manager
(DB credentials)
Logs & Metrics
|
v
Cloud Logging / Monitoring

@ -0,0 +1,3 @@
locals {
name_prefix = "wikijs-${var.environment}"
}

@ -0,0 +1,4 @@
resource "google_service_account" "wikijs" {
account_id = "wikijs-service-account"
display_name = "Wiki.js Cloud Run service account"
}

@ -0,0 +1,15 @@
output "cloud_run_url" {
value = google_cloud_run_v2_service.wikijs.uri
}
output "db_instance_name" {
value = google_sql_database_instance.postgres.name
}
output "storage_bucket" {
value = google_storage_bucket.wikijs_assets.name
}
output "service_account_email" {
value = google_service_account.wikijs.email
}

@ -0,0 +1,4 @@
provider "google" {
project = var.project_id
region = var.region
}

@ -0,0 +1,17 @@
resource "random_password" "db_password" {
length = 20
special = true
}
resource "google_secret_manager_secret" "db_password" {
secret_id = "${local.name_prefix}-db-password"
replication {
auto {}
}
}
resource "google_secret_manager_secret_version" "db_password" {
secret = google_secret_manager_secret.db_password.id
secret_data = random_password.db_password.result
}

@ -0,0 +1,32 @@
resource "google_sql_database_instance" "postgres" {
name = "${local.name_prefix}-postgres"
region = var.region
database_version = "POSTGRES_15"
settings {
tier = "db-custom-1-3840"
availability_type = "REGIONAL"
backup_configuration {
enabled = true
}
ip_configuration {
ipv4_enabled = true
}
}
deletion_protection = false
}
resource "google_sql_database" "wikijs" {
name = var.db_name
instance = google_sql_database_instance.postgres.name
}
resource "google_sql_user" "wikijs" {
name = var.db_user
instance = google_sql_database_instance.postgres.name
password = random_password.db_password.result
}

@ -0,0 +1,6 @@
resource "google_storage_bucket" "wikijs_assets" {
name = "${var.project_id}-${local.name_prefix}-assets"
location = var.region
uniform_bucket_level_access = true
force_destroy = true
}

@ -0,0 +1,3 @@
project_id = "example-project"
region = "us-central1"
environment = "dev"

@ -0,0 +1,34 @@
variable "project_id" {
description = "GCP project id"
type = string
}
variable "region" {
description = "Deployment region"
type = string
default = "us-central1"
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
variable "db_name" {
description = "Wiki.js database name"
type = string
default = "wikijs"
}
variable "db_user" {
description = "Database username"
type = string
default = "wikijs"
}
variable "container_image" {
description = "Wiki.js container image"
type = string
default = "ghcr.io/requarks/wiki:2"
}

@ -0,0 +1,15 @@
terraform {
required_version = ">= 1.5.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5"
}
}
}
Loading…
Cancel
Save