Contenido

Backstage Series #3: Integra GitHub, ArgoCD y Kubernetes en tu portal

Marzo 2026: Este artículo usa Backstage v1.49+, ArgoCD v3.3.x, y los plugins oficiales @roadiehq/backstage-plugin-argo-cd y @backstage/plugin-github-actions.

Lo que vas a lograr

En los posts anteriores construimos las piezas por separado: Backstage generando manifiestos, PRs en GitHub, y ArgoCD desplegando en Kubernetes. Hoy vamos a unirlo todo dentro del portal de Backstage. Cuando termines este post, tu portal va a mostrar:

  • Estado de los workflows de GitHub Actions directamente en cada servicio.
  • Estado de sincronización de ArgoCD — si tu app está synced, degraded o out of sync.
  • Pods y recursos de Kubernetes en tiempo real.
  • Todo conectado: un desarrollador llena un formulario, se crea un PR, se aprueba, ArgoCD sincroniza, y puedes ver todo el ciclo desde Backstage.

Pre-requisitos

Esta es la tercera entrega de la serie. Necesitas tener completados estos posts:

  1. Backstage Series #1: Primeros pasos con Backstage — instalación y primer template.
  2. Backstage Series #2: Genera manifiestos de Kubernetes y crea PRs — plugin de Kubernetes, Software Templates y PRs.
  3. ArgoCD: GitOps en tu cluster de Kubernetes paso a paso — instalación de ArgoCD y primera app GitOps.
HerramientaVersiónVerificar
Backstagev1.49+yarn backstage-cli info
ArgoCDv3.3+argocd version
Kindv0.20+kind version
kubectlv1.35+kubectl version --client
GitHub Tokenpermisos repo, workflowConfigurado en app-config.yaml

Verifica que tu cluster y ArgoCD estén corriendo:

# Cluster
kind get clusters

# ArgoCD
kubectl get pods -n argocd

Paso 1: Integrar GitHub Actions en Backstage

Vamos a empezar por lo más sencillo: ver el estado de tus pipelines de CI/CD directamente en Backstage. El plugin de GitHub Actions te muestra los workflows, sus estados y los logs — sin salir del portal.

Instalar el plugin

# Frontend: agrega la pestaña de GitHub Actions en las entidades
yarn --cwd packages/app add @backstage/plugin-github-actions

Agregar la pestaña en la UI

En packages/app/src/components/catalog/EntityPage.tsx:

import { EntityGithubActionsContent } from '@backstage/plugin-github-actions';

// Dentro de serviceEntityPage, agrega esta ruta:
<EntityLayout.Route path="/ci-cd" title="CI/CD">
  <EntityGithubActionsContent />
</EntityLayout.Route>

Configurar la autenticación con GitHub

Si ya tienes configurada la integración de GitHub del Series #1, esto ya debería funcionar. Solo verifica que tu app-config.yaml tenga esto:

integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN}
Tip
El token necesita el scope workflow además de repo para poder leer los workflows de GitHub Actions. Si tu token no lo tiene, genera uno nuevo en GitHub → Settings → Developer settings → Personal access tokens.

Para que el plugin sepa qué workflows mostrar, tus entidades necesitan la anotación github.com/project-slug:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: api-users
  annotations:
    github.com/project-slug: tu-usuario/api-users
    backstage.io/kubernetes-id: api-users
    backstage.io/kubernetes-namespace: staging
spec:
  type: service
  lifecycle: production
  owner: platform-team

Reinicia Backstage y navega a la entidad. Deberías ver la pestaña CI/CD con los últimos workflow runs.


Paso 2: Integrar ArgoCD en Backstage

Ahora viene lo bueno. Vamos a darle a Backstage la capacidad de ver el estado de tus aplicaciones en ArgoCD. El plugin te muestra si la app está sincronizada, si hay drift, el historial de sincronizaciones, y más.

Instalar el plugin de ArgoCD

Usamos el plugin de Roadie, que es el más maduro y completo del ecosistema:

# Frontend: componentes de ArgoCD para las entidades
yarn --cwd packages/app add @roadiehq/backstage-plugin-argo-cd

# Backend: proxy para la API de ArgoCD
yarn --cwd packages/backend add @roadiehq/backstage-plugin-argo-cd-backend

Registrar el backend

En packages/backend/src/index.ts:

const backend = createBackend();

// ... otros plugins ...

backend.add(import('@roadiehq/backstage-plugin-argo-cd-backend'));

backend.start();

Agregar los componentes en la UI

En packages/app/src/components/catalog/EntityPage.tsx, tienes dos opciones. Te recomiendo ambas:

Opción 1: Card en el overview (muestra un resumen rápido del estado):

import { EntityArgoCDOverviewCard } from '@roadiehq/backstage-plugin-argo-cd';

// Dentro del overview de serviceEntityPage:
<Grid item md={6}>
  <EntityArgoCDOverviewCard />
</Grid>

Opción 2: Pestaña dedicada (muestra detalles completos):

import { EntityArgoCDHistoryCard } from '@roadiehq/backstage-plugin-argo-cd';

// Como ruta en serviceEntityPage:
<EntityLayout.Route path="/argocd" title="ArgoCD">
  <EntityArgoCDHistoryCard />
</EntityLayout.Route>

Paso 3: Configurar la conexión a ArgoCD

Abre tu app-config.yaml y agrega la configuración del proxy y el plugin:

argocd:
  baseUrl: https://localhost:8080
  username: admin
  password: ${ARGOCD_ADMIN_PASSWORD}

proxy:
  endpoints:
    '/argocd/api':
      target: https://localhost:8080/api/v1/
      changeOrigin: true
      secure: false
      headers:
        Cookie:
          $env: ARGOCD_AUTH_TOKEN

Obtener las credenciales de ArgoCD

Si seguiste el post de ArgoCD, ya tienes ArgoCD corriendo en tu cluster. Vamos a obtener lo que necesitas:

# Obtener la contraseña del admin
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

# Port-forward para acceder a la API de ArgoCD
kubectl port-forward svc/argocd-server -n argocd 8080:443

Ahora necesitas un token de API para el proxy. Hay dos formas de obtenerlo:

Opción A: Usando la CLI de ArgoCD

# Login
argocd login localhost:8080 --insecure --username admin --password <TU_PASSWORD>

# Generar un token de API
argocd account generate-token --account admin

Opción B: Usando la API directamente

# Obtener el token JWT
ARGOCD_AUTH_TOKEN=$(curl -sk https://localhost:8080/api/v1/session \
  -d '{"username":"admin","password":"<TU_PASSWORD>"}' | jq -r '.token')

echo $ARGOCD_AUTH_TOKEN

Exporta las variables antes de iniciar Backstage:

export ARGOCD_ADMIN_PASSWORD="<tu-password>"
export ARGOCD_AUTH_TOKEN="argocd.token=$ARGOCD_AUTH_TOKEN"
Seguridad
En producción, nunca uses la cuenta admin. Crea un usuario de servicio con permisos de solo lectura en ArgoCD. Para el entorno local de desarrollo está bien, pero tenlo en mente para cuando lo lleves a un entorno real.

Paso 4: Anotar las entidades con ArgoCD

Para que el plugin de ArgoCD sepa qué aplicación mostrar en cada entidad del catálogo, necesitas agregar la anotación argocd/app-name:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: api-users
  annotations:
    github.com/project-slug: tu-usuario/api-users
    backstage.io/kubernetes-id: api-users
    backstage.io/kubernetes-namespace: staging
    argocd/app-name: api-users
spec:
  type: service
  lifecycle: production
  owner: platform-team

Fíjate cómo el catalog-info.yaml ahora tiene cuatro anotaciones que conectan esta entidad con tres sistemas diferentes: GitHub, Kubernetes y ArgoCD. Ese es el poder de Backstage — una sola entidad, múltiples vistas.

Múltiples apps de ArgoCD

Si tu servicio tiene varias aplicaciones de ArgoCD (por ejemplo, una por ambiente), puedes usar una lista separada por comas:

argocd/app-name: api-users-dev, api-users-staging, api-users-prod

O usar un selector de labels:

argocd/app-selector: app=api-users

Paso 5: Crear la aplicación de ArgoCD

Si aún no tienes una aplicación de ArgoCD apuntando a tu repo de manifiestos, vamos a crearla. Esto es lo que cierra el ciclo con lo que hicimos en el Series #2.

# argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api-users
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/tu-usuario/k8s-configs.git
    targetRevision: main
    path: services/api-users/manifests
  destination:
    server: https://kubernetes.default.svc
    namespace: staging
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Aplícala:

kubectl apply -f argocd-app.yaml

Con syncPolicy.automated activado, ArgoCD va a sincronizar automáticamente cada vez que detecte cambios en el repo. El selfHeal: true significa que si alguien modifica algo directamente en el cluster, ArgoCD lo revertirá al estado de Git.


Paso 6: Probar el flujo completo

Ahora sí, vamos a cerrar el ciclo de punta a punta. Este es el momento de la verdad:

1. Generar manifiestos desde Backstage

Ve a Backstage → Create → Generar Deployment de Kubernetes (el template del Series #2):

  • Servicio: api-orders
  • Namespace: staging
  • Imagen: nginx:1.27
  • Puerto: 80
  • Réplicas: 2
  • HPA: habilitado
  • Repositorio: github.com?repo=k8s-configs&owner=tu-usuario

Backstage genera los manifiestos y crea el PR.

2. Revisar y aprobar el PR en GitHub

Ve a GitHub, revisa los manifiestos generados y haz merge del PR. Puedes ver el estado del PR directamente desde la pestaña CI/CD en Backstage si tienes workflows configurados.

3. Crear la app de ArgoCD

argocd app create api-orders \
  --repo https://github.com/tu-usuario/k8s-configs.git \
  --path services/api-orders/manifests \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace staging \
  --sync-policy automated \
  --auto-prune \
  --self-heal

4. Verificar desde Backstage

Registra la entidad en el catálogo con todas las anotaciones:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: api-orders
  annotations:
    github.com/project-slug: tu-usuario/k8s-configs
    backstage.io/kubernetes-id: api-orders
    backstage.io/kubernetes-namespace: staging
    argocd/app-name: api-orders
spec:
  type: service
  lifecycle: production
  owner: platform-team

Ahora navega a api-orders en el catálogo de Backstage. Deberías ver:

  • Overview: La card de ArgoCD mostrando el estado de sincronización (Synced / Healthy).
  • CI/CD: Los workflows de GitHub Actions.
  • ArgoCD: El historial de sincronizaciones con fechas y revisiones.
  • Kubernetes: Los pods corriendo en el namespace staging, con su estado y logs.

Paso 7: Bonus — Template que crea todo de una vez

¿Y si el template de Backstage no solo creara el PR con los manifiestos, sino que también registrara la entidad en el catálogo y creara la aplicación de ArgoCD? Vamos a extender el template del Series #2 para que haga exactamente eso.

Agrega estos pasos al template.yaml después del paso create-pr:

    - id: create-catalog-entry
      name: Registrar en el catálogo
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['create-pr'].output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

    - id: create-argocd-app
      name: Crear aplicación en ArgoCD
      action: argocd:create-application
      input:
        appName: ${{ parameters.serviceName }}
        projectName: default
        repoURL: https://github.com/${{ (parameters.repoUrl | parseRepoUrl).owner }}/${{ (parameters.repoUrl | parseRepoUrl).repo }}.git
        path: services/${{ parameters.serviceName }}/manifests
        destServer: https://kubernetes.default.svc
        destNamespace: ${{ parameters.namespace }}

Y agrega un catalog-info.yaml en el skeleton:

# skeleton/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: ${{ values.serviceName }}
  annotations:
    github.com/project-slug: ${{ values.repoOwner }}/${{ values.repoName }}
    backstage.io/kubernetes-id: ${{ values.serviceName }}
    backstage.io/kubernetes-namespace: ${{ values.namespace }}
    argocd/app-name: ${{ values.serviceName }}
spec:
  type: service
  lifecycle: production
  owner: platform-team
Sobre la acción de ArgoCD

La acción argocd:create-application no viene incluida por defecto en Backstage. Necesitas instalar el módulo del scaffolder de ArgoCD:

yarn --cwd packages/backend add @roadiehq/scaffolder-backend-argocd

Y registrarlo en el backend:

backend.add(import('@roadiehq/scaffolder-backend-argocd'));

Troubleshooting

ProblemaSolución
ArgoCD card muestra “Not Found”Verifica que la anotación argocd/app-name coincida exactamente con el nombre de la app en ArgoCD
GitHub Actions no cargaConfirma que el token tiene el scope workflow y que github.com/project-slug está correcto
Kubernetes tab vacíaRevisa que la anotación backstage.io/kubernetes-id coincida con el label app de tus pods
Error de proxy con ArgoCDVerifica que el port-forward esté activo: kubectl port-forward svc/argocd-server -n argocd 8080:443
ArgoCD muestra “OutOfSync”Puede ser normal después de un PR reciente. Espera unos segundos o haz sync manual desde la UI de ArgoCD

Resumen

PasoQué hicimos
1Instalamos el plugin de GitHub Actions para ver CI/CD en Backstage
2Instalamos el plugin de ArgoCD (frontend + backend)
3Configuramos el proxy y las credenciales para ArgoCD
4Anotamos las entidades del catálogo para conectar los tres sistemas
5Creamos una aplicación de ArgoCD apuntando al repo de manifiestos
6Probamos el flujo completo: formulario → PR → merge → sync → deploy
7Extendimos el template para automatizar el registro y la creación de apps

El panorama completo

Con estos tres posts de la serie, construimos un flujo GitOps de extremo a extremo:

  1. Backstage es la puerta de entrada. Los desarrolladores no necesitan tocar kubectl, escribir YAML a mano, ni conocer la estructura del repo de configuración.
  2. GitHub es donde vive el código y los manifiestos. Los PRs dan visibilidad y control sobre qué se despliega.
  3. ArgoCD es el motor de GitOps. Se encarga de que el cluster siempre refleje lo que hay en Git.
  4. Kubernetes es donde corren los servicios. Y gracias a los plugins, puedes ver su estado sin salir de Backstage.

Esto es Platform Engineering en acción: darle a los desarrolladores una experiencia de autoservicio que sea segura, auditable y estandarizada. El equipo de plataforma define los templates y las políticas, y los desarrolladores crean y despliegan servicios sin depender de nadie.


Recursos