This is the Experimental version (Latest). It is under active development and may change. For the most reliable documentation, use the version selector in the top-right to switch to Stable, or click here to go to the Stable version's homepage.
Opstella Workers
Last updated:
🟢 Management
Opstella Workers are Microservices to integrate with DevSecOps Tools, Observability Tools, Keycloak, and Kubernetes.
Preparation
Section titled “Preparation”Determine Required Opstella Workers
Section titled “Determine Required Opstella Workers”As you have determined number of tools/instruments in Software Resources Preparation/Determine List of Opstella Workers Section
Number of Opstella Workers will depend on DevSecOps Tools, Observability Tools enabled within the entire platform as it could be vary by your requirement.
For Example:
Hard Requirement: Opstella Keycloak Service - Install worker-keycloak
Hard Requirement: Kubernetes - Install worker-kubernetes
DevSecOps:
- ArgoCD: Install
worker-argocd - DefectDojo: Install
worker-defectdojo - GitLab: Install
worker-gitlab - Headlamp: Install
worker-headlamp - Harbor: Install
worker-harbor - SonarQube: Install
worker-sonarqube - Vault: Install
worker-vault
Observability:
- Grafana LGTM Stack: Install
worker-grafana,worker-loki,worker-tempo
In conclusion, this is the list of Opstella Workers that required to install
worker-keycloakworker-kubernetesworker-argocd- Due to Opstella Architecture and Kubernetes Clusters requirements that we followed the Reference Architecture, it must have
worker-argocdfor🟦 Non-Production Workloadand🟥 Production Workload.worker-argocd-nonprodworker-argocd-prod
- Due to Opstella Architecture and Kubernetes Clusters requirements that we followed the Reference Architecture, it must have
worker-defectdojoworker-gitlabworker-headlampworker-harborworker-sonarqubeworker-vaultworker-grafanaworker-lokiworker-tempo
List of Opstella Workers will be
#!/bin/bashexport OPSTELLA_ENABLED_INSTRUMENTS=(keycloak kubernetes argocd-nonprod argocd-prod defectdojo gitlab headlamp-nonprod headlamp-prod harbor sonarqube vault grafana loki tempo)Opstella Worker Preparation
Section titled “Opstella Worker Preparation”-
Connect to
🟢 ManagementKubernetes Cluster ; i.e w/ Kubeconfig FileEnsure you have defined and loaded your Global Shell Variables as described in Shell Variables.
Terminal window source $BASE_WORKING_DIR/shell-values/kubernetes/management_cluster.vars.shEnsure
BASE_DOMAINis defined as per the Shell Variables guide. -
Helm Values Preparation
Important Configurations
image.repository,image.tag: Set your Container Image Location, Version
(Ensure
OPSTELLA_REGISTRYis loaded from your variables)(Ensure
OPSTELLA_REGISTRYis loaded from your variables)Terminal window for KEY in "${OPSTELLA_ENABLED_INSTRUMENTS[@]}"doif echo $KEY | grep -e "^argocd"; thenexport WORKER_NAME=$KEYexport IMAGE_NAME=argocdelif echo $KEY | grep -e "^headlamp"; thenexport WORKER_NAME=$KEYexport IMAGE_NAME=kuberneteselif echo $KEY | grep -e "^kubernetes"; thenexport WORKER_NAME=$KEYexport IMAGE_NAME=kuberneteselseexport WORKER_NAME=$KEYexport IMAGE_NAME=$KEYficat <<EOF > $BASE_WORKING_DIR/helm-values/opstella-worker-${WORKER_NAME}-full-values.yamlimage:repository: ${OPSTELLA_REGISTRY}/platform/worker-${IMAGE_NAME}tag: ${OPSTELLA_WORKER_IMAGE_TAG}pullPolicy: AlwaysnameOverride: worker-${WORKER_NAME}fullnameOverride: worker-${WORKER_NAME}serviceAccount:name:imagePullSecrets:- name: registry-secretenv:- name: WORKER_NAMEvalue: ${WORKER_NAME}- name: INVOKE_URLvalue: http://localhost:3500/v1.0/invoke/opstella-core/method- name: STATE_STORE_URLvalue: http://localhost:3500/v1.0/state/statestore- name: INVOKE_URL_WORKERvalue: http://localhost:3500/v1.0/invokecontainerPorts: 3000service:port: 3000# Waiting time in seconds for shutting down pod after sent SIGTERM# terminationGracePeriodSeconds: 30healthCheck:enabled: trueliveness:httpGet:path: "/healthcheck"port: 3000initialDelaySeconds: 180periodSeconds: 30readiness:httpGet:path: "/"port: 3000initialDelaySeconds: 10periodSeconds: 5podAnnotations:dapr.io/enabled: "true"dapr.io/app-id: "${WORKER_NAME}"dapr.io/app-port: "3000"dapr.io/enable-api-logging: "true"dapr.io/config: "config"dapr.io/sidecar-seccomp-profile-type: "RuntimeDefault"podSecurityContext:fsGroup: 1000securityContext:seccompProfile:type: RuntimeDefaultcapabilities:drop: ["ALL"]runAsNonRoot: trueprivileged: falseallowPrivilegeEscalation: falserunAsGroup: 1000runAsUser: 1000EOFdoneSo that’s why
worker-argocdare needed to deploy a separate instances asworker-argocd-nonprodworker-argocd-prod
However, its container image can be shared.
In the previous Helm Values Configuration section, we have intented to ease the operation but mistakenly created the incorrect configuration. This step will fix it.
Terminal window sed -i "s#repository:.*#repository: $OPSTELLA_REGISTRY/worker-argocd#g" $BASE_WORKING_DIR/helm-values/opstella-worker-argocd-nonprod-full-values.yamlsed -i "s#repository:.*#repository: $OPSTELLA_REGISTRY/worker-argocd#g" $BASE_WORKING_DIR/helm-values/opstella-worker-argocd-prod-full-values.yaml
Installation
Section titled “Installation”-
Install Opstella Workers
Install Helm Release using local
opstella-platformHelm ChartTerminal window for key in "${OPSTELLA_ENABLED_INSTRUMENTS[@]}"dohelm upgrade --install worker-${key} \oci://asia-southeast1-docker.pkg.dev/opstella-dev/opstella-charts/generic-deployment \--version 0.3.15 \--namespace opstella-system \-f $BASE_WORKING_DIR/helm-values/opstella-worker-${key}-full-values.yamldone
Post-Installation
Section titled “Post-Installation”Opstella Workers Testing
Section titled “Opstella Workers Testing”-
Get Pod Status - Opstella Workers
Terminal window kubectl get pods -n opstella-systemOpstella Workers should be
RunningNAME READY STATUS RESTARTS AGE... (deducted)worker-argocd-nonprod-XXXXXXX-YYYYY 1/1 Running 0 XdXhworker-argocd-prod-XXXXXXX-YYYYY 1/1 Running 0 XdXhworker-defectdojo-XXXXXXX-YYYYY 1/1 Running 0 XdXhworker-gitlab-XXXXXXX-YYYYY 1/1 Running 0 XdXhworker-grafana-XXXXXXX-YYYYY 1/1 Running 0 XdXhworker-harbor-XXXXXXX-YYYYY 1/1 Running 0 XdXh... (deducted)
When the tools use a private or self-signed certificate
Section titled “When the tools use a private or self-signed certificate”The workers call every tool over HTTPS and verify the certificate, but they fail in ways that do not name TLS:
| Worker | What it looks like |
|---|---|
worker-argocd-* | panic: nil pointer in usecase/argocd.GetToken — the login returned no token, and the result is dereferenced anyway |
worker-harbor | Pod stays 1/2 and restarts; the log does show x509: certificate signed by unknown authority |
| others | no visible symptom until a task fails |
Build one CA bundle from the system store plus every certificate the workers have to trust, and mount it over the system bundle:
# Start from the system bundle so the public CAs keep workingkubectl run ca-dump --rm -i --restart=Never --image=alpine:3.20 -- \ cat /etc/ssl/certs/ca-certificates.crt > /tmp/ca-bundle.crt
# Append each internal certificate the workers must trustcat /path/to/wildcard.crt >> /tmp/ca-bundle.crt
kubectl create configmap opstella-ca-bundle --namespace opstella-system \ --from-file=ca-certificates.crt=/tmp/ca-bundle.crt \ --dry-run=client -o yaml | kubectl apply -f -Add the mount to the values file of every worker, so it survives helm upgrade. The
generic-deployment chart takes it in the same shape opstella-core-values.yaml already uses for
its custom-trusted-ca volume:
volumes: true
volumesConfigMap: - name: ca-bundle configMap: name: opstella-ca-bundle
volumeMounts: - name: ca-bundle mountPath: /etc/ssl/certs/ca-certificates.crt subPath: ca-certificates.crt💡 Mount over
ca-certificates.crtitself. Adding a separate file next to it changes nothing — the Go and OpenSSL defaults read the bundle, not every file in the directory.
Verify from inside a worker:
kubectl exec --namespace opstella-system deploy/worker-harbor -c generic-deployment -- \ wc -l /etc/ssl/certs/ca-certificates.crt💡 The container in every Opstella Deployment is named
generic-deployment, not after the worker —kubectl exec -candkubectl set imageboth need that name.
Vault token Secret is read from the vault Namespace
Section titled “Vault token Secret is read from the vault Namespace”Each worker that talks to Vault reads a Secret named vault-token-<company-slug> from the
Namespace vault, which is not configurable. If Vault itself was installed elsewhere — the
Opstella guide puts it in devsecops-system — create the Namespace and copy the Secret across:
kubectl create namespace vault --dry-run=client -o yaml | kubectl apply -f -
kubectl get secret vault-token-${ORGANIZATION_NAME} --namespace devsecops-system -o yaml \ | sed 's/namespace: devsecops-system/namespace: vault/' \ | kubectl apply --namespace vault -f -Finished?
Use the below navigation to proceed