Skip to content

Commit c5bf1a7

Browse files
committed
feat: Add complete IBM Cloud OpenShift infrastructure setup
- Add comprehensive infrastructure creation script (setup-ibm-openshift.sh) - Creates resource group - Creates VPC and subnets - Creates Cloud Object Storage (for OpenShift registry) - Creates OpenShift cluster - Deploys application using Helm - Add new Makefile targets: - openshift-create-infra: Create all infrastructure - openshift-deploy-app: Deploy app to existing cluster - openshift-setup-complete: Full end-to-end setup with cluster wait - openshift-cleanup: Clean up all resources - Add IBM Cloud OpenShift variables: - ENVIRONMENT, REGION, ZONE, WORKERS, FLAVOR - CLUSTER_NAME (derived from PROJECT_NAME-ENVIRONMENT) - Update .gitignore to allow deployment scripts Related to PR #261 - Kubernetes/OpenShift deployment
1 parent ab80a5f commit c5bf1a7

File tree

3 files changed

+298
-1
lines changed

3 files changed

+298
-1
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ data/
4040
volumes/
4141
my_chroma_data/
4242

43-
# Ignore logs and shell scripts
43+
# Ignore logs and shell scripts (except deployment scripts)
4444
*.log
4545
*.sh
46+
!deployment/scripts/*.sh
4647
backend/logs/
4748

4849
# Project specific ignores

Makefile

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,14 @@ K8S_NAMESPACE ?= rag-modulo
15761576
K8S_CONTEXT ?=
15771577
HELM_RELEASE ?= rag-modulo
15781578

1579+
# IBM Cloud OpenShift variables
1580+
ENVIRONMENT ?= staging
1581+
REGION ?= ca-tor
1582+
ZONE ?= ca-tor-1
1583+
WORKERS ?= 2
1584+
FLAVOR ?= bx2.4x16
1585+
CLUSTER_NAME ?= $(PROJECT_NAME)-$(ENVIRONMENT)
1586+
15791587
# Kubernetes: Validate manifests
15801588
k8s-validate:
15811589
@echo "$(CYAN)🔍 Validating Kubernetes manifests...$(NC)"
@@ -1752,6 +1760,79 @@ ibmcloud-deploy:
17521760
--set milvus.persistence.storageClassName=ibmc-block-gold
17531761
@echo "$(GREEN)✅ Deployed to IBM Cloud$(NC)"
17541762

1763+
# IBM Cloud OpenShift - Complete Infrastructure Setup
1764+
openshift-create-infra:
1765+
@echo "$(CYAN)🏗️ Creating OpenShift infrastructure on IBM Cloud...$(NC)"
1766+
@if [ -z "$(IBM_CLOUD_API_KEY)" ]; then \
1767+
echo "$(RED)Error: IBM_CLOUD_API_KEY must be set$(NC)"; \
1768+
echo "Usage: export IBM_CLOUD_API_KEY='your-api-key' && make openshift-create-infra"; \
1769+
exit 1; \
1770+
fi
1771+
@chmod +x deployment/scripts/setup-ibm-openshift.sh
1772+
@deployment/scripts/setup-ibm-openshift.sh $(PROJECT_NAME) $(ENVIRONMENT) $(REGION) $(ZONE) $(WORKERS) $(FLAVOR)
1773+
1774+
# Deploy application to existing OpenShift cluster
1775+
openshift-deploy-app:
1776+
@echo "$(CYAN)🚀 Deploying RAG Modulo to OpenShift cluster...$(NC)"
1777+
@if [ -z "$(CLUSTER_NAME)" ]; then \
1778+
echo "$(RED)Error: CLUSTER_NAME must be set$(NC)"; \
1779+
echo "Usage: make openshift-deploy-app CLUSTER_NAME=<cluster>"; \
1780+
exit 1; \
1781+
fi
1782+
@echo "$(CYAN)Configuring cluster access...$(NC)"
1783+
ibmcloud ks cluster config --cluster $(CLUSTER_NAME) --admin
1784+
@echo "$(CYAN)Deploying Helm chart...$(NC)"
1785+
helm upgrade --install $(HELM_RELEASE) deployment/helm/rag-modulo \
1786+
--namespace rag-modulo-$(ENVIRONMENT) \
1787+
--create-namespace \
1788+
--values deployment/helm/rag-modulo/values-$(ENVIRONMENT).yaml \
1789+
--set openshift.enabled=true \
1790+
--set openshift.routes.enabled=true \
1791+
--set ingress.enabled=false \
1792+
--set postgresql.persistence.storageClassName=ibmc-block-gold \
1793+
--set milvus.persistence.storageClassName=ibmc-block-gold \
1794+
--wait --timeout=15m
1795+
@echo "$(GREEN)✅ Application deployed to OpenShift$(NC)"
1796+
@echo ""
1797+
@echo "$(CYAN)Get application URLs:$(NC)"
1798+
@echo " oc get routes -n rag-modulo-$(ENVIRONMENT)"
1799+
@echo ""
1800+
@echo "$(CYAN)Check pod status:$(NC)"
1801+
@echo " oc get pods -n rag-modulo-$(ENVIRONMENT)"
1802+
1803+
# Complete setup: Create infrastructure + Deploy application
1804+
openshift-setup-complete:
1805+
@echo "$(CYAN)🎯 Complete OpenShift setup (Infrastructure + Application)...$(NC)"
1806+
@$(MAKE) openshift-create-infra
1807+
@echo ""
1808+
@echo "$(YELLOW)⏳ Waiting for cluster to be ready...$(NC)"
1809+
@echo "$(YELLOW)This can take 30-45 minutes. Checking every 2 minutes...$(NC)"
1810+
@while true; do \
1811+
STATE=$$(ibmcloud ks cluster get --cluster $(PROJECT_NAME)-$(ENVIRONMENT) --output json 2>/dev/null | jq -r '.state // "unknown"'); \
1812+
if [ "$$STATE" = "normal" ]; then \
1813+
echo "$(GREEN)✅ Cluster is ready!$(NC)"; \
1814+
break; \
1815+
else \
1816+
echo "$(YELLOW)Cluster state: $$STATE - waiting...$(NC)"; \
1817+
sleep 120; \
1818+
fi \
1819+
done
1820+
@$(MAKE) openshift-deploy-app CLUSTER_NAME=$(PROJECT_NAME)-$(ENVIRONMENT)
1821+
1822+
# Cleanup OpenShift infrastructure
1823+
openshift-cleanup:
1824+
@echo "$(CYAN)🧹 Cleaning up OpenShift infrastructure...$(NC)"
1825+
@echo "$(RED)⚠️ This will delete the cluster and all resources!$(NC)"
1826+
@echo "$(YELLOW)Press Ctrl+C to cancel, or Enter to continue...$(NC)"
1827+
@read -r confirmation
1828+
@echo "$(CYAN)Deleting cluster...$(NC)"
1829+
ibmcloud ks cluster rm --cluster $(PROJECT_NAME)-$(ENVIRONMENT) --force-delete-storage -f
1830+
@echo "$(CYAN)Deleting VPC...$(NC)"
1831+
-ibmcloud is vpc-delete $(PROJECT_NAME)-$(ENVIRONMENT)-vpc -f
1832+
@echo "$(CYAN)Deleting resource group...$(NC)"
1833+
-ibmcloud resource group-delete $(PROJECT_NAME)-$(ENVIRONMENT) -f
1834+
@echo "$(GREEN)✅ Cleanup complete$(NC)"
1835+
17551836
# ================================
17561837
# 📚 DOCUMENTATION
17571838
# ================================
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#!/bin/bash
2+
# Complete IBM Cloud OpenShift infrastructure setup for RAG Modulo
3+
# This script creates everything from scratch:
4+
# - Resource group
5+
# - VPC with subnets
6+
# - Cloud Object Storage (for OpenShift registry)
7+
# - OpenShift cluster
8+
# - Then deploys the application using Helm
9+
10+
set -e
11+
12+
# Colors for output
13+
RED='\033[0;31m'
14+
GREEN='\033[0;32m'
15+
YELLOW='\033[1;33m'
16+
BLUE='\033[0;34m'
17+
NC='\033[0m' # No Color
18+
19+
# Configuration
20+
PROJECT_NAME="${1:-rag-modulo}"
21+
ENVIRONMENT="${2:-staging}"
22+
REGION="${3:-ca-tor}"
23+
ZONE="${4:-ca-tor-1}"
24+
WORKERS="${5:-2}"
25+
FLAVOR="${6:-bx2.4x16}"
26+
27+
# Derived names
28+
RESOURCE_GROUP="${PROJECT_NAME}-${ENVIRONMENT}"
29+
VPC_NAME="${PROJECT_NAME}-${ENVIRONMENT}-vpc"
30+
SUBNET_NAME="${PROJECT_NAME}-${ENVIRONMENT}-subnet"
31+
CLUSTER_NAME="${PROJECT_NAME}-${ENVIRONMENT}"
32+
COS_INSTANCE="${PROJECT_NAME}-${ENVIRONMENT}-cos"
33+
34+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
35+
echo -e "${BLUE}🚀 RAG Modulo - OpenShift Infrastructure Setup${NC}"
36+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
37+
echo -e "${BLUE}Project: ${NC}${PROJECT_NAME}"
38+
echo -e "${BLUE}Environment: ${NC}${ENVIRONMENT}"
39+
echo -e "${BLUE}Region: ${NC}${REGION}"
40+
echo -e "${BLUE}Zone: ${NC}${ZONE}"
41+
echo -e "${BLUE}Workers: ${NC}${WORKERS}"
42+
echo -e "${BLUE}Worker Flavor: ${NC}${FLAVOR} (4 vCPU, 16GB RAM)"
43+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
44+
echo ""
45+
46+
# Check if IBM_CLOUD_API_KEY is set
47+
if [ -z "$IBM_CLOUD_API_KEY" ]; then
48+
echo -e "${RED}❌ IBM_CLOUD_API_KEY environment variable not set${NC}"
49+
echo "Set it with: export IBM_CLOUD_API_KEY='your-api-key'"
50+
exit 1
51+
fi
52+
53+
# Step 1: Login to IBM Cloud
54+
echo -e "${YELLOW}Step 1: Logging in to IBM Cloud...${NC}"
55+
ibmcloud login --apikey "$IBM_CLOUD_API_KEY" -r "$REGION" -q
56+
57+
# Step 2: Create Resource Group
58+
echo ""
59+
echo -e "${YELLOW}Step 2: Creating resource group '${RESOURCE_GROUP}'...${NC}"
60+
if ibmcloud resource group "$RESOURCE_GROUP" &>/dev/null; then
61+
echo -e "${GREEN}✓ Resource group already exists${NC}"
62+
else
63+
ibmcloud resource group-create "$RESOURCE_GROUP"
64+
echo -e "${GREEN}✓ Resource group created${NC}"
65+
fi
66+
67+
# Target the resource group
68+
ibmcloud target -g "$RESOURCE_GROUP"
69+
70+
# Step 3: Create VPC
71+
echo ""
72+
echo -e "${YELLOW}Step 3: Creating VPC '${VPC_NAME}'...${NC}"
73+
VPC_ID=$(ibmcloud is vpcs --output json | jq -r ".[] | select(.name==\"$VPC_NAME\") | .id")
74+
if [ -n "$VPC_ID" ] && [ "$VPC_ID" != "null" ]; then
75+
echo -e "${GREEN}✓ VPC already exists (ID: $VPC_ID)${NC}"
76+
else
77+
VPC_ID=$(ibmcloud is vpc-create "$VPC_NAME" --resource-group-name "$RESOURCE_GROUP" --output json | jq -r '.id')
78+
echo -e "${GREEN}✓ VPC created (ID: $VPC_ID)${NC}"
79+
fi
80+
81+
# Step 4: Create Subnet
82+
echo ""
83+
echo -e "${YELLOW}Step 4: Creating subnet '${SUBNET_NAME}'...${NC}"
84+
SUBNET_ID=$(ibmcloud is subnets --output json | jq -r ".[] | select(.name==\"$SUBNET_NAME\") | .id")
85+
if [ -n "$SUBNET_ID" ] && [ "$SUBNET_ID" != "null" ]; then
86+
echo -e "${GREEN}✓ Subnet already exists (ID: $SUBNET_ID)${NC}"
87+
else
88+
# Create subnet with appropriate CIDR
89+
SUBNET_ID=$(ibmcloud is subnet-create "$SUBNET_NAME" "$VPC_ID" \
90+
--ipv4-address-count 256 \
91+
--zone "$ZONE" \
92+
--resource-group-name "$RESOURCE_GROUP" \
93+
--output json | jq -r '.id')
94+
echo -e "${GREEN}✓ Subnet created (ID: $SUBNET_ID)${NC}"
95+
fi
96+
97+
# Step 5: Create Cloud Object Storage instance (required for OpenShift)
98+
echo ""
99+
echo -e "${YELLOW}Step 5: Creating Cloud Object Storage instance...${NC}"
100+
COS_CRN=$(ibmcloud resource service-instances --service-name cloud-object-storage --output json | \
101+
jq -r ".[] | select(.name==\"$COS_INSTANCE\") | .crn")
102+
103+
if [ -n "$COS_CRN" ] && [ "$COS_CRN" != "null" ]; then
104+
echo -e "${GREEN}✓ COS instance already exists${NC}"
105+
else
106+
ibmcloud resource service-instance-create "$COS_INSTANCE" \
107+
cloud-object-storage standard global \
108+
-g "$RESOURCE_GROUP"
109+
110+
# Get the CRN
111+
COS_CRN=$(ibmcloud resource service-instances --service-name cloud-object-storage --output json | \
112+
jq -r ".[] | select(.name==\"$COS_INSTANCE\") | .crn")
113+
echo -e "${GREEN}✓ COS instance created${NC}"
114+
fi
115+
116+
echo -e "${BLUE}COS CRN: ${NC}$COS_CRN"
117+
118+
# Step 6: Check if cluster already exists
119+
echo ""
120+
echo -e "${YELLOW}Step 6: Checking if cluster exists...${NC}"
121+
CLUSTER_EXISTS=$(ibmcloud ks cluster ls --output json | jq -r ".[] | select(.name==\"$CLUSTER_NAME\") | .name")
122+
123+
if [ -n "$CLUSTER_EXISTS" ]; then
124+
echo -e "${GREEN}✓ Cluster '$CLUSTER_NAME' already exists${NC}"
125+
echo -e "${YELLOW}Skipping cluster creation. Use existing cluster.${NC}"
126+
127+
# Get cluster state
128+
CLUSTER_STATE=$(ibmcloud ks cluster get --cluster "$CLUSTER_NAME" --output json | jq -r '.state')
129+
echo -e "${BLUE}Cluster state: ${NC}$CLUSTER_STATE"
130+
131+
if [ "$CLUSTER_STATE" != "normal" ]; then
132+
echo -e "${YELLOW}⚠️ Cluster is not in 'normal' state. Current state: $CLUSTER_STATE${NC}"
133+
echo "Waiting for cluster to be ready..."
134+
fi
135+
else
136+
# Step 7: Create OpenShift Cluster
137+
echo ""
138+
echo -e "${YELLOW}Step 7: Creating OpenShift cluster '${CLUSTER_NAME}'...${NC}"
139+
echo -e "${BLUE}This will take approximately 30-45 minutes...${NC}"
140+
141+
ibmcloud ks cluster create vpc-gen2 \
142+
--name "$CLUSTER_NAME" \
143+
--version 4.15_openshift \
144+
--zone "$ZONE" \
145+
--vpc-id "$VPC_ID" \
146+
--subnet-id "$SUBNET_ID" \
147+
--flavor "$FLAVOR" \
148+
--workers "$WORKERS" \
149+
--cos-instance "$COS_CRN" \
150+
--entitlement cloud_pak \
151+
--disable-public-service-endpoint
152+
153+
echo -e "${GREEN}✓ Cluster creation initiated${NC}"
154+
echo ""
155+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
156+
echo -e "${BLUE}⏳ Cluster is provisioning (30-45 minutes)${NC}"
157+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
158+
echo ""
159+
echo "Monitor progress with:"
160+
echo " ibmcloud ks cluster ls"
161+
echo " ibmcloud ks cluster get --cluster $CLUSTER_NAME"
162+
echo ""
163+
echo "Once cluster state is 'normal', run:"
164+
echo " make openshift-deploy-app CLUSTER_NAME=$CLUSTER_NAME"
165+
echo ""
166+
exit 0
167+
fi
168+
169+
# Step 8: Configure kubectl/oc CLI
170+
echo ""
171+
echo -e "${YELLOW}Step 8: Configuring cluster access...${NC}"
172+
ibmcloud ks cluster config --cluster "$CLUSTER_NAME" --admin
173+
174+
# Verify cluster access
175+
if oc status &>/dev/null; then
176+
echo -e "${GREEN}✓ Cluster access configured${NC}"
177+
else
178+
echo -e "${RED}❌ Failed to configure cluster access${NC}"
179+
exit 1
180+
fi
181+
182+
# Step 9: Deploy application using Helm
183+
echo ""
184+
echo -e "${YELLOW}Step 9: Deploying RAG Modulo application...${NC}"
185+
186+
# Change to project root directory
187+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
188+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
189+
cd "$PROJECT_ROOT"
190+
191+
# Deploy using Makefile target
192+
make openshift-deploy-app CLUSTER_NAME="$CLUSTER_NAME"
193+
194+
echo ""
195+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
196+
echo -e "${GREEN}✅ Infrastructure setup and deployment complete!${NC}"
197+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
198+
echo ""
199+
echo -e "${BLUE}Resource Summary:${NC}"
200+
echo " Resource Group: $RESOURCE_GROUP"
201+
echo " VPC: $VPC_NAME ($VPC_ID)"
202+
echo " Subnet: $SUBNET_NAME ($SUBNET_ID)"
203+
echo " Cluster: $CLUSTER_NAME"
204+
echo " COS Instance: $COS_INSTANCE"
205+
echo ""
206+
echo -e "${BLUE}Next steps:${NC}"
207+
echo " 1. Check deployment status:"
208+
echo " oc get pods -n rag-modulo-${ENVIRONMENT}"
209+
echo ""
210+
echo " 2. Get application URLs:"
211+
echo " oc get routes -n rag-modulo-${ENVIRONMENT}"
212+
echo ""
213+
echo " 3. View logs:"
214+
echo " oc logs -f deployment/rag-modulo-backend -n rag-modulo-${ENVIRONMENT}"
215+
echo ""

0 commit comments

Comments
 (0)