From 15af72c1ed0f349ff14103573869d38d8200c750 Mon Sep 17 00:00:00 2001 From: hajjimo Date: Mon, 28 Jul 2025 14:08:38 +0200 Subject: [PATCH 1/6] docs: mi/3419/rafiki-testnet-deploy --- packages/documentation/astro.config.mjs | 14 + .../gcp-prerequisites-guide.mdx | 882 ++++++++++++++ .../rafiki-deployment-testnet.mdx | 1017 +++++++++++++++++ 3 files changed, 1913 insertions(+) create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx diff --git a/packages/documentation/astro.config.mjs b/packages/documentation/astro.config.mjs index 7df97340dc..6ed5903e71 100644 --- a/packages/documentation/astro.config.mjs +++ b/packages/documentation/astro.config.mjs @@ -132,6 +132,20 @@ export default defineConfig({ } ] }, + { + label: 'Rafiki Guide', + collapsed: true, + items: [ + { + label: 'Rafiki TestNet', + link: '/integration/deploy-to-prod/rafiki-deployment-testnet' + }, + { + label: 'GCP prerequisites', + link: '/integration/deploy-to-prod/gcp-prerequisites-guide' + } + ] + }, { label: 'Integration', collapsed: true, diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx new file mode 100644 index 0000000000..fe007735ac --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx @@ -0,0 +1,882 @@ +--- +title: GCP prerequisites +--- + +## Complete Step-by-Step Instructions for Google Cloud Platform Setup + +This guide provides detailed instructions for setting up all Google Cloud Platform prerequisites required for deploying Rafiki with TigerBeetle on Kubernetes. + +## Table of Contents + +1. [Initial GCP Account Setup](#initial-gcp-account-setup) +2. [Project Creation and Configuration](#project-creation-and-configuration) +3. [Billing Setup](#billing-setup) +4. [CLI Tools Installation](#cli-tools-installation) +5. [Service Account Setup](#service-account-setup) +6. [API Enablement](#api-enablement) +7. [IAM Permissions Configuration](#iam-permissions-configuration) +8. [Network Infrastructure Setup](#network-infrastructure-setup) +9. [DNS Setup](#dns-setup) +10. [Security Configuration](#security-configuration) +11. [Verification and Testing](#verification-and-testing) + +## Initial GCP Account Setup + +### Step 1: Create Google Cloud Account + +1. **Visit Google Cloud Console** + ``` + Navigate to: https://console.cloud.google.com + ``` + +2. **Sign in or Create Account** + - If you have a Google account, sign in + - If not, create a new Google account + - Accept Google Cloud Terms of Service + +3. **Activate Free Trial (if eligible)** + - Click "Activate" for the $300 free credit + - Provide payment information (required but won't be charged during trial) + - Complete identity verification + +### Step 2: Verify Account Status + +```bash +# Check if you're logged in correctly +gcloud auth list + +# Should show your account email +``` + +## Project Creation and Configuration + +### Step 1: Create New Project + +1. **Via Google Cloud Console:** + - Go to the project selector dropdown (top of the page) + - Click "New Project" + - Enter project details: + - **Project Name**: `rafiki-production` (or your preferred name) + - **Project ID**: `rafiki-prod-[random-string]` (must be globally unique) + - **Organization**: Select your organization (if applicable) + - Click "Create" + +2. **Via Command Line:** + ```bash + # Set your desired project ID (must be globally unique) + export PROJECT_ID="rafiki-prod-$(date +%s)" + export PROJECT_NAME="Rafiki Production" + + # Create the project + gcloud projects create $PROJECT_ID --name="$PROJECT_NAME" + + # Verify project creation + gcloud projects list --filter="PROJECT_ID:$PROJECT_ID" + ``` + +### Step 2: Set Default Project + +```bash +# Set the project as your default +gcloud config set project $PROJECT_ID + +# Verify the setting +gcloud config get-value project +``` + +### Step 3: Enable Project for Billing + +```bash +# List available billing accounts +gcloud billing accounts list + +# Link project to billing account (replace BILLING_ACCOUNT_ID) +export BILLING_ACCOUNT_ID="your-billing-account-id" +gcloud billing projects link $PROJECT_ID --billing-account=$BILLING_ACCOUNT_ID + +# Verify billing is enabled +gcloud billing projects describe $PROJECT_ID +``` + +## Billing Setup + +### Step 1: Configure Billing Account + +1. **Access Billing Console:** + ``` + Navigate to: https://console.cloud.google.com/billing + ``` + +2. **Create or Select Billing Account:** + - If no billing account exists, click "Create Account" + - Fill in payment details and billing information + - If billing account exists, select it + +3. **Set Billing Alerts:** + ```bash + # Create budget alert at $100/month + gcloud billing budgets create \ + --billing-account=$BILLING_ACCOUNT_ID \ + --display-name="Rafiki Production Budget" \ + --budget-amount=100USD \ + --threshold-rule=percent=50,basis=CURRENT_SPEND \ + --threshold-rule=percent=90,basis=CURRENT_SPEND \ + --threshold-rule=percent=100,basis=CURRENT_SPEND + ``` + +### Step 2: Enable Detailed Billing Export + +```bash +# Create BigQuery dataset for billing export +bq mk --location=US billing_export + +# Configure billing export (replace with your BigQuery dataset) +gcloud billing accounts get-iam-policy $BILLING_ACCOUNT_ID +``` + +## CLI Tools Installation + +### Step 1: Install Google Cloud SDK + +#### For Linux/macOS: +```bash +# Download and install +curl https://sdk.cloud.google.com | bash + +# Restart shell or source profile +exec -l $SHELL + +# Initialize gcloud +gcloud init +``` + +#### For Windows: +1. Download installer from: https://cloud.google.com/sdk/docs/install +2. Run the installer +3. Follow installation prompts +4. Open new Command Prompt/PowerShell +5. Run: `gcloud init` + +### Step 2: Install kubectl + +```bash +# Install kubectl via gcloud +gcloud components install kubectl + +# Verify installation +kubectl version --client +``` + +### Step 3: Install Helm + +#### For Linux/macOS: +```bash +# Download and install Helm +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + +# Verify installation +helm version +``` + +#### For Windows: +```powershell +# Using Chocolatey +choco install kubernetes-helm + +# Or download from: https://github.com/helm/helm/releases +``` + +### Step 4: Install Additional Tools + +```bash +# Install additional gcloud components +gcloud components install gke-gcloud-auth-plugin +gcloud components install beta +gcloud components install alpha + +# Update all components +gcloud components update +``` + +## Service Account Setup + +### Step 1: Create Service Accounts + +```bash +# Create service account for Rafiki application +gcloud iam service-accounts create rafiki-sa \ + --description="Service account for Rafiki application" \ + --display-name="Rafiki Service Account" + +# Create service account for GKE nodes +gcloud iam service-accounts create rafiki-node-sa \ + --description="Service account for GKE nodes" \ + --display-name="Rafiki Node Service Account" + +# Create service account for CI/CD (if needed) +gcloud iam service-accounts create rafiki-cicd-sa \ + --description="Service account for CI/CD pipeline" \ + --display-name="Rafiki CI/CD Service Account" +``` + +### Step 2: Generate Service Account Keys + +```bash +# Create key for Rafiki application service account +gcloud iam service-accounts keys create rafiki-sa-key.json \ + --iam-account=rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com + +# Create key for CI/CD service account (if needed) +gcloud iam service-accounts keys create rafiki-cicd-key.json \ + --iam-account=rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com + +# Secure the keys +chmod 600 *.json +``` + +### Step 3: Set Up Workload Identity (Recommended) + +```bash +# Enable Workload Identity on the project +gcloud container clusters update rafiki-cluster \ + --workload-pool=$PROJECT_ID.svc.id.goog \ + --zone=us-central1-a + +# Create Kubernetes service account +kubectl create serviceaccount rafiki-ksa \ + --namespace=rafiki + +# Bind Kubernetes SA to Google SA +gcloud iam service-accounts add-iam-policy-binding \ + --role roles/iam.workloadIdentityUser \ + --member "serviceAccount:$PROJECT_ID.svc.id.goog[rafiki/rafiki-ksa]" \ + rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com + +# Annotate Kubernetes service account +kubectl annotate serviceaccount rafiki-ksa \ + --namespace=rafiki \ + iam.gke.io/gcp-service-account=rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com +``` + +## API Enablement + +### Step 1: Enable Required APIs + +```bash +# Core APIs for GKE and compute +gcloud services enable container.googleapis.com +gcloud services enable compute.googleapis.com +gcloud services enable containerregistry.googleapis.com +gcloud services enable artifactregistry.googleapis.com + +# Storage and database APIs +gcloud services enable storage.googleapis.com +gcloud services enable sql.googleapis.com +gcloud services enable redis.googleapis.com + +# Networking APIs +gcloud services enable dns.googleapis.com +gcloud services enable networkmanagement.googleapis.com +gcloud services enable servicenetworking.googleapis.com + +# Security and monitoring APIs +gcloud services enable cloudasset.googleapis.com +gcloud services enable cloudresourcemanager.googleapis.com +gcloud services enable monitoring.googleapis.com +gcloud services enable logging.googleapis.com + +# Certificate management +gcloud services enable certificatemanager.googleapis.com +gcloud services enable networkconnectivity.googleapis.com + +# Additional security APIs +gcloud services enable cloudkms.googleapis.com +gcloud services enable secretmanager.googleapis.com +gcloud services enable binaryauthorization.googleapis.com +``` + +### Step 2: Verify API Enablement + +```bash +# List all enabled APIs +gcloud services list --enabled + +# Check specific API status +gcloud services list --enabled --filter="NAME:container.googleapis.com" +``` + +### Step 3: Set API Usage Quotas (if needed) + +```bash +# Check current quotas +gcloud compute project-info describe --format="table(quotas.metric,quotas.limit,quotas.usage)" + +# Request quota increase if needed +echo "If you need quota increases, visit:" +echo "https://console.cloud.google.com/iam-admin/quotas" +``` + +## IAM Permissions Configuration + +### Step 1: Assign Roles to User Account + +```bash +# Get your user account email +export USER_EMAIL=$(gcloud config get-value account) + +# Assign required roles to your user account +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="user:$USER_EMAIL" \ + --role="roles/container.admin" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="user:$USER_EMAIL" \ + --role="roles/compute.admin" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="user:$USER_EMAIL" \ + --role="roles/storage.admin" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="user:$USER_EMAIL" \ + --role="roles/dns.admin" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="user:$USER_EMAIL" \ + --role="roles/iam.serviceAccountAdmin" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="user:$USER_EMAIL" \ + --role="roles/resourcemanager.projectIamAdmin" +``` + +### Step 2: Assign Roles to Service Accounts + +```bash +# Roles for Rafiki application service account +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/storage.objectViewer" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/monitoring.metricWriter" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/logging.logWriter" + +# Roles for GKE node service account +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-node-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/container.nodeServiceAgent" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-node-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/storage.objectViewer" + +# Roles for CI/CD service account +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/container.developer" + +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member="serviceAccount:rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/storage.admin" +``` + +### Step 3: Create Custom IAM Role (if needed) + +```bash +# Create custom role for specific Rafiki permissions +cat < rafiki-custom-role.yaml +title: "Rafiki Custom Role" +description: "Custom role for Rafiki application with minimal required permissions" +stage: "GA" +includedPermissions: +- container.clusters.get +- container.clusters.list +- storage.objects.create +- storage.objects.delete +- storage.objects.get +- storage.objects.list +- monitoring.timeSeries.create +- logging.logEntries.create +EOF + +# Create the custom role +gcloud iam roles create rafikiCustomRole \ + --project=$PROJECT_ID \ + --file=rafiki-custom-role.yaml +``` + +## Network Infrastructure Setup + +### Step 1: Create VPC Network + +```bash +# Create custom VPC network +gcloud compute networks create rafiki-vpc \ + --subnet-mode=custom \ + --bgp-routing-mode=regional + +# Create subnet for GKE cluster +gcloud compute networks subnets create rafiki-subnet \ + --network=rafiki-vpc \ + --range=10.0.0.0/16 \ + --region=us-central1 \ + --secondary-range=pods=10.1.0.0/16,services=10.2.0.0/16 + +# Create subnet for private services (Cloud SQL, etc.) +gcloud compute networks subnets create rafiki-private-subnet \ + --network=rafiki-vpc \ + --range=10.3.0.0/16 \ + --region=us-central1 +``` + +### Step 2: Configure Firewall Rules + +```bash +# Allow internal communication +gcloud compute firewall-rules create rafiki-allow-internal \ + --network=rafiki-vpc \ + --allow=tcp,udp,icmp \ + --source-ranges=10.0.0.0/8 + +# Allow SSH access (for debugging) +gcloud compute firewall-rules create rafiki-allow-ssh \ + --network=rafiki-vpc \ + --allow=tcp:22 \ + --source-ranges=0.0.0.0/0 \ + --target-tags=ssh-allowed + +# Allow HTTPS traffic +gcloud compute firewall-rules create rafiki-allow-https \ + --network=rafiki-vpc \ + --allow=tcp:443 \ + --source-ranges=0.0.0.0/0 \ + --target-tags=https-server + +# Allow HTTP traffic (for health checks) +gcloud compute firewall-rules create rafiki-allow-http \ + --network=rafiki-vpc \ + --allow=tcp:80 \ + --source-ranges=0.0.0.0/0 \ + --target-tags=http-server + +# Allow load balancer health checks +gcloud compute firewall-rules create rafiki-allow-health-checks \ + --network=rafiki-vpc \ + --allow=tcp \ + --source-ranges=130.211.0.0/22,35.191.0.0/16 \ + --target-tags=gke-cluster +``` + +### Step 3: Set Up Private Service Connection + +```bash +# Reserve IP range for private services +gcloud compute addresses create google-managed-services-rafiki-vpc \ + --global \ + --purpose=VPC_PEERING \ + --prefix-length=16 \ + --network=rafiki-vpc + +# Create private connection +gcloud services vpc-peerings connect \ + --service=servicenetworking.googleapis.com \ + --ranges=google-managed-services-rafiki-vpc \ + --network=rafiki-vpc +``` + +### Step 4: Create Cloud NAT (for private nodes) + +```bash +# Create Cloud Router +gcloud compute routers create rafiki-router \ + --network=rafiki-vpc \ + --region=us-central1 + +# Create Cloud NAT +gcloud compute routers nats create rafiki-nat \ + --router=rafiki-router \ + --region=us-central1 \ + --nat-all-subnet-ip-ranges \ + --auto-allocate-subnetwork-range +``` + +## DNS Setup + +### Step 1: Create Cloud DNS Zone + +```bash +# Set your domain name +export DOMAIN_NAME="your-bank-domain.com" + +# Create DNS zone +gcloud dns managed-zones create rafiki-zone \ + --description="DNS zone for Rafiki deployment" \ + --dns-name=$DOMAIN_NAME \ + --visibility=public + +# Get name servers +gcloud dns managed-zones describe rafiki-zone \ + --format="value(nameServers[].join(' '))" +``` + +### Step 2: Configure Domain Registrar + +```bash +echo "Update your domain registrar with these name servers:" +gcloud dns managed-zones describe rafiki-zone \ + --format="table(nameServers[].join(chr(10)))" + +echo "" +echo "Steps to update at your domain registrar:" +echo "1. Log into your domain registrar's control panel" +echo "2. Find DNS or Name Server settings" +echo "3. Replace existing name servers with the ones listed above" +echo "4. Save changes (may take 24-48 hours to propagate)" +``` + +### Step 3: Create Initial DNS Records + +```bash +# Reserve static IP for load balancer +gcloud compute addresses create rafiki-static-ip \ + --global + +# Get the IP address +export STATIC_IP=$(gcloud compute addresses describe rafiki-static-ip \ + --global --format="get(address)") + +# Create A record for main domain +gcloud dns record-sets transaction start --zone=rafiki-zone + +gcloud dns record-sets transaction add $STATIC_IP \ + --name=$DOMAIN_NAME. \ + --ttl=300 \ + --type=A \ + --zone=rafiki-zone + +# Create A records for subdomains +gcloud dns record-sets transaction add $STATIC_IP \ + --name=admin.$DOMAIN_NAME. \ + --ttl=300 \ + --type=A \ + --zone=rafiki-zone + +gcloud dns record-sets transaction add $STATIC_IP \ + --name=auth.$DOMAIN_NAME. \ + --ttl=300 \ + --type=A \ + --zone=rafiki-zone + +gcloud dns record-sets transaction execute --zone=rafiki-zone +``` + +## Security Configuration + +### Step 1: Enable Security Features + +```bash +# Enable Security Command Center (if available in your region) +gcloud alpha scc settings enable --organization=$(gcloud organizations list --format="value(name)") + +# Enable audit logging +cat < audit-policy.yaml +auditConfigs: +- service: allServices + auditLogConfigs: + - logType: ADMIN_READ + - logType: DATA_READ + - logType: DATA_WRITE +EOF + +gcloud logging sinks create rafiki-audit-sink \ + storage.googleapis.com/rafiki-audit-logs-$PROJECT_ID \ + --log-filter='protoPayload.serviceName="container.googleapis.com"' +``` + +### Step 2: Set Up Secret Manager + +```bash +# Create secrets in Secret Manager +echo -n "$(openssl rand -base64 32)" | \ + gcloud secrets create rafiki-database-password --data-file=- + +echo -n "$(openssl rand -base64 64)" | \ + gcloud secrets create rafiki-jwt-secret --data-file=- + +echo -n "$(openssl rand -base64 32)" | \ + gcloud secrets create rafiki-webhook-secret --data-file=- + +# Grant access to service account +gcloud secrets add-iam-policy-binding rafiki-database-password \ + --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/secretmanager.secretAccessor" + +gcloud secrets add-iam-policy-binding rafiki-jwt-secret \ + --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/secretmanager.secretAccessor" + +gcloud secrets add-iam-policy-binding rafiki-webhook-secret \ + --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ + --role="roles/secretmanager.secretAccessor" +``` + +### Step 3: Configure Binary Authorization (Optional) + +```bash +# Create Binary Authorization policy +cat < binary-authorization-policy.yaml +defaultAdmissionRule: + requireAttestationsBy: [] + enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG + evaluationMode: REQUIRE_ATTESTATION +clusterAdmissionRules: + us-central1-a.rafiki-cluster: + requireAttestationsBy: [] + enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG + evaluationMode: ALWAYS_ALLOW +EOF + +gcloud container binauthz policy import binary-authorization-policy.yaml +``` + +## Verification and Testing + +### Step 1: Verify Project Setup + +```bash +# Check project configuration +gcloud config list + +# Verify billing is enabled +gcloud billing projects describe $PROJECT_ID + +# Check enabled APIs +gcloud services list --enabled | grep -E "(container|compute|storage|dns)" +``` + +### Step 2: Test Network Connectivity + +```bash +# Test VPC creation +gcloud compute networks describe rafiki-vpc + +# Test subnet creation +gcloud compute networks subnets describe rafiki-subnet --region=us-central1 + +# Test firewall rules +gcloud compute firewall-rules list --filter="network:rafiki-vpc" +``` + +### Step 3: Test DNS Configuration + +```bash +# Test DNS zone +gcloud dns managed-zones describe rafiki-zone + +# Test DNS resolution (may take time to propagate) +nslookup $DOMAIN_NAME +``` + +### Step 4: Test Service Account Permissions + +```bash +# Test service account impersonation +gcloud auth activate-service-account --key-file=rafiki-sa-key.json + +# Test basic permissions +gcloud compute instances list +gcloud container clusters list + +# Switch back to user account +gcloud auth login +``` + +### Step 5: Create Test Resources + +```bash +# Create a small test VM to verify setup +gcloud compute instances create test-vm \ + --zone=us-central1-a \ + --machine-type=e2-micro \ + --subnet=rafiki-subnet \ + --no-address \ + --image-family=ubuntu-2004-lts \ + --image-project=ubuntu-os-cloud \ + --tags=ssh-allowed + +# Test SSH access (should work through Cloud NAT) +gcloud compute ssh test-vm --zone=us-central1-a --command="curl -s http://metadata.google.internal/computeMetadata/v1/instance/hostname -H 'Metadata-Flavor: Google'" + +# Clean up test VM +gcloud compute instances delete test-vm --zone=us-central1-a --quiet +``` + +## Environment Variables Export + +### Step 1: Create Environment Configuration File + +```bash +# Create environment configuration file +cat < rafiki-env.sh +#!/bin/bash +# Rafiki GCP Environment Configuration + +export PROJECT_ID="$PROJECT_ID" +export PROJECT_NAME="$PROJECT_NAME" +export BILLING_ACCOUNT_ID="$BILLING_ACCOUNT_ID" +export DOMAIN_NAME="$DOMAIN_NAME" +export STATIC_IP="$STATIC_IP" + +# GCP Configuration +export REGION="us-central1" +export ZONE="us-central1-a" +export CLUSTER_NAME="rafiki-cluster" +export NAMESPACE="rafiki" + +# Network Configuration +export VPC_NAME="rafiki-vpc" +export SUBNET_NAME="rafiki-subnet" + +# Service Accounts +export RAFIKI_SA="rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" +export NODE_SA="rafiki-node-sa@$PROJECT_ID.iam.gserviceaccount.com" +export CICD_SA="rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com" + +# DNS Configuration +export DNS_ZONE="rafiki-zone" + +echo "GCP environment configured for Rafiki deployment" +echo "Project ID: \$PROJECT_ID" +echo "Domain: \$DOMAIN_NAME" +echo "Static IP: \$STATIC_IP" +EOF + +chmod +x rafiki-env.sh +``` + +### Step 2: Load Environment + +```bash +# Source the environment +source rafiki-env.sh + +# Add to your shell profile for persistence +echo "source $(pwd)/rafiki-env.sh" >> ~/.bashrc +``` + +## Final Verification Checklist + +Create a verification script to ensure everything is set up correctly: + +```bash +#!/bin/bash +# rafiki-verification.sh + +echo "🔍 Verifying GCP Prerequisites for Rafiki Deployment" +echo "==================================================" + +# Check if project is set +echo -n "✅ Project configuration: " +if [ "$(gcloud config get-value project)" == "$PROJECT_ID" ]; then + echo "✓ Configured correctly" +else + echo "❌ Project not set correctly" + exit 1 +fi + +# Check billing +echo -n "✅ Billing status: " +if gcloud billing projects describe $PROJECT_ID --format="value(billingEnabled)" | grep -q "True"; then + echo "✓ Billing enabled" +else + echo "❌ Billing not enabled" + exit 1 +fi + +# Check required APIs +echo "✅ Required APIs:" +APIS=("container.googleapis.com" "compute.googleapis.com" "storage.googleapis.com" "dns.googleapis.com") +for api in "${APIS[@]}"; do + if gcloud services list --enabled --filter="NAME:$api" --format="value(NAME)" | grep -q "$api"; then + echo " ✓ $api" + else + echo " ❌ $api not enabled" + exit 1 + fi +done + +# Check VPC +echo -n "✅ VPC Network: " +if gcloud compute networks describe rafiki-vpc &>/dev/null; then + echo "✓ VPC created" +else + echo "❌ VPC not found" + exit 1 +fi + +# Check DNS +echo -n "✅ DNS Zone: " +if gcloud dns managed-zones describe rafiki-zone &>/dev/null; then + echo "✓ DNS zone created" +else + echo "❌ DNS zone not found" + exit 1 +fi + +# Check service accounts +echo -n "✅ Service Accounts: " +if gcloud iam service-accounts describe rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com &>/dev/null; then + echo "✓ Service accounts created" +else + echo "❌ Service accounts not found" + exit 1 +fi + +echo "" +echo "🎉 All prerequisites verified successfully!" +echo "You're ready to proceed with Rafiki deployment." +``` + +Make the script executable and run it: + +```bash +chmod +x rafiki-verification.sh +./rafiki-verification.sh +``` + +## Next Steps + +After completing all prerequisites: + +1. **Save all generated keys and configuration files securely** +2. **Document your specific configuration values** +3. **Proceed to the main Rafiki deployment guide** +4. **Set up monitoring and alerting for your GCP resources** + +## Cost Optimization Tips + +To minimize costs during setup and testing: + +```bash +# Set up automatic cleanup for test resources +gcloud compute instances list --format="value(name,zone)" | \ +while read name zone; do + if [[ $name == test-* ]]; then + gcloud compute instances delete $name --zone=$zone --quiet + fi +done + +# Set up budget alerts to avoid unexpected charges +gcloud billing budgets create \ + --billing-account=$BILLING_ACCOUNT_ID \ + --display-name="Rafiki Development Budget" \ + --budget-amount=50USD \ + --threshold-rule=percent=80,basis=CURRENT_SPEND +``` + +This comprehensive setup ensures your GCP environment is properly configured for a production-ready Rafiki deployment with all necessary security, networking, and access controls in place. diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx new file mode 100644 index 0000000000..441b58c093 --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx @@ -0,0 +1,1017 @@ +--- +title: Rafiki-deployment-testnet +--- + +### Table of Contents +1. [Overview](#overview) +2. [Prerequisites](#prerequisites) +3. [Architecture Overview](#architecture-overview) +4. [Infrastructure Setup with Terraform](#infrastructure-setup-with-terraform) +5. [Kubernetes Deployment](#kubernetes-deployment) +6. [Rafiki Configuration](#rafiki-configuration) +7. [Security Considerations](#security-considerations) +8. [Monitoring and Observability](#monitoring-and-observability) +9. [Testing and Validation](#testing-and-validation) +10. [Production Deployment](#production-deployment) +11. [Maintenance and Operations](#maintenance-and-operations) + +--- + +## Overview + +Rafiki is open source software that provides an efficient solution for an Account Servicing Entity to enable Interledger functionality on its users' accounts. This guide provides a comprehensive deployment strategy for financial institutions looking to integrate Rafiki into their existing infrastructure using modern cloud-native technologies. + +**Key Components:** +- **Rafiki Backend**: Includes an Interledger connector, a high-throughput accounting database called TigerBeetle, and several APIs +- **Open Payments API**: For third-party payment initiation +- **Admin APIs**: For managing peering relationships and supported assets +- **GNAP Authorization Server**: Access control for Open Payments API + +--- + +## Prerequisites + +### Technical Requirements +- **Google Cloud Platform Account** with billing enabled +- **Terraform** >= 1.0 +- **Helm** >= 3.7.2 +- **kubectl** >= 1.20 +- **Docker** for local development +- **Git** for version control + +### Financial Institution Requirements +- **Regulatory Compliance**: Ensure compliance with local financial regulations +- **KYC/AML Processes**: Integration with existing compliance systems +- **Risk Management**: Established risk assessment frameworks +- **Security Policies**: Enterprise-grade security protocols + +### Domain and DNS +- Registered domain for your institution +- SSL/TLS certificates (Let's Encrypt or commercial) +- DNS management access + +--- + +## Architecture Overview + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Google Cloud Platform │ +├─────────────────────────────────────────────────────────────────┤ +│ GKE Cluster │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ +│ │ Rafiki │ │ TigerBeetle │ │ PostgreSQL │ │ +│ │ Backend │ │ Accounting │ │ Auth DB │ │ +│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ +│ │ Auth Server │ │ Redis Cache │ │ Monitoring │ │ +│ │ (GNAP) │ │ │ │ Stack │ │ +│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ Supporting Services │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ +│ │ Cloud SQL │ │ Cloud Storage │ │ Cloud KMS │ │ +│ │ (Backup) │ │ (Artifacts) │ │ (Secrets) │ │ +│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Infrastructure Setup with Terraform + +### Project Structure + +``` +rafiki-infrastructure/ +├── environments/ +│ ├── dev/ +│ │ ├── main.tf +│ │ ├── variables.tf +│ │ └── terraform.tfvars +│ ├── staging/ +│ │ ├── main.tf +│ │ ├── variables.tf +│ │ └── terraform.tfvars +│ └── prod/ +│ ├── main.tf +│ ├── variables.tf +│ └── terraform.tfvars +├── modules/ +│ ├── gke/ +│ ├── networking/ +│ ├── security/ +│ └── storage/ +├── helm-charts/ +└── scripts/ +``` + +### Core Terraform Configuration + +#### 1. Provider Configuration (`providers.tf`) + +```hcl +terraform { + required_version = ">= 1.0" + required_providers { + google = { + source = "hashicorp/google" + version = "~> 4.0" + } + google-beta = { + source = "hashicorp/google-beta" + version = "~> 4.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.0" + } + helm = { + source = "hashicorp/helm" + version = "~> 2.0" + } + } + + backend "gcs" { + bucket = "your-bank-terraform-state" + prefix = "rafiki/terraform.tfstate" + } +} + +provider "google" { + project = var.project_id + region = var.region + zone = var.zone +} + +provider "google-beta" { + project = var.project_id + region = var.region + zone = var.zone +} + +data "google_client_config" "default" {} + +provider "kubernetes" { + host = "https://${module.gke.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(module.gke.ca_certificate) +} + +provider "helm" { + kubernetes { + host = "https://${module.gke.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(module.gke.ca_certificate) + } +} +``` + +#### 2. Variables Configuration (`variables.tf`) + +```hcl +variable "project_id" { + description = "GCP Project ID" + type = string +} + +variable "region" { + description = "GCP Region" + type = string + default = "us-central1" +} + +variable "zone" { + description = "GCP Zone" + type = string + default = "us-central1-a" +} + +variable "environment" { + description = "Environment name (dev, staging, prod)" + type = string +} + +variable "organization_name" { + description = "Your bank or financial institution name" + type = string +} + +variable "domain_name" { + description = "Your institution's domain name" + type = string +} + +variable "gke_node_count" { + description = "Number of GKE nodes" + type = number + default = 3 +} + +variable "gke_machine_type" { + description = "GKE node machine type" + type = string + default = "e2-standard-4" +} + +variable "enable_tigerbeetle" { + description = "Enable TigerBeetle for high-performance accounting" + type = bool + default = true +} +``` + +#### 3. Main Infrastructure (`main.tf`) + +```hcl +locals { + name_prefix = "${var.organization_name}-rafiki-${var.environment}" + common_labels = { + environment = var.environment + organization = var.organization_name + managed_by = "terraform" + application = "rafiki" + } +} + +# VPC Network +module "networking" { + source = "./modules/networking" + + name_prefix = local.name_prefix + project_id = var.project_id + region = var.region + common_labels = local.common_labels +} + +# GKE Cluster +module "gke" { + source = "./modules/gke" + + name_prefix = local.name_prefix + project_id = var.project_id + region = var.region + zone = var.zone + network_name = module.networking.network_name + subnet_name = module.networking.subnet_name + node_count = var.gke_node_count + machine_type = var.gke_machine_type + common_labels = local.common_labels +} + +# Cloud SQL for PostgreSQL (Auth services) +module "postgresql" { + source = "./modules/storage" + + name_prefix = local.name_prefix + project_id = var.project_id + region = var.region + network_id = module.networking.network_id + database_name = "rafiki_auth" + common_labels = local.common_labels +} + +# Security and Secrets Management +module "security" { + source = "./modules/security" + + name_prefix = local.name_prefix + project_id = var.project_id + region = var.region + common_labels = local.common_labels +} + +# DNS and SSL +resource "google_dns_managed_zone" "rafiki_zone" { + name = "${replace(local.name_prefix, "-", "")}zone" + dns_name = "${var.environment}.${var.domain_name}." + description = "DNS zone for Rafiki ${var.environment} environment" + + labels = local.common_labels +} + +# Static IP for Load Balancer +resource "google_compute_global_address" "rafiki_ip" { + name = "${local.name_prefix}-ip" + ip_version = "IPV4" + address_type = "EXTERNAL" +} +``` + +### GKE Module (`modules/gke/main.tf`) + +```hcl +resource "google_container_cluster" "rafiki_cluster" { + name = "${var.name_prefix}-cluster" + location = var.region + + # Enable Workload Identity + workload_identity_config { + workload_pool = "${var.project_id}.svc.id.goog" + } + + # Network configuration + network = var.network_name + subnetwork = var.subnet_name + + # Security configuration + enable_shielded_nodes = true + + # Remove default node pool + remove_default_node_pool = true + initial_node_count = 1 + + # Addons + addons_config { + network_policy_config { + disabled = false + } + + horizontal_pod_autoscaling { + disabled = false + } + + istio_config { + disabled = false + auth = "AUTH_MUTUAL_TLS" + } + } + + # Enable network policy + network_policy { + enabled = true + } + + # Private cluster configuration for production + private_cluster_config { + enable_private_nodes = true + enable_private_endpoint = false + master_ipv4_cidr_block = "172.16.0.0/28" + } + + # IP allocation policy + ip_allocation_policy { + cluster_secondary_range_name = "gke-pods" + services_secondary_range_name = "gke-services" + } + + master_auth { + client_certificate_config { + issue_client_certificate = false + } + } +} + +resource "google_container_node_pool" "rafiki_nodes" { + name = "${var.name_prefix}-node-pool" + location = var.region + cluster = google_container_cluster.rafiki_cluster.name + node_count = var.node_count + + # Auto-scaling configuration + autoscaling { + min_node_count = 1 + max_node_count = 10 + } + + # Node configuration + node_config { + preemptible = var.environment != "prod" + machine_type = var.machine_type + disk_size_gb = 100 + disk_type = "pd-ssd" + + # Security + shielded_instance_config { + enable_secure_boot = true + enable_integrity_monitoring = true + } + + # Service account + service_account = google_service_account.gke_nodes.email + oauth_scopes = [ + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/devstorage.read_only", + ] + + # Labels + labels = var.common_labels + } + + # Update strategy + management { + auto_repair = true + auto_upgrade = true + } +} + +resource "google_service_account" "gke_nodes" { + account_id = "${var.name_prefix}-gke-nodes" + display_name = "GKE Nodes Service Account" +} +``` + +--- + +## Kubernetes Deployment + +### Namespace and RBAC + +```yaml +# k8s/namespaces.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: rafiki-system + labels: + name: rafiki-system + istio-injection: enabled +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: rafiki-backend + namespace: rafiki-system + annotations: + iam.gke.io/gcp-service-account: rafiki-backend@PROJECT_ID.iam.gserviceaccount.com +``` + +### Using Interledger Helm Charts + +Add the Interledger Helm repository: + +```bash +# Add the Interledger Helm repository +helm repo add interledger https://interledger.github.io/helm-charts +helm repo update + +# Search available charts +helm search repo interledger +``` + +### Rafiki Configuration Values + +Create a `values-production.yaml` file: + +```yaml +# values-production.yaml +rafiki: + backend: + image: + repository: interledger/rafiki + tag: "latest" + pullPolicy: IfNotPresent + + replicaCount: 3 + + env: + # Database Configuration + DATABASE_URL: "postgresql://rafiki:password@postgresql:5432/rafiki_auth" + + # TigerBeetle Configuration (if enabled) + TIGERBEETLE_CLUSTER_ID: "0" + TIGERBEETLE_REPLICA_ADDRESSES: "tigerbeetle:3000" + + # Open Payments Configuration + OPEN_PAYMENTS_URL: "https://rafiki.yourdomain.com" + + # Interledger Configuration + ILP_ADDRESS: "g.yourdomain" + ILP_CONNECTOR_ADDRESS: "0.0.0.0:4000" + + # Auth Configuration + AUTH_SERVER_GRANT_URL: "https://auth.yourdomain.com" + AUTH_SERVER_INTROSPECTION_URL: "https://auth.yourdomain.com/introspect" + + # Redis Configuration + REDIS_URL: "redis://redis:6379" + + # Logging + LOG_LEVEL: "info" + + resources: + requests: + memory: "512Mi" + cpu: "500m" + limits: + memory: "2Gi" + cpu: "2000m" + + service: + type: ClusterIP + port: 3001 + + ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + hosts: + - host: rafiki.yourdomain.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: rafiki-tls + hosts: + - rafiki.yourdomain.com + +# TigerBeetle Configuration +tigerbeetle: + enabled: true + replicaCount: 3 + + image: + repository: tigerbeetle/tigerbeetle + tag: "latest" + pullPolicy: IfNotPresent + + persistence: + enabled: true + storageClass: "ssd" + size: 100Gi + + resources: + requests: + memory: "1Gi" + cpu: "1000m" + limits: + memory: "4Gi" + cpu: "4000m" + +# PostgreSQL Configuration +postgresql: + enabled: true + + auth: + username: rafiki + database: rafiki_auth + existingSecret: rafiki-db-secret + + primary: + persistence: + enabled: true + storageClass: "ssd" + size: 50Gi + + resources: + requests: + memory: "512Mi" + cpu: "500m" + limits: + memory: "2Gi" + cpu: "2000m" + +# Redis Configuration +redis: + enabled: true + + auth: + enabled: true + existingSecret: redis-secret + + master: + persistence: + enabled: true + storageClass: "ssd" + size: 20Gi + +# Auth Server Configuration +authServer: + enabled: true + + image: + repository: interledger/rafiki-auth + tag: "latest" + + replicaCount: 2 + + env: + DATABASE_URL: "postgresql://rafiki:password@postgresql:5432/rafiki_auth" + IDENTITY_SERVER_URL: "https://auth.yourdomain.com" + + service: + type: ClusterIP + port: 3006 + + ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + hosts: + - host: auth.yourdomain.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: auth-tls + hosts: + - auth.yourdomain.com + +# Monitoring Configuration +monitoring: + prometheus: + enabled: true + grafana: + enabled: true + adminPassword: "secure-password" + +# Security +securityContext: + runAsNonRoot: true + runAsUser: 1001 + fsGroup: 1001 + +# Network Policies +networkPolicy: + enabled: true +``` + +--- + +## Security Considerations + +### 1. Secrets Management + +```bash +# Create required secrets +kubectl create secret generic rafiki-db-secret \ + --from-literal=username=rafiki \ + --from-literal=password=your-secure-password \ + -n rafiki-system + +kubectl create secret generic redis-secret \ + --from-literal=redis-password=your-redis-password \ + -n rafiki-system + +# TLS Certificates (using cert-manager) +kubectl apply -f - < r.status === 200, + 'response time < 500ms': (r) => r.timings.duration < 500, + }); +} +``` + +--- + +## Production Deployment + +### Pre-deployment Checklist + +- [ ] **Security Review**: Penetration testing completed +- [ ] **Compliance Verification**: Regulatory requirements met +- [ ] **Backup Strategy**: Database and configuration backups configured +- [ ] **Disaster Recovery**: Recovery procedures documented and tested +- [ ] **Monitoring**: All alerts and dashboards configured +- [ ] **Performance Testing**: Load testing completed successfully +- [ ] **Documentation**: Operational runbooks completed + +### Deployment Steps + +```bash +# 1. Deploy infrastructure +cd environments/prod +terraform init +terraform plan -var-file=terraform.tfvars +terraform apply + +# 2. Configure kubectl +gcloud container clusters get-credentials rafiki-prod-cluster \ + --region us-central1 \ + --project your-project-id + +# 3. Install cert-manager +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml + +# 4. Install ingress controller +helm upgrade --install ingress-nginx ingress-nginx \ + --repo https://kubernetes.github.io/ingress-nginx \ + --namespace ingress-nginx \ + --create-namespace + +# 5. Deploy Rafiki +helm upgrade --install rafiki interledger/rafiki \ + -f values-production.yaml \ + -n rafiki-system \ + --create-namespace \ + --wait + +# 6. Verify deployment +kubectl get pods -n rafiki-system +kubectl get ingress -n rafiki-system +``` + +### Post-deployment Validation + +```bash +# Health checks +curl -f https://rafiki.yourdomain.com/health +curl -f https://auth.yourdomain.com/health + +# Admin API test +curl -X POST https://rafiki.yourdomain.com/graphql \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -d '{"query": "query { peers { edges { node { id staticIlpAddress } } } }"}' + +# Open Payments discovery +curl https://rafiki.yourdomain.com/.well-known/open_payments_authz +``` + +--- + +## Maintenance and Operations + +### Regular Maintenance Tasks + +1. **Weekly**: + - Review monitoring dashboards + - Check security alerts + - Verify backup integrity + +2. **Monthly**: + - Update Helm charts + - Review resource utilization + - Security patch updates + +3. **Quarterly**: + - Disaster recovery testing + - Security audit + - Performance optimization review + +### Backup and Recovery + +```bash +# Database backup script +#!/bin/bash +BACKUP_NAME="rafiki-backup-$(date +%Y%m%d-%H%M%S)" + +# Create database backup +kubectl exec -n rafiki-system deployment/postgresql -- \ + pg_dump -U rafiki rafiki_auth > $BACKUP_NAME.sql + +# Upload to Cloud Storage +gsutil cp $BACKUP_NAME.sql gs://your-backup-bucket/ +``` + +### Scaling Considerations + +- **Horizontal Pod Autoscaling**: Configure HPA for backend services +- **Vertical Pod Autoscaling**: Optimize resource requests/limits +- **Database Scaling**: Consider read replicas for high-read workloads +- **TigerBeetle Scaling**: TigerBeetle is optimized for online transaction processing (OLTP) workloads, offering significantly higher performance + +### Troubleshooting Guide + +Common issues and solutions: + +1. **Pod Startup Issues**: + ```bash + kubectl describe pod -n rafiki-system + kubectl logs -f deployment/rafiki-backend -n rafiki-system + ``` + +2. **Database Connection Issues**: + ```bash + kubectl exec -n rafiki-system deployment/rafiki-backend -- \ + nc -zv postgresql 5432 + ``` + +3. **TLS Certificate Issues**: + ```bash + kubectl describe certificate -n rafiki-system + kubectl describe certificaterequest -n rafiki-system + ``` + +--- + +## Conclusion + +This guide provides a comprehensive foundation for deploying Rafiki in a production environment. By harnessing TigerBeetle's advanced features, Rafiki offers Account Servicing Entities (ASEs) a powerful and dependable solution for implementing Interledger functionality. + +Key success factors: +- **Security-first approach** with proper secrets management +- **Scalable architecture** using Kubernetes best practices +- **Comprehensive monitoring** for operational excellence +- **Automated deployment** with Terraform and Helm +- **Compliance readiness** for financial regulations + +For additional support and community resources, visit the [Interledger Community](https://community.interledger.org/) and the [Rafiki GitHub repository](https://github.com/interledger/rafiki). From f021ed7dc747da6d321f69c2bf6f2bd8ed1f2be1 Mon Sep 17 00:00:00 2001 From: hajjimo Date: Fri, 1 Aug 2025 21:40:39 +0200 Subject: [PATCH 2/6] docs: mi/3149/deployment-example --- packages/documentation/astro.config.mjs | 26 +- .../01-architecture-overview.mdx | 208 ++++ .../02-configuration-variables.mdx | 373 ++++++ .../deploy-to-prod/03-secrets-management.mdx | 84 ++ .../04-infrastructure-setup.mdx | 270 +++++ .../deploy-to-prod/05-services-deployment.mdx | 964 ++++++++++++++++ .../deploy-to-prod/06-troubleshooting.mdx | 139 +++ .../gcp-prerequisites-guide.mdx | 882 -------------- .../rafiki-deployment-testnet.mdx | 1017 ----------------- 9 files changed, 2059 insertions(+), 1904 deletions(-) create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/03-secrets-management.mdx create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/04-infrastructure-setup.mdx create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx create mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx delete mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx delete mode 100644 packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx diff --git a/packages/documentation/astro.config.mjs b/packages/documentation/astro.config.mjs index 6ed5903e71..ec97982537 100644 --- a/packages/documentation/astro.config.mjs +++ b/packages/documentation/astro.config.mjs @@ -133,16 +133,32 @@ export default defineConfig({ ] }, { - label: 'Rafiki Guide', + label: 'Deployment example', collapsed: true, items: [ { - label: 'Rafiki TestNet', - link: '/integration/deploy-to-prod/rafiki-deployment-testnet' + label: 'Overview', + link: '/integration/deploy-to-prod/01-architecture-overview' }, { - label: 'GCP prerequisites', - link: '/integration/deploy-to-prod/gcp-prerequisites-guide' + label: 'Configuration variables', + link: '/integration/deploy-to-prod/02-configuration-variables' + }, + { + label: 'Secrets management', + link: '/integration/deploy-to-prod/03-secrets-management' + }, + { + label: 'Infrastructure setup', + link: '/integration/deploy-to-prod/04-infrastructure-setup' + }, + { + label: 'Services deployment', + link: '/integration/deploy-to-prod/05-services-deployment' + }, + { + label: 'Troubleshooting', + link: '/integration/deploy-to-prod/06-troubleshooting' } ] }, diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx new file mode 100644 index 0000000000..ec530a9d4c --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx @@ -0,0 +1,208 @@ +--- +title: Overview +--- + +import { + MermaidWrapper, + Mermaid, + LinkOut, + Tooltip +} from '@interledger/docs-design-system' + +This guide provides an approach for you to deploy and integrate Rafiki on Google Cloud Platform using Terraform, Kubernetes, Helm charts, and Argo CD. The reference architecture used in this guide is the Interledger Test Network. For this example we'll assume you are a digital wallet provider that wants to deploy your wallet application and Rafiki in your Kubernetes cluster. + +:::caution +As the Interledger Test Network is used to showcase Rafiki's functionalities and to serve as a sandbox environment, this example is intended for informational purposes only and should not be used for a production deployment. +::: + +## Prerequisites + +Before beginning the integration, ensure you have the following: + +- A Google Cloud Platform account with billing enabled +- The gcloud CLI installed and + authenticated +- Hashicorp Terraform installed +- A Kubernetes cluster deployed via GKE +- Helm installed +- kubectl installed + and configured +- The argocd CLI (optional) +- Domain name for your wallet (required for SSL/TLS certificates) + +## Architecture overview + +The deployment follows the Interledger Test Network reference architecture, which includes: + +- **GKE Cluster**: Managed Kubernetes cluster on GCP +- **Rafiki Services**: Core Interledger functionality (Admin API, Auth Service, Backend) +- **PostgreSQL**: Database for Rafiki and wallet data +- **Redis**: Caching and session management +- **NGINX Ingress**: Load balancing and SSL termination +- **Argo CD**: GitOps continuous deployment +- **Digital Wallet**: Your wallet application integrated with Rafiki + +## Reference architecture + +The following diagram illustrates the complete architecture based on the Interledger Test Network reference implementation: + + + +your-wallet.com] + LB[Google Cloud
Load Balancer] + end + + %% GKE Cluster + subgraph "GKE Cluster" + %% Ingress Layer + subgraph "Ingress Layer" + Ingress[NGINX Ingress
Controller] + CertManager[cert-manager
Let's Encrypt] + end + + %% Application Layer + subgraph "Digital Wallet Namespace" + WalletUI[Digital Wallet UI
wallet.your-wallet.com] + WalletAPI[Wallet Backend API
api.your-wallet.com] + WalletDB[(Wallet Database
PostgreSQL)] + end + + %% Rafiki Services + subgraph "Rafiki Namespace" + RafikiAuth[Rafiki Auth Server
auth.your-wallet.com] + RafikiBackend[Rafiki Backend
backend.your-wallet.com] + RafikiAdmin[Rafiki Admin API
admin.your-wallet.com] + RafikiDB[(Rafiki Database
PostgreSQL)] + Redis[(Redis Cache)] + end + + %% GitOps and Monitoring + subgraph "Platform Services" + ArgoCD[Argo CD
argocd.your-wallet.com] + Monitoring[Prometheus
& Grafana] + end + + %% Persistent Storage + subgraph "Storage" + PVC1[Wallet DB PVC] + PVC2[Rafiki DB PVC] + PVC3[Redis PVC] + end + end + + %% External Git Repository + GitRepo[📁 Git Repository
Helm Charts & Config] + + %% Connections - External + User --> Internet + Internet --> DNS + DNS --> LB + LB --> Ingress + + %% Connections - Internal Services + Ingress --> WalletUI + Ingress --> WalletAPI + Ingress --> RafikiAuth + Ingress --> RafikiBackend + Ingress --> RafikiAdmin + Ingress --> ArgoCD + + %% Wallet Internal Connections + WalletUI --> WalletAPI + WalletAPI --> WalletDB + WalletAPI --> RafikiAdmin + WalletAPI --> RafikiBackend + + %% Rafiki Internal Connections + RafikiAuth --> RafikiDB + RafikiAuth --> Redis + RafikiBackend --> RafikiDB + RafikiBackend --> Redis + RafikiAdmin --> RafikiDB + + %% Interledger Protocol Connections + RafikiBackend --> External + External --> RafikiBackend + + %% Storage Connections + WalletDB --> PVC1 + RafikiDB --> PVC2 + Redis --> PVC3 + + %% GitOps + GitRepo --> ArgoCD + ArgoCD --> WalletAPI + ArgoCD --> RafikiAuth + ArgoCD --> RafikiBackend + ArgoCD --> RafikiAdmin + + %% Certificate Management + CertManager --> Ingress + + %% Styling + classDef userFacing fill:#f0f0f0,stroke:#333,color:#000 + classDef rafiki fill:#d9d9d9,stroke:#333,color:#000 + classDef wallet fill:#e6e6e6,stroke:#333,color:#000 + classDef platform fill:#cccccc,stroke:#333,color:#000 + classDef storage fill:#b3b3b3,stroke:#333,color:#000 + classDef external fill:#ffffff,stroke:#333,color:#000 + + class User,WalletUI userFacing + class RafikiAuth,RafikiBackend,RafikiAdmin,RafikiDB,Redis rafiki + class WalletAPI,WalletDB wallet + class ArgoCD,Monitoring,Ingress,CertManager platform + class PVC1,PVC2,PVC3 storage + class External,Internet,DNS,LB,GitRepo external`} +/> + +
+ +## Component details + +### External layer + +- **Users**: Access wallet through web/mobile interfaces +- **DNS & Load Balancing**: Google Cloud DNS and Load Balancer for traffic routing + +### Ingress layer + +- **NGINX Ingress**: Routes traffic to appropriate services based on hostname +- **cert-manager**: Automatically provisions and manages TLS certificates + +### Digital wallet layer + +- **Wallet UI** (`wallet.your-wallet.com`): User-facing web application +- **Wallet API** (`api.your-wallet.com`): Backend services for wallet functionality +- **Wallet Database**: User accounts, balances, transaction history + +### Rafiki layer + +Core Interledger services providing the following functionality: + +- **Auth server** (`auth.your-wallet.com`): Handles Open Payments authentication and authorization +- **Backend** (`backend.your-wallet.com`): Core Interledger protocol implementation +- **Admin API** (`admin.your-wallet.com`): Administrative functions and account management via GraphQL API +- **Database**: Stores Interledger accounts, payment pointers, and transaction data +- **Redis**: Caching and session management + +### Platform Services + +- **Argo CD**: GitOps continuous deployment from Git repositories +- **Monitoring**: Prometheus metrics collection and Grafana dashboards + +## Next steps + +1. **[Configuration variables](/integration/deploy-to-prod/02-configuration-variables)**: Review all variables that need customization for your environment +2. **[Secrets management](/integration/deploy-to-prod/03-secrets-management)**: Set up secure secret generation, storage, and rotation strategies +3. **[Infrastructure setup](/integration/deploy-to-prod/04-infrastructure-setup)**: Deploy GCP infrastructure using Terraform +4. **[Rafiki services deployment](/integration/deploy-to-prod/05-services-deployment)**: Install and configure all services using Helm and Argo CD +5. **[Troubleshooting](/integration/deploy-to-prod/06-troubleshooting)**: Verify end-to-end payment flows and resolve common issues diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx new file mode 100644 index 0000000000..58fc5f27ed --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx @@ -0,0 +1,373 @@ +--- +title: Configure variables +--- + +This document outlines all variables you must customize for you specific environment when deploying Rafiki with your digital wallet. + +## Google Cloud environment variables + +These are the primary variables you'll need to define for your deployment: + +
+ +| Variable | Example Value | Description | +| ----------------- | ------------------------------ | ------------------------------------------------------- | +| `YOUR_PROJECT_ID` | `my-wallet-project-123` | Your Google Cloud Project ID | +| `YOUR_DOMAIN` | `mywallet.com` | Your primary domain name | +| `YOUR_COMPANY` | `MyWallet Inc` | Your company/organization name | +| `YOUR_EMAIL` | `admin@mywallet.com` | Administrative email for certificates and notifications | +| `YOUR_REGION` | `us-central1` | Primary GCP region for deployment | +| `YOUR_REGISTRY` | `gcr.io/my-wallet-project-123` | Container registry for your wallet images | + +
+ +## Terraform variables + +_Found in: `terraform/variables.tf` (definitions) and `terraform.tfvars` (values)_ + +Configure your infrastructure deployment with these variables: + +
+ +| Variable | Default Value | Required | Description | +| ------------------------ | ----------------------- | -------- | ----------------------------------------------------- | +| `project_id` | - | Yes | GCP Project ID where resources will be created | +| `region` | `us-central1` | No | Primary GCP region for cluster and resources | +| `cluster_name` | `rafiki-wallet-cluster` | No | Name of the GKE cluster | +| `domain_name` | - | Yes | Primary domain for your wallet (e.g., `mywallet.com`) | +| `node_pool_machine_type` | `e2-standard-4` | No | GCE machine type for Kubernetes nodes | +| `min_node_count` | `1` | No | Minimum number of nodes in the cluster | +| `max_node_count` | `10` | No | Maximum number of nodes for autoscaling | +| `disk_size_gb` | `100` | No | Boot disk size for each node in GB | +| `enable_network_policy` | `true` | No | Enable Kubernetes network policies for security | + +
+ +## DNS configuration + +_Found in: DNS provider settings and `terraform/dns.tf`_ + +Set up your domain and subdomains according to the following convention: + +
+ +| Subdomain | Example FQDN | Purpose | Description | +| ------------ | ------------------------- | -------------- | --------------------------------- | +| `wallet` | `wallet.mywallet.com` | User Interface | Main wallet web application | +| `api` | `api.mywallet.com` | Wallet API | Wallet backend REST/GraphQL API | +| `auth` | `auth.mywallet.com` | Rafiki Auth | Rafiki authentication server | +| `backend` | `backend.mywallet.com` | Rafiki Backend | Rafiki payment processing backend | +| `admin` | `admin.mywallet.com` | Rafiki Admin | Rafiki administrative GraphQL API | +| `argocd` | `argocd.mywallet.com` | GitOps | Argo CD web interface | +| `grafana` | `grafana.mywallet.com` | Monitoring | Grafana dashboards | +| `prometheus` | `prometheus.mywallet.com` | Metrics | Prometheus metrics endpoint | + +
+ +## Database configuration + +### PostgreSQL variables + +
+ +| Variable | Example Value | Description | +| ------------------- | -------------------- | ------------------------------------------ | +| `POSTGRES_DB` | `rafiki` | Primary database name for Rafiki | +| `POSTGRES_USER` | `rafiki` | Database username for Rafiki services | +| `POSTGRES_PASSWORD` | `` | Database password (use Kubernetes secrets) | +| `WALLET_DB_NAME` | `wallet` | Database name for wallet application | +| `WALLET_DB_USER` | `wallet_user` | Database username for wallet application | +| `DB_HOST` | `rafiki-postgresql` | Database service hostname within cluster | +| `DB_PORT` | `5432` | Database port | +| `DB_SSL_MODE` | `require` | SSL mode for database connections | + +
+ +### Redis variables + +
+ +| Variable | Example Value | Description | +| ---------------- | ---------------------------------- | ------------------------------------------ | +| `REDIS_HOST` | `rafiki-redis-master` | Redis service hostname within cluster | +| `REDIS_PORT` | `6379` | Redis port | +| `REDIS_PASSWORD` | `` | Redis password (if authentication enabled) | +| `REDIS_DB` | `0` | Redis database number | +| `REDIS_URL` | `redis://rafiki-redis-master:6379` | Complete Redis connection URL | + +
+ +## Rafiki service configuration + +Configure your Rafiki services with these variables: + +### Rafiki auth service variables + +_Found in: `helm-values/rafiki/values.yaml` under `rafiki-auth.env` section_ + +
+ +| Variable | Example Value | Description | +| -------------------- | ---------------------------------------- | -------------------------------------- | +| `AUTH_DATABASE_URL` | `postgresql://rafiki:***@host:5432/auth` | Database connection for auth service | +| `AUTH_SERVER_URL` | `https://auth.mywallet.com` | Public URL for the auth server | +| `COOKIE_KEY` | `<32-byte-secret>` | Secret key for cookie encryption | +| `REDIS_URL` | `redis://redis:6379` | Redis connection for session storage | +| `NODE_ENVIRONMENT` | `production` | Runtime environment | +| `LOG_LEVEL` | `info` | Logging level | +| `TRUST_PROXY` | `true` | Enable when behind load balancer/proxy | +| `ADMIN_PORT` | `3003` | Port for auth admin API | +| `AUTH_PORT` | `3006` | Port for auth server | +| `INTROSPECTION_PORT` | `3007` | Port for token introspection | +| `INTERACTION_PORT` | `3009` | Port for user interaction flows | + +
+ +### Rafiki backend service variables + +_Found in: `helm-values/rafiki/values.yaml` under `rafiki-backend.env` section_ + +
+ +| Variable | Example Value | Description | +| -------------------- | ------------------------------------------ | ------------------------------------------ | +| `DATABASE_URL` | `postgresql://rafiki:***@host:5432/rafiki` | Main database connection | +| `REDIS_URL` | `redis://redis:6379` | Redis connection for caching | +| `WEBHOOK_URL` | `https://api.mywallet.com/webhooks/rafiki` | Webhook endpoint for payment notifications | +| `OPEN_PAYMENTS_URL` | `https://backend.mywallet.com` | Public URL for Open Payments API | +| `ILP_ADDRESS` | `test.mywallet` | ILP address for this instance | +| `ILP_CONNECTOR_URL` | `https://ilp.mywallet.com` | ILP connector endpoint | +| `EXCHANGE_RATES_URL` | `https://api.mywallet.com/rates` | Exchange rates endpoint | +| `PRIVATE_KEY_FILE` | `/path/to/private.key` | Private key file path | + +
+ +### Worker configuration variables + +_Found in: `helm-values/rafiki/values.yaml` under `rafiki-backend.env` section_ + +
+ +| Variable | Example Value | Description | +| ------------------------------ | ------------- | ------------------------------------------- | +| `OUTGOING_PAYMENT_WORKERS` | `1` | Number of outgoing payment workers | +| `INCOMING_PAYMENT_WORKERS` | `1` | Number of incoming payment workers | +| `WALLET_ADDRESS_WORKERS` | `1` | Number of wallet address processing workers | +| `WEBHOOK_WORKERS` | `1` | Number of webhook processing workers | +| `OUTGOING_PAYMENT_WORKER_IDLE` | `200` | Idle time (ms) for outgoing payment workers | +| `INCOMING_PAYMENT_WORKER_IDLE` | `200` | Idle time (ms) for incoming payment workers | +| `WALLET_ADDRESS_WORKER_IDLE` | `1000` | Idle time (ms) for wallet address workers | +| `WEBHOOK_WORKER_IDLE` | `200` | Idle time (ms) for webhook workers | + +
+ +### Additional Rafiki configuration + +_Found in: `helm-values/rafiki/values.yaml` under various sections (global, rafiki-backend.env)_ + +
+ +| Variable | Example Value | Description | +| --------------------- | --------------------------------------------- | ----------------------------------- | +| `PAYMENT_POINTER_URL` | `https://wallet.mywallet.com/.well-known/pay` | Payment pointer well-known endpoint | +| `AUTH_SERVER_SECRET` | `<32-byte-secret>` | Secret for auth server JWT signing | +| `USE_TIGERBEETLE` | `false` | Disable TigerBeetle for accounting | + +
+ +## TLS certificate configuration + +_Found in: `k8s-manifests/cert-manager/cluster-issuer.yaml`_ + +
+ +| Variable | Example Value | Description | +| --------------------- | ------------------------------------------------ | ------------------------------------------------ | +| `CERT_MANAGER_EMAIL` | `certificates@mywallet.com` | Email for Let's Encrypt certificate registration | +| `CLUSTER_ISSUER_NAME` | `letsencrypt-prod` | Name of the cert-manager cluster issuer | +| `ACME_SERVER` | `https://acme-v02.api.letsencrypt.org/directory` | ACME server URL (prod vs staging) | +| `CERT_SECRET_NAME` | `{service}-tls` | Pattern for TLS secret names | + +
+ +## Container image configuration + +_Found in: `helm-values/rafiki/values.yaml` and `helm-values/wallet/values.yaml` under image sections_ + +
+ +| Variable | Example Value | Description | +| ---------------------- | ------------------------------------------- | ---------------------------------- | +| `RAFIKI_AUTH_IMAGE` | `ghcr.io/interledger/rafiki-auth:latest` | Rafiki auth server container image | +| `RAFIKI_BACKEND_IMAGE` | `ghcr.io/interledger/rafiki-backend:latest` | Rafiki backend container image | +| `RAFIKI_ADMIN_IMAGE` | `ghcr.io/interledger/rafiki-admin:latest` | Rafiki admin API container image | +| `WALLET_UI_IMAGE` | `gcr.io/my-project/wallet-ui:v1.0.0` | Your wallet UI container image | +| `WALLET_API_IMAGE` | `gcr.io/my-project/wallet-api:v1.0.0` | Your wallet API container image | +| `POSTGRES_IMAGE` | `postgres:14` | PostgreSQL container image version | +| `REDIS_IMAGE` | `redis:7-alpine` | Redis container image version | + +
+ +## Resource limits + +_Found in: `helm-values/rafiki/values.yaml` and `helm-values/wallet/values.yaml` under resources sections_ + +
+ +| Resource Type | CPU Request | CPU Limit | Memory Request | Memory Limit | Description | +| -------------- | ----------- | --------- | -------------- | ------------ | ------------------------------------ | +| Rafiki Auth | `100m` | `500m` | `128Mi` | `512Mi` | Authentication server resources | +| Rafiki Backend | `200m` | `1000m` | `256Mi` | `1Gi` | Payment processing backend resources | +| Rafiki Admin | `100m` | `500m` | `128Mi` | `512Mi` | Admin API resources | +| Wallet API | `200m` | `1000m` | `256Mi` | `1Gi` | Wallet backend API resources | +| Wallet UI | `50m` | `200m` | `64Mi` | `256Mi` | Wallet frontend resources | +| PostgreSQL | `250m` | `1000m` | `256Mi` | `2Gi` | Database resources | +| Redis | `100m` | `500m` | `128Mi` | `512Mi` | Cache resources | + +
+ +## Storage configuration + +_Found in: `helm-values/rafiki/values.yaml` and `helm-values/wallet/values.yaml` under persistence sections_ + +
+ +| Storage Type | Size | Storage Class | Description | +| --------------- | ------- | ------------- | ---------------------------------------- | +| Rafiki Database | `20Gi` | `ssd` | Persistent storage for Rafiki PostgreSQL | +| Wallet Database | `50Gi` | `ssd` | Persistent storage for wallet PostgreSQL | +| Redis | `5Gi` | `ssd` | Persistent storage for Redis cache | +| Backup Storage | `100Gi` | `standard` | Storage for database backups | + +
+ +## Monitoring configuration + +_Found in: `k8s-manifests/monitoring/values.yaml`_ + +
+ +| Variable | Example Value | Description | +| ------------------------ | ----------------------------- | ------------------------------------- | +| `GRAFANA_ADMIN_PASSWORD` | `` | Grafana admin user password | +| `PROMETHEUS_RETENTION` | `15d` | How long to retain Prometheus metrics | +| `ALERTMANAGER_SLACK_URL` | `https://hooks.slack.com/...` | Slack webhook for alerts | +| `GRAFANA_SMTP_HOST` | `smtp.gmail.com:587` | SMTP server for Grafana notifications | +| `GRAFANA_SMTP_USER` | `notifications@mywallet.com` | SMTP username for email alerts | + +
+ +## Security configuration + +_Found in: `helm-values/rafiki/values.yaml` and `helm-values/wallet/values.yaml` under various security sections_ + +
+ +| Variable | Example Value | Description | +| ------------------------ | ------------- | ------------------------------------------- | +| `NETWORK_POLICY_ENABLED` | `true` | Enable Kubernetes network policies | +| `POD_SECURITY_STANDARD` | `restricted` | Pod security standard level | +| `SERVICE_ACCOUNT_NAME` | `rafiki-sa` | Kubernetes service account name | +| `RBAC_ENABLED` | `true` | Enable role-based access control | +| `ADMISSION_CONTROLLER` | `gatekeeper` | Admission controller for policy enforcement | + +
+ +## Backup configuration + +_Found in: `k8s-manifests/backup/postgres-backup.yaml`_ + +
+ +| Variable | Example Value | Description | +| ----------------------- | ----------------------- | ---------------------------------- | +| `BACKUP_SCHEDULE` | `0 2 * * *` | Cron schedule for database backups | +| `BACKUP_RETENTION_DAYS` | `30` | How many days to keep backups | +| `BACKUP_STORAGE_BUCKET` | `gs://mywallet-backups` | GCS bucket for storing backups | +| `BACKUP_ENCRYPTION_KEY` | `` | KMS key for backup encryption | + +
+ +## Environment-specific overrides + +### Development environment + +
+ +| Variable | Development Value | Description | +| ------------------- | ---------------------------------------------- | --------------------------------- | +| `ACME_SERVER` | `https://acme-staging-v02.api.letsencrypt.org` | Use Let's Encrypt staging for dev | +| `LOG_LEVEL` | `debug` | Enable debug logging | +| `REPLICA_COUNT` | `1` | Single replica for all services | +| `RESOURCE_REQUESTS` | `50% of production` | Lower resource requests | +| `STORAGE_SIZE` | `10Gi` | Smaller storage volumes | + +
+ +### Staging environment + +
+ +| Variable | Staging Value | Description | +| -------------------- | ------------------- | -------------------------------- | +| `REPLICA_COUNT` | `2` | Moderate replicas for testing | +| `RESOURCE_REQUESTS` | `75% of production` | Higher than dev, lower than prod | +| `MONITORING_ENABLED` | `true` | Full monitoring enabled | +| `BACKUP_ENABLED` | `false` | No backups in staging | + +
+ +### Production environment + +
+ +| Variable | Production Value | Description | +| ----------------------- | ----------------- | -------------------------- | +| `REPLICA_COUNT` | `3-5` | High availability replicas | +| `RESOURCE_REQUESTS` | `Full allocation` | Production resource limits | +| `MONITORING_ENABLED` | `true` | Comprehensive monitoring | +| `BACKUP_ENABLED` | `true` | Full backup strategy | +| `NETWORK_POLICIES` | `true` | Enhanced security | +| `POD_SECURITY_POLICIES` | `true` | Strict security policies | + +
+ +## DNS record configuration + +Configure these DNS A records pointing to your static IP: + +
+ +| Record Type | Name | Value | TTL | +| ----------- | ---------------------------- | ---------------- | --- | +| A | `wallet.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `api.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `auth.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `backend.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `admin.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `argocd.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `grafana.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | +| A | `prometheus.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + +
+ +## Note about placeholders + +All configuration files use these placeholder patterns that you must replace: + +- `YOUR_DOMAIN.com` - Replace with your actual domain +- `YOUR_PROJECT_ID` - Replace with your GCP project ID +- `YOUR_REGISTRY` - Replace with your container registry +- `YOUR_EMAIL` - Replace with your administrative email +- `` - Generate using `openssl rand -base64 32` (see Secrets Management guide) +- `` - Generate strong passwords for admin accounts + +Ensure you systematically replace all placeholder values before deployment to avoid configuration errors. + +## Next steps + +Now that you understand all the configuration variables, proceed to: + +1. **[Secrets management](/integration/deploy-to-prod/03-secrets-management)**: Generate and securely store all required secrets before infrastructure deployment +2. **[Infrastructure setup](/integration/deploy-to-prod/04-infrastructure-setup)**: Deploy GCP infrastructure using Terraform +3. **[Services deployment](/integration/deploy-to-prod/05-services-deployment)**: Install and configure Rafiki and wallet services diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/03-secrets-management.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/03-secrets-management.mdx new file mode 100644 index 0000000000..5fc1048ed0 --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/03-secrets-management.mdx @@ -0,0 +1,84 @@ +--- +title: Secrets management +--- + +Proper secrets management is critical for securing your Rafiki deployment. This section covers all types of secrets used in the architecture. + +:::note +You should generate and prepare all secrets before beginning infrastructure deployment. +::: + +## Types of secrets + +### Database credentials + +Database credentials are used by all services to connect to PostgreSQL and Redis instances. + +
+ +| Secret Type | Usage | +| ------------------ | ----------------------- | +| PostgreSQL Admin | Database administration | +| PostgreSQL Service | Application connections | +| Redis Password | Cache connections | + +
+ +### Application Secrets + +Application-specific secrets used by Rafiki services for encryption and authentication. + +
+ +| Secret Type | Usage | +| -------------------- | ---------------------------- | +| `COOKIE_KEY` | Session cookie encryption | +| `AUTH_SERVER_SECRET` | JWT token signing | +| `WEBHOOK_SECRET` | Webhook signature validation | +| `PRIVATE_KEY_FILE` | ILP packet signing | + +
+ +### TLS certificates + +TLS certificates for securing communications between services and external clients. + +
+ +| Certificate Type | Usage | +| ---------------- | ---------------------- | +| Let's Encrypt | Public HTTPS endpoints | +| Internal CA | Service-to-service | + +
+ +### External service credentials + +Credentials for connecting to external services and APIs. + +
+ +| Credential Type | Usage | +| ------------------- | -------------------- | +| GCP Service Account | Google Cloud APIs | +| Container Registry | Image pulls | +| Monitoring APIs | Metrics and alerting | + +
+ +## Best practices + +- **Generate strong secrets**: Use cryptographically secure methods to generate secrets +- **Secure Kubernetes namespaces**: Create Kubernetes secrets for each namespace +- **Use a secrets manager**: For enhanced security, store secrets in Google Cloud Secrets Manager or Hashicorp Vault +- **Rotate secrets on a regular basis**: Automate secret rotations with CronJobs + +## Next steps + +With your secrets securely generated and managed: + +1. **Secure storage**: Store your generated secrets in a secure location (not in Git!) +2. **[Setup infrastructure](/integration/deploy-to-prod/04-infrastructure-setup)**: Deploy GCP infrastructure using Terraform - you'll need these secrets during the deployment process +3. **[Deploy services](/integration/deploy-to-prod/05-services-deployment)**: Configure and deploy Rafiki and wallet services using your pre-generated secrets + +Proper secrets management is foundational to a secure Rafiki deployment. Regular rotation, secure storage, and comprehensive monitoring ensure your payment infrastructure remains protected. diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/04-infrastructure-setup.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/04-infrastructure-setup.mdx new file mode 100644 index 0000000000..b20a295187 --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/04-infrastructure-setup.mdx @@ -0,0 +1,270 @@ +--- +title: Infrastructure setup +--- + +This guide covers the infrastructure setup phase, including Terraform configuration, Google Kubernetes Engine (GKE) cluster deployment, and core Kubernetes components. + +:::caution +Before starting infrastructure deployment, ensure you have completed [configuration variables](/integration/deploy-to-prod/02-configuration-variables) review and [secrets management](/integration/deploy-to-prod/03-secrets-management) setup. You'll need generated secrets ready for the deployment process. +::: + +## Project structure + +Create the following directory structure for your infrastructure: + +``` +rafiki-wallet-infrastructure/ +├── terraform/ +│ ├── main.tf +│ ├── variables.tf +│ ├── outputs.tf +│ ├── gke.tf +│ ├── networking.tf +│ └── dns.tf +├── k8s-manifests/ +│ ├── argocd/ +│ ├── ingress-nginx/ +│ └── cert-manager/ +└── helm-values/ + ├── rafiki/ + └── wallet/ +``` + +## Terraform configuration + +### Main configuration + +Configure the Terraform providers and backend: + +```hcl +# terraform/main.tf +terraform { + required_version = ">= 1.0" + required_providers { + google = { + source = "hashicorp/google" + version = "~> 4.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.0" + } + } +} + +provider "google" { + project = var.project_id + region = var.region +} + +data "google_client_config" "default" {} + +provider "kubernetes" { + host = "https://${google_container_cluster.primary.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth.0.cluster_ca_certificate) +} +``` + +### Variables definition + +Define all the variables needed for your deployment: + +```hcl +# terraform/variables.tf +variable "project_id" { + description = "GCP Project ID" + type = string +} + +variable "region" { + description = "GCP Region" + type = string + default = "us-central1" +} + +variable "cluster_name" { + description = "GKE Cluster name" + type = string + default = "rafiki-wallet-cluster" +} + +variable "domain_name" { + description = "Domain name for the wallet" + type = string +} + +variable "node_pool_machine_type" { + description = "Machine type for GKE nodes" + type = string + default = "e2-standard-4" +} + +variable "min_node_count" { + description = "Minimum number of nodes in the cluster" + type = number + default = 1 +} + +variable "max_node_count" { + description = "Maximum number of nodes for autoscaling" + type = number + default = 10 +} + +variable "disk_size_gb" { + description = "Boot disk size for each node in GB" + type = number + default = 100 +} + +variable "enable_network_policy" { + description = "Enable Kubernetes network policies" + type = bool + default = true +} +``` + +### GKE cluster configuration + +Create a GKE cluster with security and scalability features: + +```hcl +# terraform/gke.tf +resource "google_container_cluster" "primary" { + name = var.cluster_name + location = var.region + + # We can't create a cluster with no node pool defined, but we want to only use + # separately managed node pools. So we create the smallest possible default + # node pool and immediately delete it. + remove_default_node_pool = true + initial_node_count = 1 + + network = google_compute_network.vpc.name + subnetwork = google_compute_subnetwork.subnet.name + + workload_identity_config { + workload_pool = "${var.project_id}.svc.id.goog" + } + + addons_config { + http_load_balancing { + disabled = false + } + horizontal_pod_autoscaling { + disabled = false + } + } + + network_policy { + enabled = var.enable_network_policy + } + + # Enable network policy addon if network policy is enabled + dynamic "addons_config" { + for_each = var.enable_network_policy ? [1] : [] + content { + network_policy_config { + disabled = false + } + } + } +} + +resource "google_container_node_pool" "primary_nodes" { + name = "${var.cluster_name}-node-pool" + location = var.region + cluster = google_container_cluster.primary.name + node_count = var.min_node_count + + node_config { + preemptible = false + machine_type = var.node_pool_machine_type + disk_size_gb = var.disk_size_gb + + service_account = google_service_account.kubernetes.email + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] + + workload_metadata_config { + mode = "GKE_METADATA" + } + + # Security settings + shielded_instance_config { + enable_secure_boot = true + enable_integrity_monitoring = true + } + } + + autoscaling { + min_node_count = var.min_node_count + max_node_count = var.max_node_count + } + + management { + auto_repair = true + auto_upgrade = true + } +} + +resource "google_service_account" "kubernetes" { + account_id = "${var.cluster_name}-sa" + display_name = "GKE Service Account for ${var.cluster_name}" +} + +# IAM binding for the service account +resource "google_project_iam_member" "kubernetes" { + project = var.project_id + role = "roles/container.nodeServiceAccount" + member = "serviceAccount:${google_service_account.kubernetes.email}" +} +``` + +### Networking configuration + +Set up virtual private cloud (VPC) networking with proper IP ranges and firewall rules: + +```hcl +# terraform/networking.tf +resource "google_compute_network" "vpc" { + name = "${var.cluster_name}-vpc" + auto_create_subnetworks = "false" +} + +resource "google_compute_subnetwork" "subnet" { + name = "${var.cluster_name}-subnet" + region = var.region + network = google_compute_network.vpc.name + ip_cidr_range = "10.10.0.0/24" + + secondary_ip_range { + range_name = "services-range" + ip_cidr_range = "192.168.1.0/24" + } + + secondary_ip_range { + range_name = "pod-ranges" + ip_cidr_range = "192.168.64.0/22" + } +} + +resource "google_compute_global_address" "ingress_ip" { + name = "${var.cluster_name}-ingress-ip" +} + +resource "google_compute_firewall" "allow_ingress" { + name = "${var.cluster_name}-allow-ingress" + network = google_compute_network.vpc.name + + allow { + protocol = "tcp" + ports = ["80", "443"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["gke-node"] +} +``` diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx new file mode 100644 index 0000000000..888d8e0272 --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx @@ -0,0 +1,964 @@ +--- +title: Services deployment +--- + +This guide covers deploying Rafiki services and your digital wallet application using Helm charts and Argo CD. + +## Rafiki deployment + +Set up the Rafiki namespace and required secrets: + +:::note +If you followed the recommended sequence, you should have already generated your secrets using the [secrets management guide](/integration/deploy-to-prod/03-secrets-management). The commands below assume you have the secrets ready to deploy. +::: + +```bash +# Create Rafiki namespace +kubectl create namespace rafiki + +# Create database credentials +kubectl create secret generic rafiki-db-secret \ + --from-literal=username=rafiki \ + --from-literal=password=$(openssl rand -base64 32) \ + --from-literal=postgres-password=$(openssl rand -base64 32) \ + --namespace rafiki + +# Create application secrets +kubectl create secret generic rafiki-secrets \ + --from-literal=auth-server-secret=$(openssl rand -base64 32) \ + --from-literal=cookie-key=$(openssl rand -base64 32) \ + --from-literal=webhook-secret=$(openssl rand -base64 32) \ + --namespace rafiki + +# Verify secrets +kubectl get secrets -n rafiki +``` + +### Rafiki Helm configuration + +Configure the Rafiki services with the following settings: + +```yaml +# helm-values/rafiki/values.yaml - CUSTOMIZE all YOUR_DOMAIN references +global: + image: + registry: ghcr.io + tag: 'latest' + +postgresql: + enabled: true + primary: + persistence: + size: 20Gi + storageClass: 'ssd' # Use SSD for better performance + auth: + existingSecret: rafiki-db-secret + secretKeys: + adminPasswordKey: postgres-password + userPasswordKey: password + metrics: + enabled: true # Enable PostgreSQL metrics + +redis: + enabled: true + architecture: standalone + auth: + enabled: false + master: + persistence: + size: 5Gi + metrics: + enabled: true # Enable Redis metrics + +rafiki-auth: + enabled: true + image: + repository: interledger/rafiki-auth + replicaCount: 2 # High availability + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/rate-limit: '100' # Rate limiting + hosts: + - host: auth.YOUR_DOMAIN.com # Replace with your domain + paths: + - path: / + pathType: Prefix + tls: + - secretName: rafiki-auth-tls + hosts: + - auth.YOUR_DOMAIN.com # Replace with your domain + env: + AUTH_DATABASE_URL: 'postgresql://rafiki:$(POSTGRES_PASSWORD)@rafiki-postgresql:5432/rafiki' + REDIS_URL: 'redis://rafiki-redis-master:6379' + COOKIE_KEY: + valueFrom: + secretKeyRef: + name: rafiki-secrets + key: cookie-key + TRUST_PROXY: 'true' # Enable proxy trust for GCP Load Balancer + NODE_ENVIRONMENT: 'production' # Set environment mode + LOG_LEVEL: 'info' # Set logging level + +rafiki-backend: + enabled: true + image: + repository: interledger/rafiki-backend + replicaCount: 3 # Scale for payment processing + resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 1000m + memory: 1Gi + ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/rate-limit: '1000' # Higher rate limit for payments + hosts: + - host: backend.YOUR_DOMAIN.com # Replace with your domain + paths: + - path: / + pathType: Prefix + tls: + - secretName: rafiki-backend-tls + hosts: + - backend.YOUR_DOMAIN.com # Replace with your domain + env: + DATABASE_URL: 'postgresql://rafiki:$(POSTGRES_PASSWORD)@rafiki-postgresql:5432/rafiki' + REDIS_URL: 'redis://rafiki-redis-master:6379' + WEBHOOK_URL: 'https://api.YOUR_DOMAIN.com/webhooks/rafiki' # Replace with your domain + OPEN_PAYMENTS_URL: 'https://backend.YOUR_DOMAIN.com' # Replace with your domain + ILP_ADDRESS: 'test.YOUR_DOMAIN' # Replace with your ILP address + ILP_CONNECTOR_URL: 'https://ilp.YOUR_DOMAIN.com' # Replace with your domain + EXCHANGE_RATES_URL: 'https://api.YOUR_DOMAIN.com/rates' # Replace with your domain + TRUST_PROXY: 'true' + NODE_ENVIRONMENT: 'production' + LOG_LEVEL: 'info' + # Worker configuration + OUTGOING_PAYMENT_WORKERS: '1' + INCOMING_PAYMENT_WORKERS: '1' + WALLET_ADDRESS_WORKERS: '1' + WEBHOOK_WORKERS: '1' + # Worker idle times (milliseconds) + OUTGOING_PAYMENT_WORKER_IDLE: '200' + INCOMING_PAYMENT_WORKER_IDLE: '200' + WALLET_ADDRESS_WORKER_IDLE: '1000' + WEBHOOK_WORKER_IDLE: '200' + # TigerBeetle configuration + USE_TIGERBEETLE: 'true' + TIGERBEETLE_CLUSTER_ID: '0' + TIGERBEETLE_REPLICA_ADDRESSES: '10.5.0.50:4342' + # Private key configuration + # PRIVATE_KEY_FILE: "/path/to/private.key" # Uncomment and configure as needed + # Volume mounts for private key file (if needed) + # volumes: + # - name: private-key + # secret: + # secretName: rafiki-private-key + # volumeMounts: + # - name: private-key + # mountPath: /path/to/private.key + # subPath: private.key + # readOnly: true + +rafiki-admin: + enabled: true + image: + repository: interledger/rafiki-admin + replicaCount: 2 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/rate-limit: '50' # Lower rate limit for admin + hosts: + - host: admin.YOUR_DOMAIN.com # Replace with your domain + paths: + - path: / + pathType: Prefix + tls: + - secretName: rafiki-admin-tls + hosts: + - admin.YOUR_DOMAIN.com # Replace with your domain + env: + DATABASE_URL: 'postgresql://rafiki:$(POSTGRES_PASSWORD)@rafiki-postgresql:5432/rafiki' + TRUST_PROXY: 'true' + +# Monitoring and observability +serviceMonitor: + enabled: true # Enable Prometheus monitoring + +# Network policies for security +networkPolicy: + enabled: true + ingress: + - from: + - namespaceSelector: + matchLabels: + name: ingress-nginx + - from: + - namespaceSelector: + matchLabels: + name: monitoring +``` + +### Deploy Rafiki with Argo CD + +Create an Argo CD application for Rafiki deployment: + +```yaml +# k8s-manifests/argocd/rafiki-application.yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: rafiki + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: https://interledger.github.io/charts/interledger + chart: rafiki + targetRevision: '*' + helm: + valueFiles: + - values.yaml + values: | + # Include your customized values here or reference from Git repo + global: + image: + registry: ghcr.io + tag: "latest" + # Add other values from helm-values/rafiki/values.yaml + destination: + server: https://kubernetes.default.svc + namespace: rafiki + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m +``` + +Deploy Rafiki using Argo CD: + +```bash +# Deploy Rafiki using Argo CD +kubectl apply -f k8s-manifests/argocd/rafiki-application.yaml + +# Monitor deployment +kubectl get applications -n argocd +argocd app sync rafiki +argocd app wait rafiki --health +``` + +## Digital wallet deployment + +Set up the wallet namespace and required secrets: + +```bash +# Create wallet namespace +kubectl create namespace wallet + +# Create wallet database secret +kubectl create secret generic wallet-db-secret \ + --from-literal=username=wallet \ + --from-literal=password=$(openssl rand -base64 32) \ + --from-literal=postgres-password=$(openssl rand -base64 32) \ + --from-literal=database-url="postgresql://wallet:$(openssl rand -base64 32)@wallet-postgresql:5432/wallet" \ + --namespace wallet + +# Create wallet application secrets +kubectl create secret generic wallet-secrets \ + --from-literal=jwt-secret=$(openssl rand -base64 32) \ + --from-literal=webhook-secret=$(openssl rand -base64 32) \ + --from-literal=session-secret=$(openssl rand -base64 32) \ + --namespace wallet + +# Create Redis secret +kubectl create secret generic wallet-redis-secret \ + --from-literal=password=$(openssl rand -base64 32) \ + --namespace wallet + +# If using private container registry, create image pull secret +kubectl create secret docker-registry gcr-json-key \ + --docker-server=gcr.io \ + --docker-username=_json_key \ + --docker-password="$(cat path/to/service-account-key.json)" \ + --docker-email=YOUR_EMAIL@YOUR_DOMAIN.com \ + --namespace wallet +``` + +### Wallet Helm configuration + +Configure your digital wallet application: + +```yaml +# helm-values/wallet/values.yaml - CUSTOMIZE all YOUR_DOMAIN and YOUR_REGISTRY references +replicaCount: 3 # High availability + +image: + repository: YOUR_REGISTRY/digital-wallet # Replace with your container registry + tag: 'v1.0.0' # Replace with your wallet version + pullPolicy: IfNotPresent + +imagePullSecrets: + - name: gcr-json-key # If using private registry + +service: + type: ClusterIP + port: 80 + targetPort: 3000 + +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/rate-limit: '1000' + nginx.ingress.kubernetes.io/ssl-redirect: 'true' + hosts: + - host: wallet.YOUR_DOMAIN.com # Replace with your domain + paths: + - path: / + pathType: Prefix + tls: + - secretName: wallet-tls + hosts: + - wallet.YOUR_DOMAIN.com # Replace with your domain + +resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 1000m + memory: 1Gi + +autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + +config: + rafiki: + authServerUrl: 'https://auth.YOUR_DOMAIN.com' # Replace with your domain + backendUrl: 'https://backend.YOUR_DOMAIN.com' # Replace with your domain + adminUrl: 'https://admin.YOUR_DOMAIN.com' # Replace with your domain + database: + url: 'postgresql://wallet:$(POSTGRES_PASSWORD)@wallet-postgresql:5432/wallet' + redis: + url: 'redis://wallet-redis-master:6379' + +# Separate PostgreSQL for wallet data +postgresql: + enabled: true + nameOverride: 'wallet-postgresql' + primary: + persistence: + size: 50Gi + storageClass: 'ssd' + auth: + database: 'wallet' + username: 'wallet' + existingSecret: wallet-db-secret + secretKeys: + adminPasswordKey: postgres-password + userPasswordKey: password + +# Separate Redis for wallet sessions +redis: + enabled: true + nameOverride: 'wallet-redis' + architecture: standalone + auth: + enabled: true + existingSecret: wallet-redis-secret + existingSecretPasswordKey: password + +# Environment variables for wallet application +env: + - name: RAFIKI_AUTH_SERVER_URL + value: 'https://auth.YOUR_DOMAIN.com' # Replace with your domain + - name: RAFIKI_BACKEND_URL + value: 'https://backend.YOUR_DOMAIN.com' # Replace with your domain + - name: RAFIKI_ADMIN_URL + value: 'https://admin.YOUR_DOMAIN.com' # Replace with your domain + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: wallet-db-secret + key: database-url + - name: REDIS_URL + value: 'redis://wallet-redis-master:6379' + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: wallet-secrets + key: jwt-secret + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: wallet-secrets + key: webhook-secret + - name: NODE_ENV + value: 'production' + - name: LOG_LEVEL + value: 'info' +``` + +### Create wallet API ingress + +Set up additional ingress for wallet API: + +```yaml +# k8s-manifests/wallet/api-ingress.yaml - CUSTOMIZE host field +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: wallet-api-ingress + namespace: wallet + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/ssl-redirect: 'true' + nginx.ingress.kubernetes.io/rate-limit: '500' +spec: + ingressClassName: nginx + tls: + - hosts: + - api.YOUR_DOMAIN.com # Replace with your domain + secretName: wallet-api-tls + rules: + - host: api.YOUR_DOMAIN.com # Replace with your domain + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: wallet-api + port: + number: 80 +``` + +### Deploy wallet with Argo CD + +Create an Argo CD application for wallet deployment: + +```yaml +# k8s-manifests/argocd/wallet-application.yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: digital-wallet + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: https://github.com/YOUR_ORG/wallet-helm-charts # Replace with your repo + path: charts/digital-wallet + targetRevision: HEAD + helm: + valueFiles: + - values.yaml + destination: + server: https://kubernetes.default.svc + namespace: wallet + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m +``` + +Deploy the wallet application: + +```bash +# Apply wallet API ingress +kubectl apply -f k8s-manifests/wallet/api-ingress.yaml + +# Deploy wallet using Argo CD +kubectl apply -f k8s-manifests/argocd/wallet-application.yaml + +# Monitor deployment +kubectl get applications -n argocd +argocd app sync digital-wallet +argocd app wait digital-wallet --health +``` + +## Service verification + +### Health checks + +Verify all services are running correctly: + +```bash +# Check Rafiki service health endpoints +curl -k https://auth.YOUR_DOMAIN.com/health +curl -k https://backend.YOUR_DOMAIN.com/health +curl -k https://admin.YOUR_DOMAIN.com/health + +# Check wallet application +curl -k https://wallet.YOUR_DOMAIN.com/health +curl -k https://api.YOUR_DOMAIN.com/health + +# Verify payment pointer resolution +curl -k https://backend.YOUR_DOMAIN.com/.well-known/pay +``` + +### Database Initialization + +Initialize databases with required schemas: + +```bash +# Connect to Rafiki database and run migrations (if needed) +kubectl exec -it -n rafiki deployment/rafiki-admin -- npm run migrate + +# Verify database tables +kubectl exec -it -n rafiki rafiki-postgresql-0 -- psql -U rafiki -d rafiki -c "\dt" + +# Connect to wallet database and run migrations +kubectl exec -it -n wallet deployment/wallet-api -- npm run migrate + +# Verify wallet database +kubectl exec -it -n wallet wallet-postgresql-0 -- psql -U wallet -d wallet -c "\dt" +``` + +## Monitoring setup + +### Install monitoring stack + +Configure monitoring with Prometheus and Grafana: + +```yaml +# k8s-manifests/monitoring/values.yaml - CUSTOMIZE domain references +prometheus: + prometheusSpec: + retention: 15d + storageSpec: + volumeClaimTemplate: + spec: + storageClassName: ssd + accessModes: ['ReadWriteOnce'] + resources: + requests: + storage: 30Gi + ingress: + enabled: true + ingressClassName: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - prometheus.YOUR_DOMAIN.com # Replace with your domain + tls: + - secretName: prometheus-tls + hosts: + - prometheus.YOUR_DOMAIN.com # Replace with your domain + +grafana: + adminPassword: 'CHANGE_THIS_PASSWORD' # Replace with secure password + ingress: + enabled: true + ingressClassName: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - grafana.YOUR_DOMAIN.com # Replace with your domain + tls: + - secretName: grafana-tls + hosts: + - grafana.YOUR_DOMAIN.com # Replace with your domain + + # SMTP configuration for alerts + smtp: + enabled: true + host: 'smtp.gmail.com:587' # Replace with your SMTP server + user: 'notifications@YOUR_DOMAIN.com' # Replace with your email + password: 'YOUR_SMTP_PASSWORD' # Replace with your SMTP password + from_address: 'notifications@YOUR_DOMAIN.com' # Replace with your email + +alertmanager: + alertmanagerSpec: + storage: + volumeClaimTemplate: + spec: + storageClassName: ssd + accessModes: ['ReadWriteOnce'] + resources: + requests: + storage: 5Gi + config: + global: + smtp_smarthost: 'smtp.gmail.com:587' # Replace with your SMTP server + smtp_from: 'alerts@YOUR_DOMAIN.com' # Replace with your email + route: + group_by: ['alertname'] + group_wait: 10s + group_interval: 10s + repeat_interval: 1h + receiver: 'web.hook' + receivers: + - name: 'web.hook' + slack_configs: + - api_url: 'YOUR_SLACK_WEBHOOK_URL' # Replace with your Slack webhook + channel: '#alerts' + title: 'Rafiki Wallet Alert' +``` + +Install the monitoring stack: + +```bash +# Add Prometheus community repo +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update + +# Install kube-prometheus-stack with custom values +helm install monitoring prometheus-community/kube-prometheus-stack \ + --namespace monitoring \ + --create-namespace \ + -f k8s-manifests/monitoring/values.yaml + +# Verify monitoring installation +kubectl get pods -n monitoring +kubectl get svc -n monitoring +kubectl get ingress -n monitoring +``` + +## Post-deployment configuration + +### Initialize Rafiki assets + +Create initial assets and configuration for Rafiki: + +```bash +# Create a script to initialize Rafiki with basic assets +cat > initialize-rafiki.sh << 'EOF' +#!/bin/bash + +# Get admin API endpoint +ADMIN_URL="https://admin.YOUR_DOMAIN.com" + +# Create USD asset +curl -X POST $ADMIN_URL/graphql \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -d '{ + "query": "mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { asset { id code scale } } }", + "variables": { + "input": { + "code": "USD", + "scale": 2 + } + } + }' + +# Create EUR asset +curl -X POST $ADMIN_URL/graphql \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -d '{ + "query": "mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { asset { id code scale } } }", + "variables": { + "input": { + "code": "EUR", + "scale": 2 + } + } + }' + +echo "Assets created successfully" +EOF + +chmod +x initialize-rafiki.sh +``` + +### Set up backup jobs + +Configure automated database backups: + +```yaml +# k8s-manifests/backup/postgres-backup.yaml - CUSTOMIZE GCS bucket and project ID +apiVersion: batch/v1 +kind: CronJob +metadata: + name: postgres-backup + namespace: rafiki +spec: + schedule: '0 2 * * *' # Daily at 2 AM + jobTemplate: + spec: + template: + spec: + serviceAccountName: backup-sa + containers: + - name: postgres-backup + image: google/cloud-sdk:alpine + command: + - /bin/bash + - -c + - | + BACKUP_DATE=$(date +%Y%m%d-%H%M%S) + + # Backup Rafiki database + pg_dump $RAFIKI_DATABASE_URL | gzip > /tmp/rafiki-backup-${BACKUP_DATE}.sql.gz + gsutil cp /tmp/rafiki-backup-${BACKUP_DATE}.sql.gz gs://YOUR_PROJECT-backups/rafiki/ + + # Backup Wallet database + pg_dump $WALLET_DATABASE_URL | gzip > /tmp/wallet-backup-${BACKUP_DATE}.sql.gz + gsutil cp /tmp/wallet-backup-${BACKUP_DATE}.sql.gz gs://YOUR_PROJECT-backups/wallet/ + + # Cleanup old backups (keep last 30 days) + gsutil -m rm gs://YOUR_PROJECT-backups/rafiki/rafiki-backup-$(date -d '30 days ago' +%Y%m%d)*.sql.gz || true + gsutil -m rm gs://YOUR_PROJECT-backups/wallet/wallet-backup-$(date -d '30 days ago' +%Y%m%d)*.sql.gz || true + env: + - name: RAFIKI_DATABASE_URL + valueFrom: + secretKeyRef: + name: rafiki-db-secret + key: database-url + - name: WALLET_DATABASE_URL + valueFrom: + secretKeyRef: + name: wallet-db-secret + key: database-url + restartPolicy: OnFailure +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: backup-sa + namespace: rafiki + annotations: + iam.gke.io/gcp-service-account: backup-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com # Replace with your project ID +``` + +Create the backup infrastructure: + +```bash +# Create GCS bucket for backups +gsutil mb gs://YOUR_PROJECT-backups + +# Apply backup job +kubectl apply -f k8s-manifests/backup/postgres-backup.yaml + +# Test backup job manually +kubectl create job --from=cronjob/postgres-backup manual-backup -n rafiki +``` + +## Security hardening + +### Network policies + +Implement network policies for enhanced security: + +```yaml +# k8s-manifests/security/network-policies.yaml +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: rafiki-network-policy + namespace: rafiki +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + name: ingress-nginx + - from: + - namespaceSelector: + matchLabels: + name: wallet + ports: + - protocol: TCP + port: 80 + egress: + - to: [] + ports: + - protocol: TCP + port: 53 + - protocol: UDP + port: 53 + - to: + - namespaceSelector: + matchLabels: + name: wallet +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: wallet-network-policy + namespace: wallet +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + name: ingress-nginx + - from: + - namespaceSelector: + matchLabels: + name: rafiki + egress: + - to: [] + ports: + - protocol: TCP + port: 53 + - protocol: UDP + port: 53 + - to: + - namespaceSelector: + matchLabels: + name: rafiki +``` + +Apply network policies: + +```bash +# Label namespaces for network policies +kubectl label namespace ingress-nginx name=ingress-nginx +kubectl label namespace rafiki name=rafiki +kubectl label namespace wallet name=wallet + +# Apply network policies +kubectl apply -f k8s-manifests/security/network-policies.yaml +``` + +## Deployment verification + +### Service status verification + +Check all services are running correctly: + +```bash +# Verify all pods are running +kubectl get pods -n rafiki +kubectl get pods -n wallet +kubectl get pods -n monitoring + +# Check services +kubectl get svc -n rafiki +kubectl get svc -n wallet + +# Check ingress +kubectl get ingress -A + +# Check certificates +kubectl get certificates -A +``` + +## Service URLs summary + +Your deployed services are available at these URLs: + +| Service | URL | Purpose | +| ------------------ | ---------------------------------- | ------------------------------ | +| **Wallet UI** | https://wallet.YOUR_DOMAIN.com | User-facing wallet application | +| **Wallet API** | https://api.YOUR_DOMAIN.com | Wallet backend API | +| **Rafiki Auth** | https://auth.YOUR_DOMAIN.com | Authentication server | +| **Rafiki Backend** | https://backend.YOUR_DOMAIN.com | Payment processing | +| **Rafiki Admin** | https://admin.YOUR_DOMAIN.com | Administrative API | +| **Argo CD** | https://argocd.YOUR_DOMAIN.com | GitOps management | +| **Grafana** | https://grafana.YOUR_DOMAIN.com | Monitoring dashboards | +| **Prometheus** | https://prometheus.YOUR_DOMAIN.com | Metrics collection | + +## Performance optimization + +### Database performance tuning + +Optimize PostgreSQL settings: + +```sql +-- Connect to PostgreSQL and optimize settings +-- For Rafiki database +ALTER SYSTEM SET shared_buffers = '256MB'; +ALTER SYSTEM SET effective_cache_size = '1GB'; +ALTER SYSTEM SET maintenance_work_mem = '64MB'; +ALTER SYSTEM SET checkpoint_completion_target = 0.9; +ALTER SYSTEM SET wal_buffers = '16MB'; +ALTER SYSTEM SET default_statistics_target = 100; + +-- Reload configuration +SELECT pg_reload_conf(); + +-- Create indexes for better performance +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_payments_wallet_address_id ON payments(wallet_address_id); +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_payments_created_at ON payments(created_at); +``` + +### Resource scaling + +Monitor and adjust resource allocations based on actual usage: + +```bash +# Check resource usage +kubectl top nodes +kubectl top pods -n rafiki +kubectl top pods -n wallet + +# Scale deployments based on load +kubectl scale deployment rafiki-backend --replicas=5 -n rafiki +kubectl scale deployment wallet-api --replicas=5 -n wallet + +# Enable horizontal pod autoscaling if not already enabled +kubectl autoscale deployment rafiki-backend --cpu-percent=70 --min=3 --max=10 -n rafiki +kubectl autoscale deployment wallet-api --cpu-percent=70 --min=3 --max=10 -n wallet +``` + +## Next steps + +With your services deployed, you can now: + +1. **Configure monitoring alerts**: Set up alerting rules for monitoring +2. **Implement backup verification**: Test backup and restore procedures +3. **Test performance**: Conduct load testing to validate scaling configuration +4. **Review security**: Perform security audit and penetration testing +5. **[Troubleshoot issues](/integration/deploy-to-prod/06-troubleshooting)**: Address any deployment issues + +Your Rafiki infrastructure is now fully deployed and ready for integration with your digital wallet application! diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx new file mode 100644 index 0000000000..2ecca1c938 --- /dev/null +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx @@ -0,0 +1,139 @@ +--- +title: Troubleshooting +--- + +This guide helps diagnose and resolve common issues when deploying and integrating Rafiki with your digital wallet. + +## Pre-deployment checklist + +Before troubleshooting issues, ensure you've completed all required customizations: + +### Required customizations + +
+ +| File/Location | Variables to Update | +| ----------------------------- | ------------------------------------- | +| `terraform.tfvars` | `project_id`, `domain_name`, `region` | +| `cluster-issuer.yaml` | `email` field | +| `argocd/ingress.yaml` | `host` fields | +| `ingress-nginx/values.yaml` | `loadBalancerIP` | +| `rafiki/values.yaml` | All `YOUR_DOMAIN.com` references | +| `wallet/values.yaml` | `YOUR_DOMAIN.com`, `YOUR_REGISTRY` | +| `monitoring/values.yaml` | Domain references, passwords, SMTP | +| `backup/postgres-backup.yaml` | GCS bucket, project ID | +| Environment secrets | Database passwords, API tokens | +| DNS records | Point domains to static IP | + +
+ +### Security checklist + +
+ +| Security Item | Description | +| ------------------ | -------------------------------------------------------- | +| TLS Certificates | Let's Encrypt configured for all domains | +| Database Passwords | Strong, randomly generated passwords | +| API Secrets | 32-byte secrets for auth and webhooks | +| Network Policies | Enabled to restrict pod-to-pod communication | +| RBAC | Proper service accounts and permissions | +| Image Security | Using official images with known vulnerabilities patched | +| Backup Encryption | KMS encryption for backup data | + +
+ +## Common issues and solutions + +### Infrastructure issues + +#### Issue: Error creating cluster + +**Solutions:** + +1. **Check GCP permissions:** + + ```bash + # Verify current user has required permissions + gcloud auth list + gcloud projects get-iam-policy PROJECT_ID + + # Add required roles + gcloud projects add-iam-policy-binding PROJECT_ID \ + --member="user:your-email@domain.com" \ + --role="roles/container.admin" + ``` + +2. **Enable required APIs:** + + ```bash + gcloud services enable container.googleapis.com + gcloud services enable compute.googleapis.com + gcloud services enable dns.googleapis.com + ``` + +3. **Check quota limits:** + ```bash + gcloud compute project-info describe --project=PROJECT_ID + ``` + +#### Issue: GKE Cluster Creation Hangs + +**Symptoms:** + +- Terraform hangs on cluster creation +- Cluster shows "PROVISIONING" status for extended time + +**Solutions:** + +1. **Check region availability:** + + ```bash + # List available zones in region + gcloud compute zones list --filter="region:us-central1" + + # Try different region + terraform apply -var="region=us-east1" + ``` + +2. **Reduce initial node count:** + + ```bash + terraform apply -var="min_node_count=1" + ``` + +3. **Check for resource conflicts:** + + ```bash + # List existing clusters + gcloud container clusters list + + # Clean up if needed + gcloud container clusters delete OLD_CLUSTER_NAME --region=REGION + ``` + +### DNS and Certificate Issues + +#### Issue: Certificate Not Issued + +**Symptoms:** + +```bash +kubectl get certificates -A +NAME READY SECRET AGE +rafiki-auth-tls False rafiki-auth-tls 10m +``` + +**Debugging:** + +```bash +# Check certificate status +kubectl describe certificate rafiki-auth-tls -n rafiki + +# Check certificate request +kubectl get certificaterequests -A +kubectl describe certificaterequest -n rafiki + +# Check cert-manager logs +kubectl logs -n cert-manager deployment/ +``` diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx deleted file mode 100644 index fe007735ac..0000000000 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/gcp-prerequisites-guide.mdx +++ /dev/null @@ -1,882 +0,0 @@ ---- -title: GCP prerequisites ---- - -## Complete Step-by-Step Instructions for Google Cloud Platform Setup - -This guide provides detailed instructions for setting up all Google Cloud Platform prerequisites required for deploying Rafiki with TigerBeetle on Kubernetes. - -## Table of Contents - -1. [Initial GCP Account Setup](#initial-gcp-account-setup) -2. [Project Creation and Configuration](#project-creation-and-configuration) -3. [Billing Setup](#billing-setup) -4. [CLI Tools Installation](#cli-tools-installation) -5. [Service Account Setup](#service-account-setup) -6. [API Enablement](#api-enablement) -7. [IAM Permissions Configuration](#iam-permissions-configuration) -8. [Network Infrastructure Setup](#network-infrastructure-setup) -9. [DNS Setup](#dns-setup) -10. [Security Configuration](#security-configuration) -11. [Verification and Testing](#verification-and-testing) - -## Initial GCP Account Setup - -### Step 1: Create Google Cloud Account - -1. **Visit Google Cloud Console** - ``` - Navigate to: https://console.cloud.google.com - ``` - -2. **Sign in or Create Account** - - If you have a Google account, sign in - - If not, create a new Google account - - Accept Google Cloud Terms of Service - -3. **Activate Free Trial (if eligible)** - - Click "Activate" for the $300 free credit - - Provide payment information (required but won't be charged during trial) - - Complete identity verification - -### Step 2: Verify Account Status - -```bash -# Check if you're logged in correctly -gcloud auth list - -# Should show your account email -``` - -## Project Creation and Configuration - -### Step 1: Create New Project - -1. **Via Google Cloud Console:** - - Go to the project selector dropdown (top of the page) - - Click "New Project" - - Enter project details: - - **Project Name**: `rafiki-production` (or your preferred name) - - **Project ID**: `rafiki-prod-[random-string]` (must be globally unique) - - **Organization**: Select your organization (if applicable) - - Click "Create" - -2. **Via Command Line:** - ```bash - # Set your desired project ID (must be globally unique) - export PROJECT_ID="rafiki-prod-$(date +%s)" - export PROJECT_NAME="Rafiki Production" - - # Create the project - gcloud projects create $PROJECT_ID --name="$PROJECT_NAME" - - # Verify project creation - gcloud projects list --filter="PROJECT_ID:$PROJECT_ID" - ``` - -### Step 2: Set Default Project - -```bash -# Set the project as your default -gcloud config set project $PROJECT_ID - -# Verify the setting -gcloud config get-value project -``` - -### Step 3: Enable Project for Billing - -```bash -# List available billing accounts -gcloud billing accounts list - -# Link project to billing account (replace BILLING_ACCOUNT_ID) -export BILLING_ACCOUNT_ID="your-billing-account-id" -gcloud billing projects link $PROJECT_ID --billing-account=$BILLING_ACCOUNT_ID - -# Verify billing is enabled -gcloud billing projects describe $PROJECT_ID -``` - -## Billing Setup - -### Step 1: Configure Billing Account - -1. **Access Billing Console:** - ``` - Navigate to: https://console.cloud.google.com/billing - ``` - -2. **Create or Select Billing Account:** - - If no billing account exists, click "Create Account" - - Fill in payment details and billing information - - If billing account exists, select it - -3. **Set Billing Alerts:** - ```bash - # Create budget alert at $100/month - gcloud billing budgets create \ - --billing-account=$BILLING_ACCOUNT_ID \ - --display-name="Rafiki Production Budget" \ - --budget-amount=100USD \ - --threshold-rule=percent=50,basis=CURRENT_SPEND \ - --threshold-rule=percent=90,basis=CURRENT_SPEND \ - --threshold-rule=percent=100,basis=CURRENT_SPEND - ``` - -### Step 2: Enable Detailed Billing Export - -```bash -# Create BigQuery dataset for billing export -bq mk --location=US billing_export - -# Configure billing export (replace with your BigQuery dataset) -gcloud billing accounts get-iam-policy $BILLING_ACCOUNT_ID -``` - -## CLI Tools Installation - -### Step 1: Install Google Cloud SDK - -#### For Linux/macOS: -```bash -# Download and install -curl https://sdk.cloud.google.com | bash - -# Restart shell or source profile -exec -l $SHELL - -# Initialize gcloud -gcloud init -``` - -#### For Windows: -1. Download installer from: https://cloud.google.com/sdk/docs/install -2. Run the installer -3. Follow installation prompts -4. Open new Command Prompt/PowerShell -5. Run: `gcloud init` - -### Step 2: Install kubectl - -```bash -# Install kubectl via gcloud -gcloud components install kubectl - -# Verify installation -kubectl version --client -``` - -### Step 3: Install Helm - -#### For Linux/macOS: -```bash -# Download and install Helm -curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash - -# Verify installation -helm version -``` - -#### For Windows: -```powershell -# Using Chocolatey -choco install kubernetes-helm - -# Or download from: https://github.com/helm/helm/releases -``` - -### Step 4: Install Additional Tools - -```bash -# Install additional gcloud components -gcloud components install gke-gcloud-auth-plugin -gcloud components install beta -gcloud components install alpha - -# Update all components -gcloud components update -``` - -## Service Account Setup - -### Step 1: Create Service Accounts - -```bash -# Create service account for Rafiki application -gcloud iam service-accounts create rafiki-sa \ - --description="Service account for Rafiki application" \ - --display-name="Rafiki Service Account" - -# Create service account for GKE nodes -gcloud iam service-accounts create rafiki-node-sa \ - --description="Service account for GKE nodes" \ - --display-name="Rafiki Node Service Account" - -# Create service account for CI/CD (if needed) -gcloud iam service-accounts create rafiki-cicd-sa \ - --description="Service account for CI/CD pipeline" \ - --display-name="Rafiki CI/CD Service Account" -``` - -### Step 2: Generate Service Account Keys - -```bash -# Create key for Rafiki application service account -gcloud iam service-accounts keys create rafiki-sa-key.json \ - --iam-account=rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com - -# Create key for CI/CD service account (if needed) -gcloud iam service-accounts keys create rafiki-cicd-key.json \ - --iam-account=rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com - -# Secure the keys -chmod 600 *.json -``` - -### Step 3: Set Up Workload Identity (Recommended) - -```bash -# Enable Workload Identity on the project -gcloud container clusters update rafiki-cluster \ - --workload-pool=$PROJECT_ID.svc.id.goog \ - --zone=us-central1-a - -# Create Kubernetes service account -kubectl create serviceaccount rafiki-ksa \ - --namespace=rafiki - -# Bind Kubernetes SA to Google SA -gcloud iam service-accounts add-iam-policy-binding \ - --role roles/iam.workloadIdentityUser \ - --member "serviceAccount:$PROJECT_ID.svc.id.goog[rafiki/rafiki-ksa]" \ - rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com - -# Annotate Kubernetes service account -kubectl annotate serviceaccount rafiki-ksa \ - --namespace=rafiki \ - iam.gke.io/gcp-service-account=rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com -``` - -## API Enablement - -### Step 1: Enable Required APIs - -```bash -# Core APIs for GKE and compute -gcloud services enable container.googleapis.com -gcloud services enable compute.googleapis.com -gcloud services enable containerregistry.googleapis.com -gcloud services enable artifactregistry.googleapis.com - -# Storage and database APIs -gcloud services enable storage.googleapis.com -gcloud services enable sql.googleapis.com -gcloud services enable redis.googleapis.com - -# Networking APIs -gcloud services enable dns.googleapis.com -gcloud services enable networkmanagement.googleapis.com -gcloud services enable servicenetworking.googleapis.com - -# Security and monitoring APIs -gcloud services enable cloudasset.googleapis.com -gcloud services enable cloudresourcemanager.googleapis.com -gcloud services enable monitoring.googleapis.com -gcloud services enable logging.googleapis.com - -# Certificate management -gcloud services enable certificatemanager.googleapis.com -gcloud services enable networkconnectivity.googleapis.com - -# Additional security APIs -gcloud services enable cloudkms.googleapis.com -gcloud services enable secretmanager.googleapis.com -gcloud services enable binaryauthorization.googleapis.com -``` - -### Step 2: Verify API Enablement - -```bash -# List all enabled APIs -gcloud services list --enabled - -# Check specific API status -gcloud services list --enabled --filter="NAME:container.googleapis.com" -``` - -### Step 3: Set API Usage Quotas (if needed) - -```bash -# Check current quotas -gcloud compute project-info describe --format="table(quotas.metric,quotas.limit,quotas.usage)" - -# Request quota increase if needed -echo "If you need quota increases, visit:" -echo "https://console.cloud.google.com/iam-admin/quotas" -``` - -## IAM Permissions Configuration - -### Step 1: Assign Roles to User Account - -```bash -# Get your user account email -export USER_EMAIL=$(gcloud config get-value account) - -# Assign required roles to your user account -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="user:$USER_EMAIL" \ - --role="roles/container.admin" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="user:$USER_EMAIL" \ - --role="roles/compute.admin" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="user:$USER_EMAIL" \ - --role="roles/storage.admin" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="user:$USER_EMAIL" \ - --role="roles/dns.admin" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="user:$USER_EMAIL" \ - --role="roles/iam.serviceAccountAdmin" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="user:$USER_EMAIL" \ - --role="roles/resourcemanager.projectIamAdmin" -``` - -### Step 2: Assign Roles to Service Accounts - -```bash -# Roles for Rafiki application service account -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/storage.objectViewer" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/monitoring.metricWriter" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/logging.logWriter" - -# Roles for GKE node service account -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-node-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/container.nodeServiceAgent" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-node-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/storage.objectViewer" - -# Roles for CI/CD service account -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/container.developer" - -gcloud projects add-iam-policy-binding $PROJECT_ID \ - --member="serviceAccount:rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/storage.admin" -``` - -### Step 3: Create Custom IAM Role (if needed) - -```bash -# Create custom role for specific Rafiki permissions -cat < rafiki-custom-role.yaml -title: "Rafiki Custom Role" -description: "Custom role for Rafiki application with minimal required permissions" -stage: "GA" -includedPermissions: -- container.clusters.get -- container.clusters.list -- storage.objects.create -- storage.objects.delete -- storage.objects.get -- storage.objects.list -- monitoring.timeSeries.create -- logging.logEntries.create -EOF - -# Create the custom role -gcloud iam roles create rafikiCustomRole \ - --project=$PROJECT_ID \ - --file=rafiki-custom-role.yaml -``` - -## Network Infrastructure Setup - -### Step 1: Create VPC Network - -```bash -# Create custom VPC network -gcloud compute networks create rafiki-vpc \ - --subnet-mode=custom \ - --bgp-routing-mode=regional - -# Create subnet for GKE cluster -gcloud compute networks subnets create rafiki-subnet \ - --network=rafiki-vpc \ - --range=10.0.0.0/16 \ - --region=us-central1 \ - --secondary-range=pods=10.1.0.0/16,services=10.2.0.0/16 - -# Create subnet for private services (Cloud SQL, etc.) -gcloud compute networks subnets create rafiki-private-subnet \ - --network=rafiki-vpc \ - --range=10.3.0.0/16 \ - --region=us-central1 -``` - -### Step 2: Configure Firewall Rules - -```bash -# Allow internal communication -gcloud compute firewall-rules create rafiki-allow-internal \ - --network=rafiki-vpc \ - --allow=tcp,udp,icmp \ - --source-ranges=10.0.0.0/8 - -# Allow SSH access (for debugging) -gcloud compute firewall-rules create rafiki-allow-ssh \ - --network=rafiki-vpc \ - --allow=tcp:22 \ - --source-ranges=0.0.0.0/0 \ - --target-tags=ssh-allowed - -# Allow HTTPS traffic -gcloud compute firewall-rules create rafiki-allow-https \ - --network=rafiki-vpc \ - --allow=tcp:443 \ - --source-ranges=0.0.0.0/0 \ - --target-tags=https-server - -# Allow HTTP traffic (for health checks) -gcloud compute firewall-rules create rafiki-allow-http \ - --network=rafiki-vpc \ - --allow=tcp:80 \ - --source-ranges=0.0.0.0/0 \ - --target-tags=http-server - -# Allow load balancer health checks -gcloud compute firewall-rules create rafiki-allow-health-checks \ - --network=rafiki-vpc \ - --allow=tcp \ - --source-ranges=130.211.0.0/22,35.191.0.0/16 \ - --target-tags=gke-cluster -``` - -### Step 3: Set Up Private Service Connection - -```bash -# Reserve IP range for private services -gcloud compute addresses create google-managed-services-rafiki-vpc \ - --global \ - --purpose=VPC_PEERING \ - --prefix-length=16 \ - --network=rafiki-vpc - -# Create private connection -gcloud services vpc-peerings connect \ - --service=servicenetworking.googleapis.com \ - --ranges=google-managed-services-rafiki-vpc \ - --network=rafiki-vpc -``` - -### Step 4: Create Cloud NAT (for private nodes) - -```bash -# Create Cloud Router -gcloud compute routers create rafiki-router \ - --network=rafiki-vpc \ - --region=us-central1 - -# Create Cloud NAT -gcloud compute routers nats create rafiki-nat \ - --router=rafiki-router \ - --region=us-central1 \ - --nat-all-subnet-ip-ranges \ - --auto-allocate-subnetwork-range -``` - -## DNS Setup - -### Step 1: Create Cloud DNS Zone - -```bash -# Set your domain name -export DOMAIN_NAME="your-bank-domain.com" - -# Create DNS zone -gcloud dns managed-zones create rafiki-zone \ - --description="DNS zone for Rafiki deployment" \ - --dns-name=$DOMAIN_NAME \ - --visibility=public - -# Get name servers -gcloud dns managed-zones describe rafiki-zone \ - --format="value(nameServers[].join(' '))" -``` - -### Step 2: Configure Domain Registrar - -```bash -echo "Update your domain registrar with these name servers:" -gcloud dns managed-zones describe rafiki-zone \ - --format="table(nameServers[].join(chr(10)))" - -echo "" -echo "Steps to update at your domain registrar:" -echo "1. Log into your domain registrar's control panel" -echo "2. Find DNS or Name Server settings" -echo "3. Replace existing name servers with the ones listed above" -echo "4. Save changes (may take 24-48 hours to propagate)" -``` - -### Step 3: Create Initial DNS Records - -```bash -# Reserve static IP for load balancer -gcloud compute addresses create rafiki-static-ip \ - --global - -# Get the IP address -export STATIC_IP=$(gcloud compute addresses describe rafiki-static-ip \ - --global --format="get(address)") - -# Create A record for main domain -gcloud dns record-sets transaction start --zone=rafiki-zone - -gcloud dns record-sets transaction add $STATIC_IP \ - --name=$DOMAIN_NAME. \ - --ttl=300 \ - --type=A \ - --zone=rafiki-zone - -# Create A records for subdomains -gcloud dns record-sets transaction add $STATIC_IP \ - --name=admin.$DOMAIN_NAME. \ - --ttl=300 \ - --type=A \ - --zone=rafiki-zone - -gcloud dns record-sets transaction add $STATIC_IP \ - --name=auth.$DOMAIN_NAME. \ - --ttl=300 \ - --type=A \ - --zone=rafiki-zone - -gcloud dns record-sets transaction execute --zone=rafiki-zone -``` - -## Security Configuration - -### Step 1: Enable Security Features - -```bash -# Enable Security Command Center (if available in your region) -gcloud alpha scc settings enable --organization=$(gcloud organizations list --format="value(name)") - -# Enable audit logging -cat < audit-policy.yaml -auditConfigs: -- service: allServices - auditLogConfigs: - - logType: ADMIN_READ - - logType: DATA_READ - - logType: DATA_WRITE -EOF - -gcloud logging sinks create rafiki-audit-sink \ - storage.googleapis.com/rafiki-audit-logs-$PROJECT_ID \ - --log-filter='protoPayload.serviceName="container.googleapis.com"' -``` - -### Step 2: Set Up Secret Manager - -```bash -# Create secrets in Secret Manager -echo -n "$(openssl rand -base64 32)" | \ - gcloud secrets create rafiki-database-password --data-file=- - -echo -n "$(openssl rand -base64 64)" | \ - gcloud secrets create rafiki-jwt-secret --data-file=- - -echo -n "$(openssl rand -base64 32)" | \ - gcloud secrets create rafiki-webhook-secret --data-file=- - -# Grant access to service account -gcloud secrets add-iam-policy-binding rafiki-database-password \ - --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/secretmanager.secretAccessor" - -gcloud secrets add-iam-policy-binding rafiki-jwt-secret \ - --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/secretmanager.secretAccessor" - -gcloud secrets add-iam-policy-binding rafiki-webhook-secret \ - --member="serviceAccount:rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" \ - --role="roles/secretmanager.secretAccessor" -``` - -### Step 3: Configure Binary Authorization (Optional) - -```bash -# Create Binary Authorization policy -cat < binary-authorization-policy.yaml -defaultAdmissionRule: - requireAttestationsBy: [] - enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG - evaluationMode: REQUIRE_ATTESTATION -clusterAdmissionRules: - us-central1-a.rafiki-cluster: - requireAttestationsBy: [] - enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG - evaluationMode: ALWAYS_ALLOW -EOF - -gcloud container binauthz policy import binary-authorization-policy.yaml -``` - -## Verification and Testing - -### Step 1: Verify Project Setup - -```bash -# Check project configuration -gcloud config list - -# Verify billing is enabled -gcloud billing projects describe $PROJECT_ID - -# Check enabled APIs -gcloud services list --enabled | grep -E "(container|compute|storage|dns)" -``` - -### Step 2: Test Network Connectivity - -```bash -# Test VPC creation -gcloud compute networks describe rafiki-vpc - -# Test subnet creation -gcloud compute networks subnets describe rafiki-subnet --region=us-central1 - -# Test firewall rules -gcloud compute firewall-rules list --filter="network:rafiki-vpc" -``` - -### Step 3: Test DNS Configuration - -```bash -# Test DNS zone -gcloud dns managed-zones describe rafiki-zone - -# Test DNS resolution (may take time to propagate) -nslookup $DOMAIN_NAME -``` - -### Step 4: Test Service Account Permissions - -```bash -# Test service account impersonation -gcloud auth activate-service-account --key-file=rafiki-sa-key.json - -# Test basic permissions -gcloud compute instances list -gcloud container clusters list - -# Switch back to user account -gcloud auth login -``` - -### Step 5: Create Test Resources - -```bash -# Create a small test VM to verify setup -gcloud compute instances create test-vm \ - --zone=us-central1-a \ - --machine-type=e2-micro \ - --subnet=rafiki-subnet \ - --no-address \ - --image-family=ubuntu-2004-lts \ - --image-project=ubuntu-os-cloud \ - --tags=ssh-allowed - -# Test SSH access (should work through Cloud NAT) -gcloud compute ssh test-vm --zone=us-central1-a --command="curl -s http://metadata.google.internal/computeMetadata/v1/instance/hostname -H 'Metadata-Flavor: Google'" - -# Clean up test VM -gcloud compute instances delete test-vm --zone=us-central1-a --quiet -``` - -## Environment Variables Export - -### Step 1: Create Environment Configuration File - -```bash -# Create environment configuration file -cat < rafiki-env.sh -#!/bin/bash -# Rafiki GCP Environment Configuration - -export PROJECT_ID="$PROJECT_ID" -export PROJECT_NAME="$PROJECT_NAME" -export BILLING_ACCOUNT_ID="$BILLING_ACCOUNT_ID" -export DOMAIN_NAME="$DOMAIN_NAME" -export STATIC_IP="$STATIC_IP" - -# GCP Configuration -export REGION="us-central1" -export ZONE="us-central1-a" -export CLUSTER_NAME="rafiki-cluster" -export NAMESPACE="rafiki" - -# Network Configuration -export VPC_NAME="rafiki-vpc" -export SUBNET_NAME="rafiki-subnet" - -# Service Accounts -export RAFIKI_SA="rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com" -export NODE_SA="rafiki-node-sa@$PROJECT_ID.iam.gserviceaccount.com" -export CICD_SA="rafiki-cicd-sa@$PROJECT_ID.iam.gserviceaccount.com" - -# DNS Configuration -export DNS_ZONE="rafiki-zone" - -echo "GCP environment configured for Rafiki deployment" -echo "Project ID: \$PROJECT_ID" -echo "Domain: \$DOMAIN_NAME" -echo "Static IP: \$STATIC_IP" -EOF - -chmod +x rafiki-env.sh -``` - -### Step 2: Load Environment - -```bash -# Source the environment -source rafiki-env.sh - -# Add to your shell profile for persistence -echo "source $(pwd)/rafiki-env.sh" >> ~/.bashrc -``` - -## Final Verification Checklist - -Create a verification script to ensure everything is set up correctly: - -```bash -#!/bin/bash -# rafiki-verification.sh - -echo "🔍 Verifying GCP Prerequisites for Rafiki Deployment" -echo "==================================================" - -# Check if project is set -echo -n "✅ Project configuration: " -if [ "$(gcloud config get-value project)" == "$PROJECT_ID" ]; then - echo "✓ Configured correctly" -else - echo "❌ Project not set correctly" - exit 1 -fi - -# Check billing -echo -n "✅ Billing status: " -if gcloud billing projects describe $PROJECT_ID --format="value(billingEnabled)" | grep -q "True"; then - echo "✓ Billing enabled" -else - echo "❌ Billing not enabled" - exit 1 -fi - -# Check required APIs -echo "✅ Required APIs:" -APIS=("container.googleapis.com" "compute.googleapis.com" "storage.googleapis.com" "dns.googleapis.com") -for api in "${APIS[@]}"; do - if gcloud services list --enabled --filter="NAME:$api" --format="value(NAME)" | grep -q "$api"; then - echo " ✓ $api" - else - echo " ❌ $api not enabled" - exit 1 - fi -done - -# Check VPC -echo -n "✅ VPC Network: " -if gcloud compute networks describe rafiki-vpc &>/dev/null; then - echo "✓ VPC created" -else - echo "❌ VPC not found" - exit 1 -fi - -# Check DNS -echo -n "✅ DNS Zone: " -if gcloud dns managed-zones describe rafiki-zone &>/dev/null; then - echo "✓ DNS zone created" -else - echo "❌ DNS zone not found" - exit 1 -fi - -# Check service accounts -echo -n "✅ Service Accounts: " -if gcloud iam service-accounts describe rafiki-sa@$PROJECT_ID.iam.gserviceaccount.com &>/dev/null; then - echo "✓ Service accounts created" -else - echo "❌ Service accounts not found" - exit 1 -fi - -echo "" -echo "🎉 All prerequisites verified successfully!" -echo "You're ready to proceed with Rafiki deployment." -``` - -Make the script executable and run it: - -```bash -chmod +x rafiki-verification.sh -./rafiki-verification.sh -``` - -## Next Steps - -After completing all prerequisites: - -1. **Save all generated keys and configuration files securely** -2. **Document your specific configuration values** -3. **Proceed to the main Rafiki deployment guide** -4. **Set up monitoring and alerting for your GCP resources** - -## Cost Optimization Tips - -To minimize costs during setup and testing: - -```bash -# Set up automatic cleanup for test resources -gcloud compute instances list --format="value(name,zone)" | \ -while read name zone; do - if [[ $name == test-* ]]; then - gcloud compute instances delete $name --zone=$zone --quiet - fi -done - -# Set up budget alerts to avoid unexpected charges -gcloud billing budgets create \ - --billing-account=$BILLING_ACCOUNT_ID \ - --display-name="Rafiki Development Budget" \ - --budget-amount=50USD \ - --threshold-rule=percent=80,basis=CURRENT_SPEND -``` - -This comprehensive setup ensures your GCP environment is properly configured for a production-ready Rafiki deployment with all necessary security, networking, and access controls in place. diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx deleted file mode 100644 index 441b58c093..0000000000 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/rafiki-deployment-testnet.mdx +++ /dev/null @@ -1,1017 +0,0 @@ ---- -title: Rafiki-deployment-testnet ---- - -### Table of Contents -1. [Overview](#overview) -2. [Prerequisites](#prerequisites) -3. [Architecture Overview](#architecture-overview) -4. [Infrastructure Setup with Terraform](#infrastructure-setup-with-terraform) -5. [Kubernetes Deployment](#kubernetes-deployment) -6. [Rafiki Configuration](#rafiki-configuration) -7. [Security Considerations](#security-considerations) -8. [Monitoring and Observability](#monitoring-and-observability) -9. [Testing and Validation](#testing-and-validation) -10. [Production Deployment](#production-deployment) -11. [Maintenance and Operations](#maintenance-and-operations) - ---- - -## Overview - -Rafiki is open source software that provides an efficient solution for an Account Servicing Entity to enable Interledger functionality on its users' accounts. This guide provides a comprehensive deployment strategy for financial institutions looking to integrate Rafiki into their existing infrastructure using modern cloud-native technologies. - -**Key Components:** -- **Rafiki Backend**: Includes an Interledger connector, a high-throughput accounting database called TigerBeetle, and several APIs -- **Open Payments API**: For third-party payment initiation -- **Admin APIs**: For managing peering relationships and supported assets -- **GNAP Authorization Server**: Access control for Open Payments API - ---- - -## Prerequisites - -### Technical Requirements -- **Google Cloud Platform Account** with billing enabled -- **Terraform** >= 1.0 -- **Helm** >= 3.7.2 -- **kubectl** >= 1.20 -- **Docker** for local development -- **Git** for version control - -### Financial Institution Requirements -- **Regulatory Compliance**: Ensure compliance with local financial regulations -- **KYC/AML Processes**: Integration with existing compliance systems -- **Risk Management**: Established risk assessment frameworks -- **Security Policies**: Enterprise-grade security protocols - -### Domain and DNS -- Registered domain for your institution -- SSL/TLS certificates (Let's Encrypt or commercial) -- DNS management access - ---- - -## Architecture Overview - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Google Cloud Platform │ -├─────────────────────────────────────────────────────────────────┤ -│ GKE Cluster │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ -│ │ Rafiki │ │ TigerBeetle │ │ PostgreSQL │ │ -│ │ Backend │ │ Accounting │ │ Auth DB │ │ -│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ -│ │ Auth Server │ │ Redis Cache │ │ Monitoring │ │ -│ │ (GNAP) │ │ │ │ Stack │ │ -│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ -├─────────────────────────────────────────────────────────────────┤ -│ Supporting Services │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ -│ │ Cloud SQL │ │ Cloud Storage │ │ Cloud KMS │ │ -│ │ (Backup) │ │ (Artifacts) │ │ (Secrets) │ │ -│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Infrastructure Setup with Terraform - -### Project Structure - -``` -rafiki-infrastructure/ -├── environments/ -│ ├── dev/ -│ │ ├── main.tf -│ │ ├── variables.tf -│ │ └── terraform.tfvars -│ ├── staging/ -│ │ ├── main.tf -│ │ ├── variables.tf -│ │ └── terraform.tfvars -│ └── prod/ -│ ├── main.tf -│ ├── variables.tf -│ └── terraform.tfvars -├── modules/ -│ ├── gke/ -│ ├── networking/ -│ ├── security/ -│ └── storage/ -├── helm-charts/ -└── scripts/ -``` - -### Core Terraform Configuration - -#### 1. Provider Configuration (`providers.tf`) - -```hcl -terraform { - required_version = ">= 1.0" - required_providers { - google = { - source = "hashicorp/google" - version = "~> 4.0" - } - google-beta = { - source = "hashicorp/google-beta" - version = "~> 4.0" - } - kubernetes = { - source = "hashicorp/kubernetes" - version = "~> 2.0" - } - helm = { - source = "hashicorp/helm" - version = "~> 2.0" - } - } - - backend "gcs" { - bucket = "your-bank-terraform-state" - prefix = "rafiki/terraform.tfstate" - } -} - -provider "google" { - project = var.project_id - region = var.region - zone = var.zone -} - -provider "google-beta" { - project = var.project_id - region = var.region - zone = var.zone -} - -data "google_client_config" "default" {} - -provider "kubernetes" { - host = "https://${module.gke.endpoint}" - token = data.google_client_config.default.access_token - cluster_ca_certificate = base64decode(module.gke.ca_certificate) -} - -provider "helm" { - kubernetes { - host = "https://${module.gke.endpoint}" - token = data.google_client_config.default.access_token - cluster_ca_certificate = base64decode(module.gke.ca_certificate) - } -} -``` - -#### 2. Variables Configuration (`variables.tf`) - -```hcl -variable "project_id" { - description = "GCP Project ID" - type = string -} - -variable "region" { - description = "GCP Region" - type = string - default = "us-central1" -} - -variable "zone" { - description = "GCP Zone" - type = string - default = "us-central1-a" -} - -variable "environment" { - description = "Environment name (dev, staging, prod)" - type = string -} - -variable "organization_name" { - description = "Your bank or financial institution name" - type = string -} - -variable "domain_name" { - description = "Your institution's domain name" - type = string -} - -variable "gke_node_count" { - description = "Number of GKE nodes" - type = number - default = 3 -} - -variable "gke_machine_type" { - description = "GKE node machine type" - type = string - default = "e2-standard-4" -} - -variable "enable_tigerbeetle" { - description = "Enable TigerBeetle for high-performance accounting" - type = bool - default = true -} -``` - -#### 3. Main Infrastructure (`main.tf`) - -```hcl -locals { - name_prefix = "${var.organization_name}-rafiki-${var.environment}" - common_labels = { - environment = var.environment - organization = var.organization_name - managed_by = "terraform" - application = "rafiki" - } -} - -# VPC Network -module "networking" { - source = "./modules/networking" - - name_prefix = local.name_prefix - project_id = var.project_id - region = var.region - common_labels = local.common_labels -} - -# GKE Cluster -module "gke" { - source = "./modules/gke" - - name_prefix = local.name_prefix - project_id = var.project_id - region = var.region - zone = var.zone - network_name = module.networking.network_name - subnet_name = module.networking.subnet_name - node_count = var.gke_node_count - machine_type = var.gke_machine_type - common_labels = local.common_labels -} - -# Cloud SQL for PostgreSQL (Auth services) -module "postgresql" { - source = "./modules/storage" - - name_prefix = local.name_prefix - project_id = var.project_id - region = var.region - network_id = module.networking.network_id - database_name = "rafiki_auth" - common_labels = local.common_labels -} - -# Security and Secrets Management -module "security" { - source = "./modules/security" - - name_prefix = local.name_prefix - project_id = var.project_id - region = var.region - common_labels = local.common_labels -} - -# DNS and SSL -resource "google_dns_managed_zone" "rafiki_zone" { - name = "${replace(local.name_prefix, "-", "")}zone" - dns_name = "${var.environment}.${var.domain_name}." - description = "DNS zone for Rafiki ${var.environment} environment" - - labels = local.common_labels -} - -# Static IP for Load Balancer -resource "google_compute_global_address" "rafiki_ip" { - name = "${local.name_prefix}-ip" - ip_version = "IPV4" - address_type = "EXTERNAL" -} -``` - -### GKE Module (`modules/gke/main.tf`) - -```hcl -resource "google_container_cluster" "rafiki_cluster" { - name = "${var.name_prefix}-cluster" - location = var.region - - # Enable Workload Identity - workload_identity_config { - workload_pool = "${var.project_id}.svc.id.goog" - } - - # Network configuration - network = var.network_name - subnetwork = var.subnet_name - - # Security configuration - enable_shielded_nodes = true - - # Remove default node pool - remove_default_node_pool = true - initial_node_count = 1 - - # Addons - addons_config { - network_policy_config { - disabled = false - } - - horizontal_pod_autoscaling { - disabled = false - } - - istio_config { - disabled = false - auth = "AUTH_MUTUAL_TLS" - } - } - - # Enable network policy - network_policy { - enabled = true - } - - # Private cluster configuration for production - private_cluster_config { - enable_private_nodes = true - enable_private_endpoint = false - master_ipv4_cidr_block = "172.16.0.0/28" - } - - # IP allocation policy - ip_allocation_policy { - cluster_secondary_range_name = "gke-pods" - services_secondary_range_name = "gke-services" - } - - master_auth { - client_certificate_config { - issue_client_certificate = false - } - } -} - -resource "google_container_node_pool" "rafiki_nodes" { - name = "${var.name_prefix}-node-pool" - location = var.region - cluster = google_container_cluster.rafiki_cluster.name - node_count = var.node_count - - # Auto-scaling configuration - autoscaling { - min_node_count = 1 - max_node_count = 10 - } - - # Node configuration - node_config { - preemptible = var.environment != "prod" - machine_type = var.machine_type - disk_size_gb = 100 - disk_type = "pd-ssd" - - # Security - shielded_instance_config { - enable_secure_boot = true - enable_integrity_monitoring = true - } - - # Service account - service_account = google_service_account.gke_nodes.email - oauth_scopes = [ - "https://www.googleapis.com/auth/logging.write", - "https://www.googleapis.com/auth/monitoring", - "https://www.googleapis.com/auth/devstorage.read_only", - ] - - # Labels - labels = var.common_labels - } - - # Update strategy - management { - auto_repair = true - auto_upgrade = true - } -} - -resource "google_service_account" "gke_nodes" { - account_id = "${var.name_prefix}-gke-nodes" - display_name = "GKE Nodes Service Account" -} -``` - ---- - -## Kubernetes Deployment - -### Namespace and RBAC - -```yaml -# k8s/namespaces.yaml -apiVersion: v1 -kind: Namespace -metadata: - name: rafiki-system - labels: - name: rafiki-system - istio-injection: enabled ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: rafiki-backend - namespace: rafiki-system - annotations: - iam.gke.io/gcp-service-account: rafiki-backend@PROJECT_ID.iam.gserviceaccount.com -``` - -### Using Interledger Helm Charts - -Add the Interledger Helm repository: - -```bash -# Add the Interledger Helm repository -helm repo add interledger https://interledger.github.io/helm-charts -helm repo update - -# Search available charts -helm search repo interledger -``` - -### Rafiki Configuration Values - -Create a `values-production.yaml` file: - -```yaml -# values-production.yaml -rafiki: - backend: - image: - repository: interledger/rafiki - tag: "latest" - pullPolicy: IfNotPresent - - replicaCount: 3 - - env: - # Database Configuration - DATABASE_URL: "postgresql://rafiki:password@postgresql:5432/rafiki_auth" - - # TigerBeetle Configuration (if enabled) - TIGERBEETLE_CLUSTER_ID: "0" - TIGERBEETLE_REPLICA_ADDRESSES: "tigerbeetle:3000" - - # Open Payments Configuration - OPEN_PAYMENTS_URL: "https://rafiki.yourdomain.com" - - # Interledger Configuration - ILP_ADDRESS: "g.yourdomain" - ILP_CONNECTOR_ADDRESS: "0.0.0.0:4000" - - # Auth Configuration - AUTH_SERVER_GRANT_URL: "https://auth.yourdomain.com" - AUTH_SERVER_INTROSPECTION_URL: "https://auth.yourdomain.com/introspect" - - # Redis Configuration - REDIS_URL: "redis://redis:6379" - - # Logging - LOG_LEVEL: "info" - - resources: - requests: - memory: "512Mi" - cpu: "500m" - limits: - memory: "2Gi" - cpu: "2000m" - - service: - type: ClusterIP - port: 3001 - - ingress: - enabled: true - className: "nginx" - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - hosts: - - host: rafiki.yourdomain.com - paths: - - path: / - pathType: Prefix - tls: - - secretName: rafiki-tls - hosts: - - rafiki.yourdomain.com - -# TigerBeetle Configuration -tigerbeetle: - enabled: true - replicaCount: 3 - - image: - repository: tigerbeetle/tigerbeetle - tag: "latest" - pullPolicy: IfNotPresent - - persistence: - enabled: true - storageClass: "ssd" - size: 100Gi - - resources: - requests: - memory: "1Gi" - cpu: "1000m" - limits: - memory: "4Gi" - cpu: "4000m" - -# PostgreSQL Configuration -postgresql: - enabled: true - - auth: - username: rafiki - database: rafiki_auth - existingSecret: rafiki-db-secret - - primary: - persistence: - enabled: true - storageClass: "ssd" - size: 50Gi - - resources: - requests: - memory: "512Mi" - cpu: "500m" - limits: - memory: "2Gi" - cpu: "2000m" - -# Redis Configuration -redis: - enabled: true - - auth: - enabled: true - existingSecret: redis-secret - - master: - persistence: - enabled: true - storageClass: "ssd" - size: 20Gi - -# Auth Server Configuration -authServer: - enabled: true - - image: - repository: interledger/rafiki-auth - tag: "latest" - - replicaCount: 2 - - env: - DATABASE_URL: "postgresql://rafiki:password@postgresql:5432/rafiki_auth" - IDENTITY_SERVER_URL: "https://auth.yourdomain.com" - - service: - type: ClusterIP - port: 3006 - - ingress: - enabled: true - className: "nginx" - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - hosts: - - host: auth.yourdomain.com - paths: - - path: / - pathType: Prefix - tls: - - secretName: auth-tls - hosts: - - auth.yourdomain.com - -# Monitoring Configuration -monitoring: - prometheus: - enabled: true - grafana: - enabled: true - adminPassword: "secure-password" - -# Security -securityContext: - runAsNonRoot: true - runAsUser: 1001 - fsGroup: 1001 - -# Network Policies -networkPolicy: - enabled: true -``` - ---- - -## Security Considerations - -### 1. Secrets Management - -```bash -# Create required secrets -kubectl create secret generic rafiki-db-secret \ - --from-literal=username=rafiki \ - --from-literal=password=your-secure-password \ - -n rafiki-system - -kubectl create secret generic redis-secret \ - --from-literal=redis-password=your-redis-password \ - -n rafiki-system - -# TLS Certificates (using cert-manager) -kubectl apply -f - < r.status === 200, - 'response time < 500ms': (r) => r.timings.duration < 500, - }); -} -``` - ---- - -## Production Deployment - -### Pre-deployment Checklist - -- [ ] **Security Review**: Penetration testing completed -- [ ] **Compliance Verification**: Regulatory requirements met -- [ ] **Backup Strategy**: Database and configuration backups configured -- [ ] **Disaster Recovery**: Recovery procedures documented and tested -- [ ] **Monitoring**: All alerts and dashboards configured -- [ ] **Performance Testing**: Load testing completed successfully -- [ ] **Documentation**: Operational runbooks completed - -### Deployment Steps - -```bash -# 1. Deploy infrastructure -cd environments/prod -terraform init -terraform plan -var-file=terraform.tfvars -terraform apply - -# 2. Configure kubectl -gcloud container clusters get-credentials rafiki-prod-cluster \ - --region us-central1 \ - --project your-project-id - -# 3. Install cert-manager -kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml - -# 4. Install ingress controller -helm upgrade --install ingress-nginx ingress-nginx \ - --repo https://kubernetes.github.io/ingress-nginx \ - --namespace ingress-nginx \ - --create-namespace - -# 5. Deploy Rafiki -helm upgrade --install rafiki interledger/rafiki \ - -f values-production.yaml \ - -n rafiki-system \ - --create-namespace \ - --wait - -# 6. Verify deployment -kubectl get pods -n rafiki-system -kubectl get ingress -n rafiki-system -``` - -### Post-deployment Validation - -```bash -# Health checks -curl -f https://rafiki.yourdomain.com/health -curl -f https://auth.yourdomain.com/health - -# Admin API test -curl -X POST https://rafiki.yourdomain.com/graphql \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $ADMIN_TOKEN" \ - -d '{"query": "query { peers { edges { node { id staticIlpAddress } } } }"}' - -# Open Payments discovery -curl https://rafiki.yourdomain.com/.well-known/open_payments_authz -``` - ---- - -## Maintenance and Operations - -### Regular Maintenance Tasks - -1. **Weekly**: - - Review monitoring dashboards - - Check security alerts - - Verify backup integrity - -2. **Monthly**: - - Update Helm charts - - Review resource utilization - - Security patch updates - -3. **Quarterly**: - - Disaster recovery testing - - Security audit - - Performance optimization review - -### Backup and Recovery - -```bash -# Database backup script -#!/bin/bash -BACKUP_NAME="rafiki-backup-$(date +%Y%m%d-%H%M%S)" - -# Create database backup -kubectl exec -n rafiki-system deployment/postgresql -- \ - pg_dump -U rafiki rafiki_auth > $BACKUP_NAME.sql - -# Upload to Cloud Storage -gsutil cp $BACKUP_NAME.sql gs://your-backup-bucket/ -``` - -### Scaling Considerations - -- **Horizontal Pod Autoscaling**: Configure HPA for backend services -- **Vertical Pod Autoscaling**: Optimize resource requests/limits -- **Database Scaling**: Consider read replicas for high-read workloads -- **TigerBeetle Scaling**: TigerBeetle is optimized for online transaction processing (OLTP) workloads, offering significantly higher performance - -### Troubleshooting Guide - -Common issues and solutions: - -1. **Pod Startup Issues**: - ```bash - kubectl describe pod -n rafiki-system - kubectl logs -f deployment/rafiki-backend -n rafiki-system - ``` - -2. **Database Connection Issues**: - ```bash - kubectl exec -n rafiki-system deployment/rafiki-backend -- \ - nc -zv postgresql 5432 - ``` - -3. **TLS Certificate Issues**: - ```bash - kubectl describe certificate -n rafiki-system - kubectl describe certificaterequest -n rafiki-system - ``` - ---- - -## Conclusion - -This guide provides a comprehensive foundation for deploying Rafiki in a production environment. By harnessing TigerBeetle's advanced features, Rafiki offers Account Servicing Entities (ASEs) a powerful and dependable solution for implementing Interledger functionality. - -Key success factors: -- **Security-first approach** with proper secrets management -- **Scalable architecture** using Kubernetes best practices -- **Comprehensive monitoring** for operational excellence -- **Automated deployment** with Terraform and Helm -- **Compliance readiness** for financial regulations - -For additional support and community resources, visit the [Interledger Community](https://community.interledger.org/) and the [Rafiki GitHub repository](https://github.com/interledger/rafiki). From 75b09c8bde52ffcb994699a58a9de3306297ddc2 Mon Sep 17 00:00:00 2001 From: hajjimo Date: Fri, 1 Aug 2025 21:51:43 +0200 Subject: [PATCH 3/6] docs: mi/3419/rafiki-testnet-deployment-guide --- .../integration/deploy-to-prod/01-architecture-overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx index ec530a9d4c..bc0153516d 100644 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx @@ -27,7 +27,7 @@ Before beginning the integration, ensure you have the following: - Helm installed - kubectl installed and configured -- The argocd CLI (optional) +- The argocd CLI - Domain name for your wallet (required for SSL/TLS certificates) ## Architecture overview From 1f3278f4c3375b9c33385533c528679bccb989a3 Mon Sep 17 00:00:00 2001 From: Max Kurapov Date: Wed, 6 Aug 2025 13:00:32 +0200 Subject: [PATCH 4/6] test(backend): update actionable incoming payment test --- .../backend/src/open_payments/payment/incoming/service.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/open_payments/payment/incoming/service.test.ts b/packages/backend/src/open_payments/payment/incoming/service.test.ts index a59a46cc4d..f140625339 100644 --- a/packages/backend/src/open_payments/payment/incoming/service.test.ts +++ b/packages/backend/src/open_payments/payment/incoming/service.test.ts @@ -78,7 +78,7 @@ describe('Incoming Payment Service', (): void => { return { pollIncomingPaymentCreatedWebhook: true, incomingPaymentCreatedPollFrequency: 1, - incomingPaymentCreatedPollTimeout: 100 + incomingPaymentCreatedPollTimeout: 300 } } async function patchIncomingPaymentHelper(options: { From 7a3910c8705c755ebea7efe5b884a27cc00e9c94 Mon Sep 17 00:00:00 2001 From: Max Kurapov Date: Wed, 6 Aug 2025 13:16:40 +0200 Subject: [PATCH 5/6] Revert "test(backend): update actionable incoming payment test" This reverts commit 1f3278f4c3375b9c33385533c528679bccb989a3. --- .../backend/src/open_payments/payment/incoming/service.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/open_payments/payment/incoming/service.test.ts b/packages/backend/src/open_payments/payment/incoming/service.test.ts index f140625339..a59a46cc4d 100644 --- a/packages/backend/src/open_payments/payment/incoming/service.test.ts +++ b/packages/backend/src/open_payments/payment/incoming/service.test.ts @@ -78,7 +78,7 @@ describe('Incoming Payment Service', (): void => { return { pollIncomingPaymentCreatedWebhook: true, incomingPaymentCreatedPollFrequency: 1, - incomingPaymentCreatedPollTimeout: 300 + incomingPaymentCreatedPollTimeout: 100 } } async function patchIncomingPaymentHelper(options: { From 78cb80586178cd2ee23f124fe0dbac55746ee3f0 Mon Sep 17 00:00:00 2001 From: hajjimo Date: Thu, 14 Aug 2025 11:00:57 +0200 Subject: [PATCH 6/6] docs: mi/3419/rafiki-testnet-deploy --- packages/documentation/astro.config.mjs | 56 ++--- .../01-architecture-overview.mdx | 223 ++++++++---------- .../02-configuration-variables.mdx | 25 +- .../deploy-to-prod/05-services-deployment.mdx | 20 +- .../deploy-to-prod/06-troubleshooting.mdx | 50 +++- 5 files changed, 199 insertions(+), 175 deletions(-) diff --git a/packages/documentation/astro.config.mjs b/packages/documentation/astro.config.mjs index 824fc52215..ad855c8a97 100644 --- a/packages/documentation/astro.config.mjs +++ b/packages/documentation/astro.config.mjs @@ -168,36 +168,36 @@ export default defineConfig({ { label: 'Helm and Kubernetes', link: '/integration/deployment/helm-k8s' - } - ] - }, - { - label: 'Deployment example', - collapsed: true, - items: [ - { - label: 'Overview', - link: '/integration/deploy-to-prod/01-architecture-overview' - }, - { - label: 'Configuration variables', - link: '/integration/deploy-to-prod/02-configuration-variables' - }, - { - label: 'Secrets management', - link: '/integration/deploy-to-prod/03-secrets-management' - }, - { - label: 'Infrastructure setup', - link: '/integration/deploy-to-prod/04-infrastructure-setup' - }, - { - label: 'Services deployment', - link: '/integration/deploy-to-prod/05-services-deployment' }, { - label: 'Troubleshooting', - link: '/integration/deploy-to-prod/06-troubleshooting' + label: 'Deployment example', + collapsed: true, + items: [ + { + label: 'Overview', + link: '/integration/deploy-to-prod/01-architecture-overview' + }, + { + label: 'Configuration variables', + link: '/integration/deploy-to-prod/02-configuration-variables' + }, + { + label: 'Secrets management', + link: '/integration/deploy-to-prod/03-secrets-management' + }, + { + label: 'Infrastructure setup', + link: '/integration/deploy-to-prod/04-infrastructure-setup' + }, + { + label: 'Services deployment', + link: '/integration/deploy-to-prod/05-services-deployment' + }, + { + label: 'Troubleshooting', + link: '/integration/deploy-to-prod/06-troubleshooting' + } + ] } ] }, diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx index bc0153516d..f3c17c8f88 100644 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/01-architecture-overview.mdx @@ -9,7 +9,7 @@ import { Tooltip } from '@interledger/docs-design-system' -This guide provides an approach for you to deploy and integrate Rafiki on Google Cloud Platform using Terraform, Kubernetes, Helm charts, and Argo CD. The reference architecture used in this guide is the Interledger Test Network. For this example we'll assume you are a digital wallet provider that wants to deploy your wallet application and Rafiki in your Kubernetes cluster. +This guide provides an approach for you to deploy and integrate Rafiki on Google Cloud Platform (GCP) using Terraform, Kubernetes, Helm charts, and Argo CD. The reference architecture used in this guide is the Interledger Test Network. For this example we'll assume you are a digital wallet provider that wants to deploy your wallet application and Rafiki in your Kubernetes cluster. :::caution As the Interledger Test Network is used to showcase Rafiki's functionalities and to serve as a sandbox environment, this example is intended for informational purposes only and should not be used for a production deployment. @@ -19,7 +19,7 @@ As the Interledger Test Network is used to showcase Rafiki's functionalities and Before beginning the integration, ensure you have the following: -- A Google Cloud Platform account with billing enabled +- A GCP account with billing enabled - The gcloud CLI installed and authenticated - Hashicorp Terraform installed @@ -41,163 +41,146 @@ The deployment follows the Interledger Test Network reference architecture, whic - **NGINX Ingress**: Load balancing and SSL termination - **Argo CD**: GitOps continuous deployment - **Digital Wallet**: Your wallet application integrated with Rafiki +- **GateHub Integration**: Payment backend and ledger services ## Reference architecture -The following diagram illustrates the complete architecture based on the Interledger Test Network reference implementation: +The following diagram illustrates the architecture based on the Interledger Test Network wallet application with GateHub integration: your-wallet.com] - LB[Google Cloud
Load Balancer] + %% Core Rafiki System + Rafiki[Rafiki] + AdminAPI[Admin API] + AuthAPI[Auth API] + + %% Wallet Backend Components + subgraph WalletBackend[Wallet Backend] + RatesService[Rates Service] + WebhookService[Webhook Service] + RafikiIntegration[Rafiki Integration] + GateHubService[GateHub Service] + InternalLedger[Internal Ledger System] + IDPLedgering[IDP & Ledgering] + NodeJS[Node.js] + ExpressJS[Express.js] end - %% GKE Cluster - subgraph "GKE Cluster" - %% Ingress Layer - subgraph "Ingress Layer" - Ingress[NGINX Ingress
Controller] - CertManager[cert-manager
Let's Encrypt] - end - - %% Application Layer - subgraph "Digital Wallet Namespace" - WalletUI[Digital Wallet UI
wallet.your-wallet.com] - WalletAPI[Wallet Backend API
api.your-wallet.com] - WalletDB[(Wallet Database
PostgreSQL)] - end - - %% Rafiki Services - subgraph "Rafiki Namespace" - RafikiAuth[Rafiki Auth Server
auth.your-wallet.com] - RafikiBackend[Rafiki Backend
backend.your-wallet.com] - RafikiAdmin[Rafiki Admin API
admin.your-wallet.com] - RafikiDB[(Rafiki Database
PostgreSQL)] - Redis[(Redis Cache)] - end - - %% GitOps and Monitoring - subgraph "Platform Services" - ArgoCD[Argo CD
argocd.your-wallet.com] - Monitoring[Prometheus
& Grafana] - end - - %% Persistent Storage - subgraph "Storage" - PVC1[Wallet DB PVC] - PVC2[Rafiki DB PVC] - PVC3[Redis PVC] - end + %% Frontend + subgraph WalletFrontend[Wallet Frontend] + NextJS[Next.js] + React[React] end - %% External Git Repository - GitRepo[📁 Git Repository
Helm Charts & Config] + %% Client + subgraph ClientDevices[Client] + Desktop[Desktop] + Mobile[Mobile] + end - %% Connections - External - User --> Internet - Internet --> DNS - DNS --> LB - LB --> Ingress + %% Database for Open Payments + PostgreSQL2[PostgreSQL] - %% Connections - Internal Services - Ingress --> WalletUI - Ingress --> WalletAPI - Ingress --> RafikiAuth - Ingress --> RafikiBackend - Ingress --> RafikiAdmin - Ingress --> ArgoCD + %% Connections + Redis --> Rafiki + PostgreSQL1 --> Rafiki - %% Wallet Internal Connections - WalletUI --> WalletAPI - WalletAPI --> WalletDB - WalletAPI --> RafikiAdmin - WalletAPI --> RafikiBackend + Rafiki --> AdminAPI + Rafiki --> AuthAPI - %% Rafiki Internal Connections - RafikiAuth --> RafikiDB - RafikiAuth --> Redis - RafikiBackend --> RafikiDB - RafikiBackend --> Redis - RafikiAdmin --> RafikiDB + AdminAPI --> WalletBackend + AuthAPI --> WalletBackend - %% Interledger Protocol Connections - RafikiBackend --> External - External --> RafikiBackend + FreecurrencyAPI --> WalletBackend + GateHub --> WalletBackend - %% Storage Connections - WalletDB --> PVC1 - RafikiDB --> PVC2 - Redis --> PVC3 + WalletBackend --> PostgreSQL2 + WalletBackend --> WalletFrontend - %% GitOps - GitRepo --> ArgoCD - ArgoCD --> WalletAPI - ArgoCD --> RafikiAuth - ArgoCD --> RafikiBackend - ArgoCD --> RafikiAdmin + OpenPayments --> PostgreSQL2 + OpenPayments --> WalletBackend - %% Certificate Management - CertManager --> Ingress + WalletFrontend --> ClientDevices %% Styling - classDef userFacing fill:#f0f0f0,stroke:#333,color:#000 - classDef rafiki fill:#d9d9d9,stroke:#333,color:#000 - classDef wallet fill:#e6e6e6,stroke:#333,color:#000 - classDef platform fill:#cccccc,stroke:#333,color:#000 - classDef storage fill:#b3b3b3,stroke:#333,color:#000 - classDef external fill:#ffffff,stroke:#333,color:#000 + classDef redisStyle fill:#DC382D,stroke:#333,stroke-width:2px,color:#fff + classDef postgresStyle fill:#336791,stroke:#333,stroke-width:2px,color:#fff + classDef rafikiStyle fill:#4ECDC4,stroke:#333,stroke-width:2px,color:#fff + classDef openPaymentsStyle fill:#00A86B,stroke:#333,stroke-width:2px,color:#fff + classDef apiStyle fill:#FF69B4,stroke:#333,stroke-width:2px,color:#fff + classDef walletBackendStyle fill:#E6F3FF,stroke:#333,stroke-width:2px + classDef frontendStyle fill:#E8F5E8,stroke:#333,stroke-width:2px + classDef clientStyle fill:#E6E6FA,stroke:#333,stroke-width:2px + classDef nodeStyle fill:#68A063,stroke:#333,stroke-width:2px,color:#fff + classDef gatehubStyle fill:#1E3A8A,stroke:#333,stroke-width:2px,color:#fff - class User,WalletUI userFacing - class RafikiAuth,RafikiBackend,RafikiAdmin,RafikiDB,Redis rafiki - class WalletAPI,WalletDB wallet - class ArgoCD,Monitoring,Ingress,CertManager platform - class PVC1,PVC2,PVC3 storage - class External,Internet,DNS,LB,GitRepo external`} + class Redis redisStyle + class PostgreSQL1,PostgreSQL2 postgresStyle + class Rafiki rafikiStyle + class OpenPayments openPaymentsStyle + class AdminAPI,AuthAPI apiStyle + class WalletBackend walletBackendStyle + class WalletFrontend frontendStyle + class ClientDevices clientStyle + class NodeJS nodeStyle + class GateHub,GateHubService gatehubStyle`} />
## Component details -### External layer +### External services -- **Users**: Access wallet through web/mobile interfaces -- **DNS & Load Balancing**: Google Cloud DNS and Load Balancer for traffic routing +- **Redis**: Provides caching and session management for the Rafiki system +- **FreecurrencyAPI**: External service providing real-time currency exchange rates +- **GateHub**: Payment backend service providing ledger and payment processing capabilities -### Ingress layer +### Database layer -- **NGINX Ingress**: Routes traffic to appropriate services based on hostname -- **cert-manager**: Automatically provisions and manages TLS certificates +- **PostgreSQL (Rafiki)**: Primary database storing Interledger accounts, wallet addresses, and core transaction data +- **PostgreSQL (Open Payments)**: Dedicated database for Open Payments protocol data and wallet-specific information -### Digital wallet layer +### Rafiki core services -- **Wallet UI** (`wallet.your-wallet.com`): User-facing web application -- **Wallet API** (`api.your-wallet.com`): Backend services for wallet functionality -- **Wallet Database**: User accounts, balances, transaction history +- **Rafiki**: Core Interledger payment engine handling protocol implementation and payment processing +- **Admin API**: GraphQL interface for administrative functions and account management +- **Auth API**: Authentication and authorization service implementing Open Payments standards -### Rafiki layer +### GKE cluster - wallet services -Core Interledger services providing the following functionality: +#### Wallet backend namespace -- **Auth server** (`auth.your-wallet.com`): Handles Open Payments authentication and authorization -- **Backend** (`backend.your-wallet.com`): Core Interledger protocol implementation -- **Admin API** (`admin.your-wallet.com`): Administrative functions and account management via GraphQL API -- **Database**: Stores Interledger accounts, payment pointers, and transaction data -- **Redis**: Caching and session management +- **Wallet Backend**: Main Node.js/Express application orchestrating wallet functionality +- **Rates Service**: Handles currency exchange rate management and calculations +- **Webhook Service**: Manages incoming webhook notifications from external services +- **Rafiki Integration**: Interface layer for communication with Rafiki services +- **GateHub Service**: Integration component for GateHub payment backend +- **Internal Ledger System**: Manages internal transaction ledgering and accounting +- **IDP & Ledgering**: Identity provider integration and additional ledger management + +#### Wallet frontend namespace + +- **Wallet Frontend**: Next.js/React application providing the user interface + +#### Ingress layer + +- **NGINX Ingress**: Routes external traffic to appropriate services based on hostname and path +- **cert-manager**: Automatically provisions and manages SSL/TLS certificates -### Platform Services +#### Platform services -- **Argo CD**: GitOps continuous deployment from Git repositories -- **Monitoring**: Prometheus metrics collection and Grafana dashboards +- **Argo CD**: GitOps continuous deployment system managing application deployments +- **Monitoring**: Prometheus metrics collection and Grafana dashboards for system observability ## Next steps diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx index 58fc5f27ed..a965195053 100644 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/02-configuration-variables.mdx @@ -32,9 +32,9 @@ Configure your infrastructure deployment with these variables: | Variable | Default Value | Required | Description | | ------------------------ | ----------------------- | -------- | ----------------------------------------------------- | | `project_id` | - | Yes | GCP Project ID where resources will be created | +| `domain_name` | - | Yes | Primary domain for your wallet (e.g., `mywallet.com`) | | `region` | `us-central1` | No | Primary GCP region for cluster and resources | | `cluster_name` | `rafiki-wallet-cluster` | No | Name of the GKE cluster | -| `domain_name` | - | Yes | Primary domain for your wallet (e.g., `mywallet.com`) | | `node_pool_machine_type` | `e2-standard-4` | No | GCE machine type for Kubernetes nodes | | `min_node_count` | `1` | No | Minimum number of nodes in the cluster | | `max_node_count` | `10` | No | Maximum number of nodes for autoscaling | @@ -337,17 +337,16 @@ _Found in: `k8s-manifests/backup/postgres-backup.yaml`_ Configure these DNS A records pointing to your static IP:
- -| Record Type | Name | Value | TTL | -| ----------- | ---------------------------- | ---------------- | --- | -| A | `wallet.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `api.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `auth.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `backend.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `admin.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `argocd.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `grafana.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | -| A | `prometheus.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | Name | Value | TTL | + | ---------------------------- | ---------------- | --- | + | `wallet.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `api.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `auth.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `backend.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `admin.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `argocd.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `grafana.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 | + | `prometheus.YOUR_DOMAIN.com` | `YOUR_STATIC_IP` | 300 |
@@ -359,7 +358,7 @@ All configuration files use these placeholder patterns that you must replace: - `YOUR_PROJECT_ID` - Replace with your GCP project ID - `YOUR_REGISTRY` - Replace with your container registry - `YOUR_EMAIL` - Replace with your administrative email -- `` - Generate using `openssl rand -base64 32` (see Secrets Management guide) +- `` - Generate using `openssl rand -base64 32` (refer to the [Secrets Management](/integration/deploy-to-prod/03-secrets-management) guide) - `` - Generate strong passwords for admin accounts Ensure you systematically replace all placeholder values before deployment to avoid configuration errors. diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx index 888d8e0272..f005514aa7 100644 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/05-services-deployment.mdx @@ -897,16 +897,16 @@ kubectl get certificates -A Your deployed services are available at these URLs: -| Service | URL | Purpose | -| ------------------ | ---------------------------------- | ------------------------------ | -| **Wallet UI** | https://wallet.YOUR_DOMAIN.com | User-facing wallet application | -| **Wallet API** | https://api.YOUR_DOMAIN.com | Wallet backend API | -| **Rafiki Auth** | https://auth.YOUR_DOMAIN.com | Authentication server | -| **Rafiki Backend** | https://backend.YOUR_DOMAIN.com | Payment processing | -| **Rafiki Admin** | https://admin.YOUR_DOMAIN.com | Administrative API | -| **Argo CD** | https://argocd.YOUR_DOMAIN.com | GitOps management | -| **Grafana** | https://grafana.YOUR_DOMAIN.com | Monitoring dashboards | -| **Prometheus** | https://prometheus.YOUR_DOMAIN.com | Metrics collection | +| Service | URL | Purpose | +| ------------------ | ------------------------------------ | ------------------------------ | +| **Wallet UI** | `https://wallet.YOUR_DOMAIN.com` | User-facing wallet application | +| **Wallet API** | `https://api.YOUR_DOMAIN.com` | Wallet backend API | +| **Rafiki Auth** | `https://auth.YOUR_DOMAIN.com` | Authentication server | +| **Rafiki Backend** | `https://backend.YOUR_DOMAIN.com` | Payment processing | +| **Rafiki Admin** | `https://admin.YOUR_DOMAIN.com` | Administrative API | +| **Argo CD** | `https://argocd.YOUR_DOMAIN.com` | GitOps management | +| **Grafana** | `https://grafana.YOUR_DOMAIN.com` | Monitoring dashboards | +| **Prometheus** | `https://prometheus.YOUR_DOMAIN.com` | Metrics collection | ## Performance optimization diff --git a/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx b/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx index 2ecca1c938..9eeac3583a 100644 --- a/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx +++ b/packages/documentation/src/content/docs/integration/deploy-to-prod/06-troubleshooting.mdx @@ -77,7 +77,7 @@ Before troubleshooting issues, ensure you've completed all required customizatio gcloud compute project-info describe --project=PROJECT_ID ``` -#### Issue: GKE Cluster Creation Hangs +#### Issue: GKE cluster creation hangs **Symptoms:** @@ -112,18 +112,55 @@ Before troubleshooting issues, ensure you've completed all required customizatio gcloud container clusters delete OLD_CLUSTER_NAME --region=REGION ``` -### DNS and Certificate Issues +### DNS and certificate issues -#### Issue: Certificate Not Issued +#### Issue: certificate not issued **Symptoms:** +- Certificate shows `READY: False` status +- TLS certificate secret not created +- HTTPS connections fail with certificate errors +- Let's Encrypt certificate challenges failing + ```bash kubectl get certificates -A NAME READY SECRET AGE rafiki-auth-tls False rafiki-auth-tls 10m ``` +**Solutions:** + +1. **Verify DNS records are correctly configured:** + + ```bash + # Check if domain resolves to your cluster IP + nslookup auth.YOUR_DOMAIN.com + dig auth.YOUR_DOMAIN.com + + # Verify static IP is assigned + kubectl get ingress -A + ``` + +2. **Check cert-manager is running properly:** + + ```bash + # Verify cert-manager pods are healthy + kubectl get pods -n cert-manager + + # Check cluster-issuer status + kubectl get clusterissuer + kubectl describe clusterissuer letsencrypt-prod + ``` + +3 . **Check firewall rules allow HTTP/HTTPS traffic:** + +```bash +# Ensure HTTP challenge can reach your domain +gcloud compute firewall-rules list +curl -I http://auth.YOUR_DOMAIN.com/.well-known/acme-challenge/test +``` + **Debugging:** ```bash @@ -135,5 +172,10 @@ kubectl get certificaterequests -A kubectl describe certificaterequest -n rafiki # Check cert-manager logs -kubectl logs -n cert-manager deployment/ +kubectl logs -n cert-manager deployment/cert-manager +kubectl logs -n cert-manager deployment/cert-manager-webhook +kubectl logs -n cert-manager deployment/cert-manager-cainjector + +# Check ingress-nginx logs for HTTP challenges +kubectl logs -n ingress-nginx deployment/ingress-nginx-controller ```