# IBM

Provision all required IBM Cloud services and install Dynamiq via Helm so that the platform is production‑ready, fully private, and upgradeable through IBM Cloud Schematics.

***

### Table of contents

1. [Prerequisites](#prerequisites)
2. [Quick‑start variables](#quick-start-variables)
3. [Install CLI & plugins](#id-1-install-cli-and-plugins)
4. [Authenticate & target a resource group](#id-1-install-cli-and-plugins)
5. [Create networking (VPC + Subnet + Gateway)](#id-3-create-networking-vpc--subnet--gateway)
6. [Provision the VPC‑Gen2 Kubernetes cluster](#id-4-provision-the-kubernetes-cluster)
7. [Provision PostgreSQL](#id-5-provision-postgresql)
8. [Provision Object Storage](#id-6-provision-object-storage)
9. [Install Dynamiq platform (Helm)](#id-7-install-dynamiq-platform)
10. [Create production secrets](#id-8-create-production-secrets)
11. [Verify installation](#id-9-verify-installation)
12. [Upgrade](#id-10-upgrade)
13. [Uninstall](#id-11-uninstall)

***

### Prerequisites

| Requirement            | Notes                                                                                                    |
| ---------------------- | -------------------------------------------------------------------------------------------------------- |
| **IBM Cloud account**  | Billing enabled & quota for VPC, Kubernetes, Databases for PostgreSQL, and Cloud Object Storage          |
| **Access**             | *Manager* and *Administrator* roles on the destination Kubernetes cluster service citeibm\_roles\_doc |
| **Local tooling**      | `bash`, `curl`, **IBM Cloud CLI v2.20+**, **kubectl v1.31+**, **Helm v3.13+**, `jq`, `openssl`           |
| **Kubernetes version** | 1.31 (latest LTS)                                                                                        |
| **Outbound network**   | Port 22 (SSH), 443 (HTTPS) open to IBM Cloud APIs                                                        |

> **Tip** If you prefer containerised tooling, grab the official 💡 *ibmcloud‑tools* image: `docker run --rm -it ibmcom/ibmcloud-tools:latest`.

***

### Quick‑start variables

Export once and reuse everywhere:

```bash
# ====== Edit me ======
export REGION="us-south"              #  <REGION>  e.g. us-south, eu-de
export RG_NAME="dynamiq"              #  <RESOURCE_GROUP_NAME>
export VPC_NAME="dynamiq"             #  <VPC_NAME>
export SUBNET_NAME="public"           #  <SUBNET_NAME>
export GW_NAME="dynamiq-gateway"      #  <PUBLIC_GATEWAY_NAME>
export ZONE="${REGION}-1"             #  Keep default or pick another zone
export CLUSTER_NAME="dynamiq-cluster" #  <CLUSTER_NAME>
export K8S_VERSION="1.31"             #  Align with supported versions
export FLAVOR="bx2.2x8"               #  2 vCPU / 8 GB each worker
export WORKERS="2"                    #  Adjust for your workload
export DB_INSTANCE_NAME="db-dynamiq"  #  <POSTGRES_INSTANCE_NAME>
export COS_INSTANCE_NAME="cos-dynamiq"#  <COS_INSTANCE_NAME>
export COS_BUCKET="dynamiqai"         #  <BUCKET_NAME>
# =======================
```

***

### 1 – Install CLI & plugins

```bash
curl -sL https://ibm.biz/idt-installer | bash
ibmcloud plugin install infrastructure-service
ibmcloud plugin install kubernetes-service
ibmcloud plugin install cos
```

Verify:

```bash
ibmcloud -v  # should be ≥ 2.20
helm version
kubectl version --client
```

***

### 2 – Authenticate & target a resource group

```bash
ibmcloud login -r $REGION --sso  # or remove --sso for API‑key login
ibmcloud resource group-create $RG_NAME || true
ibmcloud target -g $RG_NAME
```

***

### 3 – Create networking (VPC + Subnet + Gateway)

```bash
ibmcloud is vpc-create $VPC_NAME --resource-group-name $RG_NAME
ibmcloud is public-gateway-create $GW_NAME $VPC_NAME $ZONE --resource-group-name $RG_NAME
ibmcloud is subnet-create $SUBNET_NAME $VPC_NAME --zone $ZONE \
  --ipv4-address-count 256 --pgw $GW_NAME --resource-group-name $RG_NAME
```

Grab IDs for automation:

```bash
export VPC_ID=$(ibmcloud is vpcs --json | jq -r '.[] | select(.name=="'$VPC_NAME'") | .id')
export SUBNET_ID=$(ibmcloud is subnets --json | jq -r '.[] | select(.name=="'$SUBNET_NAME'") | .id')
```

***

### 4 – Provision the Kubernetes cluster

```bash
ibmcloud ks cluster create vpc-gen2 \
  --name $CLUSTER_NAME \
  --zone $ZONE \
  --version $K8S_VERSION \
  --flavor $FLAVOR \
  --workers $WORKERS \
  --vpc-id $VPC_ID \
  --subnet-id $SUBNET_ID \
  --disable-outbound-traffic-protection
```

Configure `kubectl`:

```bash
ibmcloud ks cluster ls
export CLUSTER_ID=$(ibmcloud ks cluster ls --output json --provider vpc-gen2 | jq -r '.[] | select(.name=="'$CLUSTER_NAME'") | .id')
ibmcloud ks cluster config --cluster $CLUSTER_ID
```

***

### 5 – Provision PostgreSQL

```bash
ibmcloud resource service-instance-create $DB_INSTANCE_NAME \
  databases-for-postgresql standard $REGION \
  --service-endpoints public --parameters '{"location_hardware":"virtual","version":"16"}'
# Wait until the instance becomes AVAILABLE
ibmcloud resource service-instance $DB_INSTANCE_NAME
```

Create credentials:

```bash
ibmcloud resource service-key-create ${DB_INSTANCE_NAME}-credentials \
  --instance-name $DB_INSTANCE_NAME --parameters '{"HMAC":true}'
export DATABASE_USERNAME=$(ibmcloud resource service-key ${DB_INSTANCE_NAME}-credentials --output json | jq -r '.[0].credentials.connection.postgres.authentication.username')
export DATABASE_PASSWORD=$(ibmcloud resource service-key ${DB_INSTANCE_NAME}-credentials --output json | jq -r '.[0].credentials.connection.postgres.authentication.password')
export DATABASE_HOST=$(ibmcloud resource service-key ${DB_INSTANCE_NAME}-credentials --output json | jq -r '.[0].credentials.connection.postgres.hosts[0].hostname')
export DATABASE_PORT=$(ibmcloud resource service-key ${DB_INSTANCE_NAME}-credentials --output json | jq -r '.[0].credentials.connection.postgres.hosts[0].port')
export DATABASE_NAME=$(ibmcloud resource service-key ${DB_INSTANCE_NAME}-credentials --output json | jq -r '.[0].credentials.connection.postgres.database')
```

***

### 6 – Provision Object Storage

```bash
ibmcloud resource service-instance-create $COS_INSTANCE_NAME \
  cloud-object-storage standard global -g $RG_NAME
ibmcloud resource service-key-create ${COS_INSTANCE_NAME}-credentials Writer \
  --instance-name $COS_INSTANCE_NAME --parameters '{"HMAC":true}'
export STORAGE_IBM_COS_API_KEY=$(ibmcloud resource service-key ${COS_INSTANCE_NAME}-credentials --output json | jq -r '.[0].credentials.apikey')
export STORAGE_IBM_COS_SERVICE_INSTANCE_ID=$(ibmcloud resource service-instance $COS_INSTANCE_NAME --output json | jq -r '.[0].id')
export STORAGE_IBM_COS_SERVICE_ENDPOINT="https://s3.${REGION}.cloud-object-storage.appdomain.cloud"
ibmcloud cos bucket-create --bucket $COS_BUCKET --region $REGION --ibm-service-instance-id $STORAGE_IBM_COS_SERVICE_INSTANCE_ID
```

***

### 7 – Install Dynamiq platform

Install Fission CRDs + Dynamiq dependencies:

```bash
kubectl create -k "github.com/fission/fission/crds/v1?ref=v1.20.5"
helm upgrade --install fission fission-all \
  --repo https://fission.github.io/fission-charts/ \
  --namespace fission --create-namespace \
  --set routerServiceType=ClusterIP \
  --set defaultNamespace=apps \
  --set analytics=false --wait
```

***

### 8 – Create production secrets

Generate secure keys:

```bash
export AUTH_ACCESS_TOKEN_KEY=$(openssl rand -base64 48 | tr -d '\n')
export AUTH_REFRESH_TOKEN_KEY=$(openssl rand -base64 48 | tr -d '\n')
export AUTH_VERIFICATION_TOKEN_KEY=$(openssl rand -base64 48 | tr -d '\n')
# SMTP & HF tokens
export SMTP_HOST="<SMTP_HOST>"
export SMTP_PORT="<SMTP_PORT>"
export SMTP_USERNAME="<SMTP_USERNAME>"
export SMTP_PASSWORD="<SMTP_PASSWORD>"
export HUGGING_FACE_TOKEN="<HF_TOKEN>"
```

Apply secret:

```bash
kubectl create namespace dynamiq || true
cat <<EOF | envsubst | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: nexus-secret
  namespace: dynamiq
type: Opaque
stringData:
  DATABASE_HOST: "$DATABASE_HOST"
  DATABASE_PORT: "$DATABASE_PORT"
  DATABASE_SSLMODE: "require"
  DATABASE_NAME: "$DATABASE_NAME"
  DATABASE_SCHEMA: "public"
  DATABASE_USERNAME: "$DATABASE_USERNAME"
  DATABASE_PASSWORD: "$DATABASE_PASSWORD"
  STORAGE_IBM_COS_API_KEY: "$STORAGE_IBM_COS_API_KEY"
  STORAGE_IBM_COS_SERVICE_INSTANCE_ID: "$STORAGE_IBM_COS_SERVICE_INSTANCE_ID"
  STORAGE_IBM_COS_SERVICE_ENDPOINT: "$STORAGE_IBM_COS_SERVICE_ENDPOINT"
  SMTP_HOST: "$SMTP_HOST"
  SMTP_PORT: "$SMTP_PORT"
  SMTP_USERNAME: "$SMTP_USERNAME"
  SMTP_PASSWORD: "$SMTP_PASSWORD"
  SMTP_DEFAULT_FROM: "system@getdynamiq.ai"
  AUTH_ACCESS_TOKEN_KEY: "$AUTH_ACCESS_TOKEN_KEY"
  AUTH_REFRESH_TOKEN_KEY: "$AUTH_REFRESH_TOKEN_KEY"
  AUTH_VERIFICATION_TOKEN_KEY: "$AUTH_VERIFICATION_TOKEN_KEY"
  HUGGING_FACE_TOKEN: "$HUGGING_FACE_TOKEN"
EOF
```

> **Remember** to pass `--set nexus.appSecret=nexus-secret` (or prefixed name) when you deploy Dynamiq’s Helm chart.

Install Dynamiq:

```bash
helm upgrade --install dynamiq getdynamiq/dynamiq \
  --version <CHART_VERSION> \
  --namespace dynamiq \
  --create-namespace \
  --values values-production.yaml \
  --set nexus.appSecret=nexus-secret \
  --wait
```

***

### 9 – Verify installation

```bash
kubectl -n dynamiq get all
# Check that pods are RUNNING and the ingress/LoadBalancer endpoints are assigned
```

Browse to `https://<YOUR_DOMAIN>` and log in with the initial admin user.

***

### 10 – Upgrade

A new chart version appears as an **Update** inside your IBM Cloud Schematics workspace.

1. Go to **Menu ▸ Schematics** → select the workspace.
2. Click **Settings** → **Update**.
3. Pick the desired chart version and confirm.\
   The Dynamiq pods will roll seamlessly with zero‑downtime if you have ≥ 2 replicas per component.

***

### 11 – Uninstall

```bash
helm -n dynamiq uninstall dynamiq  # removes Dynamiq workloads only
# Optional: destroy workspace to delete infra managed by Schematics
ibmcloud schematics workspace destroy --id <WORKSPACE_ID>
```

***

### Appendix A – `values.yaml` reference

| Parameter                           | Description                                               | Default        | Required |
| ----------------------------------- | --------------------------------------------------------- | -------------- | -------- |
| `dynamiq.imageCredentials.username` | Container registry username                               | \`\`           | ✅        |
| `dynamiq.imageCredentials.password` | Container registry password                               | \`\`           | ✅        |
| `nexus.ingress.enabled`             | Expose Nexus API via ingress                              | `true`         | ✅        |
| `nexus.configMapData.DOMAIN`        | Public FQDN mapped in DNS (e.g. **dynamiq.example.com**)  | \`\`           | ✅        |
| `nexus.appSecret`                   | Name of Kubernetes secret with DB/ObjectStore credentials | `nexus-secret` | ✅        |
| `synapse.ingress.enabled`           | Expose WebSocket gateway                                  | `true`         | ✅        |
| `ui.ingress.enabled`                | Expose web UI                                             | `true`         | ✅        |

***

### Appendix B – Security & Compliance controls

* **Network isolation** – all components run inside your VPC with no public ingress unless explicitly enabled.
* **TLS‑only** – Dynamiq forces HTTPS and uses Cert‑Manager (optional) for automated certificate rotation.
* **IAM separation** – each IBM Cloud service instance uses least‑privileged service IDs.

***

#### Need help?

&#x20;Email: [**support@getdynamiq.ai**](mailto:support@getdynamiq.ai)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.getdynamiq.ai/on-premise-deployment/ibm.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
