> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getcollate.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Collate | OpenShift (ROSA) Deployment

> Install Collate on OpenShift (ROSA) using the openmetadata Helm chart with Argo Workflows, ECR credentials, and restricted-v2 SCC configuration.

# Deploy Collate

<Note>
  Complete [Prerequisites](/how-to-guides/deployment/byoc/kubernetes/openshift/prerequisites) and [Deploy Argo Workflows](/how-to-guides/deployment/byoc/kubernetes/openshift/argo-workflows) before this step.
</Note>

***

## IAM Roles (ROSA)

<Note>
  This section is ROSA/AWS-specific. On non-AWS OpenShift, skip to [ECR Credentials](#ecr-credentials). Inject AWS credentials through your own mechanism (static `Secret` via `envFrom`, HashiCorp Vault, or your cloud's workload identity), and set `secretsManager.provider: db` in the Helm values.
</Note>

### IRSA for Collate Application

A single IAM role (`openmetadata-rosa-role`) covers all AWS service access for the Collate pod: Secrets Manager and S3. It binds to the `openmetadata` service account created by the chart.

```bash theme={null}
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
NAMESPACE="openmetadata"
ROLE_NAME="openmetadata-rosa-role"

cat > trust-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_ENDPOINT}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${OIDC_ENDPOINT}:sub": "system:serviceaccount:${NAMESPACE}:openmetadata"
        }
      }
    }
  ]
}
EOF

aws iam create-role \
  --role-name "$ROLE_NAME" \
  --assume-role-policy-document file://trust-policy.json

# Secrets Manager
aws iam attach-role-policy \
  --role-name "$ROLE_NAME" \
  --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite

# S3 — asset uploads and Argo workflow logs
aws iam attach-role-policy \
  --role-name "$ROLE_NAME" \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
```

***

## ECR Credentials

Collate images are hosted in a private AWS ECR registry. The Collate team will provide ECR credentials — use them to create an image pull secret in the `openmetadata` namespace:

```bash theme={null}
oc create secret docker-registry collate-ecr-secret \
  -n openmetadata \
  --docker-server=<ecr-registry>.dkr.ecr.<region>.amazonaws.com \
  --docker-username=AWS \
  --docker-password=$(aws ecr get-login-password --region <region>)
```

<Warning>
  ECR tokens expire every 12 hours. You must refresh the `collate-ecr-secret` before expiry or implement automated rotation.
</Warning>

***

## Create the Collate Namespace

```bash theme={null}
oc new-project openmetadata
```

***

## Create Required Secrets

The chart reads the database password from an existing Kubernetes secret:

```bash theme={null}
oc create secret generic openmetadata-db-secret \
  -n openmetadata \
  --from-literal=openmetadata-mysql-password=<db-password>
```

***

## Configure `values-openshift.yaml`

Add the Helm chart repo:

```bash theme={null}
helm repo add open-metadata https://helm.open-metadata.org/
helm repo update
```

Update the following required fields in `values-openshift.yaml`:

| Field                                                                          | Description                                | Example                                                                                   |
| ------------------------------------------------------------------------------ | ------------------------------------------ | ----------------------------------------------------------------------------------------- |
| `image.repository`                                                             | ECR image repository (provided by Collate) | `<ecr-account>.dkr.ecr.<region>.amazonaws.com/collate-customers-<region>`                 |
| `image.tag`                                                                    | Image tag (provided by Collate)            | `om-1.13.0-cl-1.13.0`                                                                     |
| `serviceAccount.annotations`                                                   | IRSA role ARN                              | `arn:aws:iam::<id>:role/openmetadata-rosa-role`                                           |
| `openmetadata.config.database.host`                                            | RDS endpoint                               | `<cluster>.<region>.rds.amazonaws.com`                                                    |
| `openmetadata.config.database.auth.username`                                   | DB username                                | `openmetadata_user`                                                                       |
| `openmetadata.config.elasticsearch.host`                                       | OpenSearch endpoint                        | `<domain>.opensearch.amazonaws.com`                                                       |
| `openmetadata.config.pipelineServiceClientConfig.argoWorkflows.ingestionImage` | ECR ingestion image (provided by Collate)  | `<ecr-account>.dkr.ecr.<region>.amazonaws.com/collate-customers-ingestion-<region>:<tag>` |

Annotations in the snippet below indicate which values are ROSA/AWS-specific and which apply to any OpenShift:

```yaml theme={null}
# Collate image from ECR (provided by the Collate team)
image:
  repository: <ecr-registry>.dkr.ecr.<region>.amazonaws.com/collate-customers-<region>
  tag: <image-tag>
  pullPolicy: IfNotPresent

# ECR pull secret
imagePullSecrets:
  - name: collate-ecr-secret

# [ROSA] IRSA — chart creates the SA and applies the annotation automatically.
# On non-AWS OpenShift, remove the annotation and inject credentials via a static Secret.
serviceAccount:
  create: true
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/openmetadata-rosa-role

# [Any OpenShift] Route replaces Ingress on all OpenShift clusters.
ingress:
  enabled: false
route:
  enabled: true
  tls:
    enabled: true
    termination: edge
    insecureEdgeTerminationPolicy: Redirect

# [Any OpenShift] Required for restricted-v2 SCC on all OpenShift 4.x clusters.
podSecurityContext: {}
securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: [ALL]
  runAsNonRoot: true
  seccompProfile:
    type: RuntimeDefault

openmetadata:
  config:
    # Database connection
    database:
      host: <rds-endpoint>.<region>.rds.amazonaws.com
      port: 3306
      driverClass: com.mysql.cj.jdbc.Driver
      dbScheme: mysql
      databaseName: openmetadata_db
      auth:
        username: openmetadata_user
        password:
          secretRef: openmetadata-db-secret
          secretKey: openmetadata-mysql-password

    # OpenSearch connection — configured under the chart's legacy `elasticsearch:` key.
    # ElasticSearch is not supported in Collate BYOC; `searchType` must be `opensearch`.
    elasticsearch:
      host: <opensearch-endpoint>
      port: 443
      searchType: opensearch
      scheme: https

    # Argo Workflows pipeline client
    pipelineServiceClientConfig:
      enabled: true
      type: "argoWorkflows"
      metadataApiEndpoint: "http://openmetadata:8585/api"
      argoWorkflows:
        serviceAccountName: openmetadata
        ingestionImage: "<ecr-registry>.dkr.ecr.<region>.amazonaws.com/collate-customers-ingestion-<region>:<image-tag>"
        imagePullPolicy: "IfNotPresent"
        imagePullSecrets: "collate-ecr-secret"

    # [ROSA] AWS Secrets Manager.
    # On non-AWS OpenShift, set provider: db to use the database as secrets backend.
    secretsManager:
      enabled: true
      provider: managed-aws

extraEnvs:
  # [ROSA] AWS SDK v2 requires AWS_REGION explicitly.
  - name: AWS_REGION
    value: "us-east-2"
  - name: OPENMETADATA_HEAP_OPTS
    value: "-Xmx8G -Xms8G"

# [Any OpenShift] /opt/openmetadata/logs requires a writable emptyDir under restricted-v2 SCC.
extraVolumes:
  - name: logs
    emptyDir: {}
extraVolumeMounts:
  - name: logs
    mountPath: /opt/openmetadata/logs

#  [Any OpenShift] Resource requests/limits to ensure scheduling on clusters with limited resources. Adjust as needed based on cluster capacity and expected load.
resources:
  limits:
    cpu: 3000m
    memory: 12Gi
  requests:
    cpu: 1000m
    memory: 10Gi
```

***

## Deploy

```bash theme={null}
helm upgrade --install openmetadata open-metadata/openmetadata \
  --namespace openmetadata \
  --values values-openshift.yaml
```

For subsequent upgrades:

```bash theme={null}
helm upgrade openmetadata open-metadata/openmetadata \
  --namespace openmetadata \
  --values values-openshift.yaml \
  --reuse-values
```

### Optional: Enable Prometheus Metrics

```yaml theme={null}
serviceMonitor:
  enabled: true
```

***

## Post-Installation

### Verify the Deployment

```bash theme={null}
# Watch pods come up
oc get pods -n openmetadata -w

# Check migration init container logs
oc logs -n openmetadata -l app.kubernetes.io/name=openmetadata -c run-db-migrations --tail=50

# Confirm IRSA env vars are injected
oc exec -n openmetadata deployment/openmetadata -- env | grep -E "AWS_ROLE_ARN|AWS_WEB_IDENTITY"

# Get the application route URL
oc get route openmetadata -n openmetadata -o jsonpath='{.spec.host}'

# Health check
curl -s https://$(oc get route openmetadata -n openmetadata -o jsonpath='{.spec.host}')/healthcheck
```

Expected health check response: `{"status":"OK"}`

### Configure Reindexing

After the initial deployment, trigger a re-index from the Collate UI:

**Settings → Collate → Re-Index**

***

## Environment Variables Reference

| Variable                      | Description                                                                                                            | Default            | Required   |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ | ---------- |
| `AWS_REGION`                  | AWS region for SDK v2 clients (Secrets Manager, S3). `AWS_DEFAULT_REGION` set by the chart is insufficient for SDK v2. | set in `extraEnvs` | Yes (ROSA) |
| `AWS_ROLE_ARN`                | IAM role ARN — injected automatically by ROSA OIDC when SA is annotated                                                | injected by ROSA   | Auto       |
| `AWS_WEB_IDENTITY_TOKEN_FILE` | Path to OIDC token — injected automatically by ROSA                                                                    | injected by ROSA   | Auto       |

***

## Troubleshooting

### Pod Stuck in Pending

```bash theme={null}
oc describe pod -n openmetadata -l app.kubernetes.io/name=openmetadata
```

| Symptom                              | Cause                                   | Fix                                                                     |
| ------------------------------------ | --------------------------------------- | ----------------------------------------------------------------------- |
| `Insufficient cpu / memory`          | Cluster at capacity                     | Reduce `resources.requests` in `values-openshift.yaml`                  |
| `ImagePullBackOff`                   | ECR pull secret missing or expired      | Recreate `collate-ecr-secret` with a fresh ECR token                    |
| `unable to validate against any SCC` | Security context incompatible with SCCs | Ensure `securityContext` in values matches `restricted-v2` requirements |

### Migration Init Container Fails

```bash theme={null}
oc logs -n openmetadata -l app.kubernetes.io/name=openmetadata -c run-db-migrations
```

| Error                                                | Fix                                                                                                             |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `Unable to load region from any of the providers`    | Add `AWS_REGION` to `extraEnvs` in `values-openshift.yaml`                                                      |
| `Unable to contact EC2 metadata service` / STS error | IRSA annotation missing or trust policy mismatch — verify with `oc get sa openmetadata -n openmetadata -o yaml` |
| `Communications link failure`                        | RDS unreachable — check `openmetadata-db-secret` and RDS security group                                         |
| `Access denied for user`                             | Wrong DB credentials in `openmetadata-db-secret`                                                                |

### IRSA Not Working (ROSA Only)

```bash theme={null}
# 1. Confirm SA has the annotation
oc get sa openmetadata -n openmetadata -o jsonpath='{.metadata.annotations}'

# 2. Confirm IRSA env vars are injected into the pod
oc exec -n openmetadata deployment/openmetadata -- env | grep AWS

# 3. Test credentials from inside the pod
oc exec -n openmetadata deployment/openmetadata -- aws sts get-caller-identity
```

If step 3 fails: verify the OIDC provider ARN in the trust policy exactly matches your cluster's OIDC endpoint, and the `sub` condition matches `system:serviceaccount:openmetadata:openmetadata` exactly.

***

## Appendix: OpenShift vs EKS Differences

| Area               | EKS                                          | ROSA (OpenShift)                                        |
| ------------------ | -------------------------------------------- | ------------------------------------------------------- |
| **OIDC provider**  | Created manually via `eksctl`                | Built into ROSA automatically                           |
| **Pod security**   | Pod Security Admission (PSA)                 | Security Context Constraints (SCC)                      |
| **SCC required**   | N/A                                          | `restricted-v2` for Collate; `anyuid` for Argo          |
| **Ingress**        | Kubernetes `Ingress`                         | OpenShift `Route`                                       |
| **TLS**            | Managed by ingress controller / cert-manager | Managed by OpenShift router                             |
| **Image names**    | Short names allowed                          | Fully qualified required (e.g. `docker.io/...`)         |
| **ECR pull**       | Node IAM role or pull secret                 | Image pull secret using Collate-provided credentials    |
| **CLI**            | `kubectl`                                    | `oc` (superset of `kubectl`)                            |
| **Logs directory** | Writable by default                          | Requires `emptyDir` volume for `/opt/openmetadata/logs` |
| **AWS SDK region** | `AWS_DEFAULT_REGION` sufficient              | `AWS_REGION` required for SDK v2 Java clients           |
