tech_surveillance2596 wordsRead on Arc Codex

Build a unified CI/CD control plane with Red Hat Developer Hub

If your engineering teams waste time context-switching between Red Hat OpenShift, Argo CD, Tekton, and Quay, your platform needs a unified developer portal. Building on the previous article in this series, this guide shows platform engineers how to deploy and configure Red Hat Developer Hub to bring those tools into a single pane of glass. The friction of tool switching Consider what happens during a standard release: starting the pipeline initiates a PipelineRun . On successful completion of the PipelineRun , the image tag in the deployment manifest updates with the latest image pushed to the image registry. As soon as the deployment manifest updates, the Argo CD reconciliation loop updates the deployment with the latest image tag. Finally, a new pod starts up with the latest image. Across all of this, reviewing a single PipelineRun requires switching between the OpenShift console, the Pipelines tab in the OpenShift web console, the Argo CD console, and the image registry. Imagine pushing a code fix, then having to monitor Tekton logs in one tab, check Quay image tags in another, and watch Argo CD sync status in a third. That constant task-switching disrupts developer flow. For new team members, navigating four separate web consoles creates significant cognitive friction and slows down onboarding. This is where platform engineering steps in—reducing cognitive load by abstracting infrastructure complexity so developers can focus on writing code. The solution: Red Hat Developer Hub To overcome this overhead, an internal developer portal provides a thin management layer on top of these key components that brings everything into one place. As a CNCF graduated project, Backstage has emerged as a leading open source framework for internal developer portals. Red Hat Developer Hub is Red Hat's build of Backstage, enabling simple integration with Argo CD, Red Hat OpenShift Pipelines, Quay, and OpenShift clusters. Developer Hub unifies pipeline runs, deployment health, and container image tags into one view so developers don't have to switch across 4 different web consoles. Red Hat Developer Hub includes preconfigured software templates (often called golden paths) that give developers ready-to-use repositories with automated CI/CD pipelines already configured. Developers starting a new project can quickly bootstrap their environment from a simple self-service form. Overview of this guide In this article, you will set up a Red Hat Developer Hub instance to aggregate status from your OpenShift pipeline, Argo CD, and Quay, preparing your environment to visualize the entire CI/CD workflow. A follow-up article will cover translating the simple Go project into a Backstage software template to create a Git repository with built-in CI/CD elements. This quick start walks through setting up Red Hat Developer Hub along with the required dynamic plug-ins for Quay, Red Hat OpenShift Pipelines, Argo CD, and Kubernetes. Once a platform engineer completes this initial configuration, developers can immediately start onboarding projects through standardized platform templates. Architecture overview Red Hat Developer Hub is the abstraction layer that acts as an interface between CI/CD components and provides a self-service layer. Each component connects to Red Hat Developer Hub through plug-ins. The CI/CD pipeline from part 1 remains the same: push triggers → build triggers → deploy. This guide focuses on the platform engineer setup, with the developer workflow covered in a follow-up article. As a one-time setup, a platform engineer installs Red Hat Developer Hub, configures plug-ins, and writes the golden path template. The next part in this series will demonstrate how developers scaffold components from the template to view CI, CD, images, pods, and topology directly within the Red Hat Developer Hub console. Prerequisites Before you begin, complete part 1 of this series. You should have: - OpenShift cluster (Red Hat OpenShift Service on AWS (ROSA) or self-managed) with cluster-admin access - Red Hat OpenShift Pipelines Operator installed with Pipelines-as-Code configured - Red Hat OpenShift GitOps Operator installed with an Argo CD instance - GitHub account and organization Part 1 used Docker Hub as the container registry. Part 2 switches to Quay.io because Red Hat Developer Hub provides a stable Quay plug-in. This plug-in displays image tags, vulnerabilities, and manifest details directly in the developer portal. If you followed part 1 with Docker Hub, you'll need to update your secret to use Quay.io credentials instead. No pipeline changes are required. This guide uses simplified cluster permissions for proof-of-concept setup; for production deployments, consult the Red Hat Developer Hub documentation to configure RBAC with least privilege. Platform engineer sets up Red Hat Developer Hub This section covers setting up Red Hat Developer Hub and its required plug-ins from the perspective of a platform engineer. Step 1: Install the Red Hat Developer Hub operator Install the Red Hat Developer Hub operator from OperatorHub in the OpenShift web console. Navigate to Operators → OperatorHub, search for "Red Hat Developer Hub," and select Install. Accept the default settings—the operator installs into the rhdh-operator namespace. Step 2: Create secrets Because Red Hat Developer Hub acts as an integration layer across components like Pipelines, Argo CD applications, and pods, create a secret containing the required credentials. Authenticating users and scaffolding repositories from the template also requires configuring Git credentials. First, retrieve the default service account token. Red Hat Developer Hub uses this token to query the cluster for pods, deployments, pipeline runs, and routes: $ cat secret.yaml apiVersion: v1 kind: Secret metadata: name: default-token namespace: rhdh-operator annotations: kubernetes.io/service-account.name: default type: kubernetes.io/service-account-token $ oc create -f secret.yaml $ oc get secret default-token -o go-template='{{.data.token | base64decode}}' -n rhdh-operator Next, create a GitHub OAuth app so developers can log in to Red Hat Developer Hub with their GitHub identity. Navigate to GitHub → Settings → Developer settings → OAuth Apps and create a new application. Set both the Homepage URL and Authorization callback URL to your Red Hat Developer Hub route URL. You'll get this URL after deploying Red Hat Developer Hub in step 6—you might need to come back and update the OAuth app at that point. Now create the secret with all the required credentials: $ oc create secret generic my-rhdh-secrets \ --from-literal=GITHUB_CLIENT_ID= \ --from-literal=GITHUB_CLIENT_SECRET= \ --from-literal=GITHUB_TOKEN= \ --from-literal=GITHUB_URL=https://github.com \ --from-literal=GITHUB_ORG= \ --from-literal=K8S_SA_TOKEN= \ --from-literal=ARGOCD_ADMIN_USER=admin \ --from-literal=ARGOCD_ADMIN_PASSWORD= \ -n rhdh-operator The following table explains each variable: | Variable | Purpose | |---|---| GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | GitHub OAuth app credentials for the Developer Hub login | GITHUB_TOKEN | Personal access token for Red Hat Developer Hub to read repos and org membership | GITHUB_ORG | Your GitHub organization name | K8S_SA_TOKEN | Service account token so Red Hat Developer Hub can query the Kubernetes API for pods, deployments, and pipeline runs | ARGOCD_ADMIN_USER / ARGOCD_ADMIN_PASSWORD | Argo CD credentials so Red Hat Developer Hub can create the application, display sync status and history | Step 3: Create the app config This ConfigMap serves as Red Hat Developer Hub's main app-config file to configure authentication, catalog providers, Kubernetes cluster access, Argo CD integration, and the Quay registry integration. Create a file called my-rhdh-app-config.yaml with the following content: kind: ConfigMap apiVersion: v1 metadata: name: my-rhdh-app-config namespace: rhdh-operator data: default.app-config.yaml: | app: baseUrl: https:// auth: environment: production providers: github: production: clientId: ${GITHUB_CLIENT_ID} clientSecret: ${GITHUB_CLIENT_SECRET} signIn: resolvers: - resolver: usernameMatchingUserEntityName dangerouslyAllowSignInWithoutUserInCatalog: true signInPage: github backend: auth: externalAccess: - options: secret: subject: legacy-default-config type: legacy baseUrl: https:// cors: origin: https:// catalog: rules: - allow: [Component, System, API, Template, Location, Resource, User, Group, Domain] providers: githubOrg: id: githuborg githubUrl: "${GITHUB_URL}" orgs: [ "${GITHUB_ORG}" ] schedule: frequency: minutes: 60 initialDelay: seconds: 15 timeout: minutes: 15 integrations: github: - host: github.com token: ${GITHUB_TOKEN} kubernetes: serviceLocatorMethod: type: 'multiTenant' clusterLocatorMethods: - type: 'config' clusters: - url: https://api.:443 name: ocp-cluster-test authProvider: 'serviceAccount' skipTLSVerify: true serviceAccountToken: ${K8S_SA_TOKEN} customResources: - group: 'route.openshift.io' apiVersion: 'v1' plural: 'routes' - group: 'tekton.dev' apiVersion: 'v1' plural: 'pipelineruns' - group: 'tekton.dev' apiVersion: 'v1' plural: 'taskruns' argocd: waitCycles: 25 appLocatorMethods: - type: 'config' instances: - name: argocd1 url: https://openshift-gitops-server-openshift-gitops. username: ${ARGOCD_ADMIN_USER} password: ${ARGOCD_ADMIN_PASSWORD} proxy: endpoints: '/quay/api': target: 'https://quay.io' headers: X-Requested-With: 'XMLHttpRequest' changeOrigin: true secure: true permission: enabled: true rbac: policies-csv-file: /opt/app-root/src/rbac-policies.csv policyFileReload: true admin: users: - name: user:default/ quay: uiUrl: 'https://quay.io' Here is what each top-level section does: - auth + signInPage: Configures GitHub OAuth login. - catalog.providers.githubOrg: Auto-discovers users and groups from your GitHub organization and imports them into the Red Hat Developer Hub catalog every 60 minutes. - kubernetes: Connects Red Hat Developer Hub to your OpenShift cluster using the service account token. The critical customResources block tells the Kubernetes plug-in to also fetch OpenShift routes, TektonPipelineRun resources, andTaskRun resources, which powers the Tekton and Topology plug-ins. - argocd: Points to your OpenShift GitOps instance. The argocd1 name must match what you use in the Argo CD scaffolder plug-in (step 8). - proxy.endpoints./quay/api: Proxies Quay.io API calls through the Red Hat Developer Hub back end, so the Quay plug-in can fetch image tags and manifests. - permission + rbac: Enables role-based access control with policies loaded from a CSV file mounted into the container (step 5). Replace all placeholder values— , , , and —with your actual values. Note This configuration assumes a public Quay.io repository. The Quay proxy has no Authorization header configured. If you use a private Quay repository, add Authorization: 'Bearer ' under the headers section of the Quay proxy endpoint. Step 4: Configure dynamic plug-ins Red Hat Developer Hub supports dynamic plug-ins, allowing you to add integrations at runtime without rebuilding container images. This ConfigMap tells Red Hat Developer Hub which plug-ins to enable. Create a file called dynamic-plugins-rhdh.yaml : kind: ConfigMap apiVersion: v1 metadata: name: dynamic-plugins-rhdh namespace: rhdh-operator data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic' disabled: false - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic' disabled: false - package: './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-github-dynamic' disabled: false - package: './dynamic-plugins/dist/backstage-community-plugin-rbac' disabled: false - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-tekton:bs_1.45.3__3.33.3' disabled: false - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-quay:bs_1.45.3__1.28.1' disabled: false - package: './dynamic-plugins/dist/backstage-plugin-kubernetes' disabled: false - package: './dynamic-plugins/dist/backstage-plugin-kubernetes-backend-dynamic' disabled: false - package: './dynamic-plugins/dist/backstage-community-plugin-topology' disabled: false - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-scaffolder-backend-argocd:bs_1.45.3__1.8.1' disabled: false - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-backstage-plugin-argo-cd-backend:bs_1.45.3__4.6.0' disabled: false - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-backstage-plugin-argo-cd:bs_1.45.3__2.12.4' disabled: false pluginConfig: dynamicPlugins: frontend: roadiehq.backstage-plugin-argo-cd: mountPoints: - config: if: allOf: - isArgocdAvailable layout: gridColumnEnd: lg: span 8 xs: span 12 importName: EntityArgoCDOverviewCard mountPoint: entity.page.overview/cards - config: if: allOf: - isArgocdAvailable layout: gridColumn: 1 / -1 importName: EntityArgoCDHistoryCard mountPoint: entity.page.cd/cards The following table summarizes what each plug-in group provides in Red Hat Developer Hub: | Plug-in group | What it shows in Red Hat Developer Hub | |---|---| | GitHub (3 plug-ins) | Catalog discovery from GitHub, scaffolding repos, org user/group sync | | RBAC | Permission management UI | | Tekton | Pipeline runs and task logs in the CI tab | | Quay | Container image tags, digests, and layers in the Image Registry tab | | Kubernetes + Topology | Pod details and visual topology graph in dedicated tabs | | Argo CD / Roadie (3 plug-ins) | Sync status, health, and history cards in the CD tab and overview page | The Argo CD front-end plug-in configuration at the bottom mounts 2 cards: EntityArgoCDOverviewCard on the component overview page (so developers see sync status at a glance) and EntityArgoCDHistoryCard on the dedicated CD tab (for full sync history). Step 5: Configure RBAC RBAC controls what authenticated users can see and do in Red Hat Developer Hub. Without these policies, users might see empty tabs or get permission errors even though the plug-ins are correctly configured. Create a file called rbac-policies.csv : p, role:default/team-member, quay.view.read, read, allow p, role:default/team-member, catalog-entity, read, allow p, role:default/team-member, catalog.entity.create, create, allow p, role:default/team-member, catalog.entity.refresh, update, allow p, role:default/team-member, catalog.entity.delete, delete, allow p, role:default/team-member, catalog.location.create, create, allow p, role:default/team-member, catalog.location.read, read, allow p, role:default/team-member, scaffolder-template, read, allow p, role:default/team-member, scaffolder-template, create, allow p, role:default/team-member, scaffolder-action, use, allow p, role:default/team-member, scaffolder.task.create, create, allow p, role:default/team-member, scaffolder.task.cancel, use, allow p, role:default/team-member, scaffolder.task.read, read, allow p, role:default/team-member, kubernetes.proxy, use, allow p, role:default/team-member, ocm.entity.read, read, allow p, role:default/team-member, ocm.cluster.read, read, allow p, role:default/team-member, topology.view.read, read, allow p, role:default/team-member, policy-entity, read, allow g, user:default/rishabhsvats, role:default/team-member # if you want to assign the role to already existing group #g, group:default/developer, role:default/team-member This policy file defines a single role role:default/team-member with permissions across 6 areas: - Catalog: Read, create, and refresh catalog entities and locations - Scaffolder: Read templates and execute scaffolder actions (use the golden path template) - Kubernetes proxy: Access pod details, logs, and resource status through Red Hat Developer Hub - Open Cluster Management (OCM): Read cluster information - Topology: View the topology graph - Policy: Read RBAC policies The last line (g, group:default/developer, role:default/team-member ) assigns this role to all members of your GitHub organization. Replace rishabhsvats with your GitHub username. Create the ConfigMap from this file: $ oc create configmap rbac-policies \ --from-file=rbac-policies.csv \ -n rhdh-operator Step 6: Deploy Red Hat Developer Hub With the ConfigMaps and secret in place, apply them and create the Backstage custom resource. First, apply the configuration: $ oc apply -f my-rhdh-app-config.yaml -n rhdh-operator $ oc apply -f dynamic-plugins-rhdh.yaml -n rhdh-operator Now create a file called my-rhdh-cr.yaml with the Backstage custom resource: apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: my-rhdh-custom-resource namespace: rhdh-operator spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-config extraEnvs: secrets: - name: my-rhdh-secrets dynamicPluginsConfigMapName: dynamic-plugins-rhdh extraFiles: mountPath: /opt/app-root/src configMaps: - name: rbac-policies route: enabled: true database: enableLocalDb: true Apply it: $ oc apply -f my-rhdh-cr.yaml -n rhdh-operator Here is what each field in the CR does: - appConfig.configMaps: Mounts the app configuration from step 3 into the Red Hat Developer Hub container. - extraEnvs.secrets: Injects the secret values from step 2 as environment variables. The ${GITHUB_TOKEN} ,${K8S_SA_TOKEN} , and other references in the app config resolve these. - dynamicPluginsConfigMapName: Loads the dynamic plug-in configuration from step 4. - extraFiles.configMaps: Mounts the RBAC CSV file from step 5 into the container at /opt/app-root/src/rbac-policies.csv . - route.enabled: true : Creates an OpenShift route so Red Hat Developer Hub is accessible externally. - enableLocalDb: true : Uses a local PostgreSQL database. For production deployments, consider using an external database. Wait for the Red Hat Developer Hub pod to come up: $ oc get pods -n rhdh-operator -w Once the pod is running, retrieve the route URL: $ oc get route -n rhdh-operator Copy this URL—this is your . If you haven't already, go back and update the app config (step 3) and your GitHub OAuth app (step 2) with this URL, then re-apply: $ oc apply -f my-rhdh-app-config.yaml -n rhdh-operator The Red Hat Developer Hub pod will restart automatically to pick up the updated configuration. Step 7: Configure service account permissions Red Hat Developer Hub's service account needs read access to the namespaces it monitors. Without this, the Kubernetes, Tekton, and Argo CD plug-ins will show empty tabs. $ oc adm policy add-role-to-user view \ system:serviceaccount:rhdh-operator:default \ -n openshift-gitops $ oc adm policy add-role-to-user view \ system:serviceaccount:rhdh-operator:default \ -n pipeline-test The first command grants read access to the openshift-gitops namespace so Red Hat Developer Hub can query Argo CD application state. The second grants access to the pipeline-test namespace where your workloads and pipeline runs live. If you didn't label the application namespace in part 1, label it now so Argo CD can manage resources in it: $ oc label namespace pipeline-test \ argocd.argoproj.io/managed-by=openshift-gitops Your portal foundation is officially ready. With the core operators, secrets, and plug-ins wired together, you have a live Developer Hub instance connected directly to OpenShift, Tekton, Argo CD, and Quay.io. Verification and next steps Before moving to part 3, log in to your new Red Hat Developer Hub portal using your GitHub account and verify that you are able to access Catalog -> Register Existing Component . In the next article, we will transform our Go project into a standardized software template for instant developer self-service and automated repository creation.

How it works

Once you click Generate, Ollama reads this article and crafts 5 comprehension questions. Your answers are graded against the article content — general knowledge won't be enough. Score 70+ to count toward your certificate.

Questions are cached — you'll always get the same 5 for this article.