| name | devops-specialist |
| description | Deep domain knowledge for DevOps โ Azure DevOps pipeline templates, Docker multi-stage builds, Helm/K8s deployment patterns, environment promotion flow, Confix configuration management, and pipeline troubleshooting. Triggers on: azure-pipelines YAML, Dockerfile, Helm values.yaml, k8s-deployment, Confix decrypt, ACR push, environment promotion A/UAT/PAV, release pipeline, pipeline template, HelmChartVersion, k8s-vars, service connection, pod CrashLoopBackOff, ImagePullBackOff. |
DevOps Specialist
Domain knowledge for CI/CD pipelines, Docker builds, Helm/K8s deployments, and environment promotion.
Scope: Project-specific DevOps patterns only. For general DevOps workflow and investigation โ DevOps Expert agent.
Azure DevOps Organization
| Project | Purpose |
|---|
| Main | Main development โ Backend services, Pipeline-Templates |
| ReleaseManagement | Change/Test/Release Management โ wikis, release process docs, Developer-Handbook |
| IaC | Infrastructure as Code โ Terraform modules, Azure resource provisioning |
Key repos in the Main project:
- My-Backend โ main monorepo for all domain services
- Pipeline-Templates โ shared pipeline templates (
Deployment/k8s-deployment.yaml, variable templates)
Branching Strategy
GitHub Flow:
master is always deployable
- Feature branches from
master, PRs trigger validation (test-pr + sonar-pr)
- Tags on
master trigger release pipelines
- Preview tags on feature branches deploy to A environment
Pipeline Architecture
Pipeline Types
| Pipeline | Trigger | Purpose |
|---|
| test-pr | PR to master | Unit/integration tests, build validation |
| sonar-pr | PR to master | SonarQube code quality analysis |
| release | Tag on master | Build Docker images, push to ACR, deploy |
Repository Pipeline Structure
.devops/
โโโ azure-pipelines.release-<Service>.yml
โโโ azure-pipelines.sonar-pr.yml
โโโ azure-pipelines.test-pr.yml
โโโ templates/
โโโ template.detect-changes.yml
โโโ template.release.yml
โโโ template.sonar-pr.yml
โโโ template.test-pr.yml
Shared Templates (Pipeline-Templates)
K8s Deployment Template (Deployment/k8s-deployment.yaml) key parameters:
| Parameter | Purpose |
|---|
DockerImageName | Docker image name |
HelmReleaseName | Helm release name in cluster |
HelmChartName | Defaults to deployment-ng () |
HelmChartVersion | Chart version (e.g., 12.12.0) |
Environment | Target: A, A2, UAT, UAT2, PAV, PAV2, DEV001 |
Namespace | Kubernetes namespace |
KubernetesFilePath | Path to K8s values (default: app/k8s) |
Agent pool: scm-vmss-agentpool-001 (fallback: ubuntu-latest)
Environment Variable Templates
Per-environment variables from k8s-vars-{env}.yaml define: ACR, ConfigEnvironment, ConfigVault, ConfigDecryptionKey, AspNetCoreEnvironment, KubernetesServiceConnection, ConfixDecryptServiceConnectionName, OTEL_EXPORTER_OTLP_ENDPOINT, ELASTIC_APM_URL, ELASTIC_APM_TOKEN, TeamsHookUri.
Environments & Promotion
| Environment | Purpose | Deployment | Approval |
|---|
| A / A2 | Development | Auto on preview tags / Manual | None |
| UAT / UAT2 | Business testing | Tag-triggered / Manual | May require approval |
| PAV / PAV2 | Production | Tag-triggered / Manual | Approval gate required |
| DEV001 | Isolated sandbox | Manual | None |
Promotion flow: A โ UAT โ PAV
Docker & Container Build
Multi-Stage Dockerfile Pattern
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["src/<Service>/Host/Host.csproj", "src/<Service>/Host/"]
RUN dotnet restore "src/<Service>/Host/Host.csproj"
COPY . .
WORKDIR "/src/src/<Service>/Host"
RUN dotnet build "Host.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Host.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Host.dll"]
Image Structure per Service
docker/<service-name>/
โโโ Dockerfile
โโโ k8s/
โโโ A/
โ โโโ values.yaml
โ โโโ appsettings.json # Confix-encrypted
โโโ UAT/
โโโ PAV/
ACR
- Images via
$(ACR) variable, tag = $(Build.SourceBranchName) (git tag, SemVer)
- Helm chart registry:
$(HelmRepoName).azurecr.io (OCI-based)
Helm Deployment Flow
- Download Docker artifact from build stage
- Copy K8s manifests + values.yaml
- Confix Decrypt โ
dotnet confix decrypt via Azure CLI service connection
- Split
BffContainer from appsettings.json โ appsettings.bff.json
- Helm login:
helm registry login $(HelmRepoName).azurecr.io
- Helm pull:
oci://$(HelmRepoName).azurecr.io/deployment-ng
- Helm upgrade
--atomic --timeout=600s --create-namespace with environment values
- Teams notification
Helm Values Set During Deployment
image.name, image.repository=$(ACR), image.tag=$(Build.SourceBranchName)
env.DEPLOYMENT_ENVIRONMENT, env.DEPLOYMENT_VAULT, env.ASPNETCORE_ENVIRONMENT
env.OTEL_EXPORTER_OTLP_ENDPOINT, env.REMOTE_CONFIGURATION_URL
envSecrets.DEPLOYMENT_DECRYPTIONKEY, envSecrets.DEPLOYMENT_SHAREDSECRET
envSecrets.REMOTE_CONFIGURATION_TOKEN
Health Probes
All services: /_health/live (liveness), /_health/ready (readiness)
Versioning & Release
- SemVer:
MAJOR.MINOR.PATCH, preview: MAJOR.MINOR.PATCH-preview.N
- Release tags on
master โ full deployment pipeline
- Flow: feature branch โ PR โ merge โ release tag โ A (auto) โ UAT (approval) โ PAV (approval)
Configuration Management
Confix
Encrypts appsettings.json at rest. Pipeline decrypts using $(ConfixDecryptServiceConnectionName).
Azure Key Vault
Secrets via DEPLOYMENT_VAULT + DEPLOYMENT_DECRYPTIONKEY. Managed Identity in production.
Infrastructure as Code
- Terraform for Azure resources (I_IaC project)
- Helm for K8s packages
- ARM Templates for legacy resources
- CCOE manages foundational infra, quarterly compliance reviews
Observability
| Component | Purpose |
|---|
| OpenTelemetry | Distributed tracing, metrics |
| Elastic APM | Performance monitoring |
| Structured logging | ILogger + Serilog โ Elasticsearch |
| Health checks | K8s liveness/readiness probes |
Pipeline Troubleshooting
Build Failures
| Symptom | Likely Cause | Resolution |
|---|
dotnet restore fails | NuGet feed auth, version mismatch | Check nuget.config, Directory.Packages.props |
| Docker build fails | Missing COPY files, SDK mismatch | Check paths, global.json |
| Test failures | Flaky tests, missing infra | Run locally, check Squadron containers |
Deployment Failures
| Symptom | Likely Cause | Resolution |
|---|
| Helm upgrade fails | Chart not found, values.yaml error | Verify HelmChartVersion, validate YAML |
| Confix decrypt fails | Service connection permissions | Check ConfixDecryptServiceConnectionName |
| CrashLoopBackOff | Config error, missing secrets | kubectl logs, verify appsettings |
| ImagePullBackOff | ACR auth, tag not found | Verify ACR creds, confirm image push |
| Timeout (600s) | Pod not ready, low resources | Increase resources in values.yaml |
Pipeline Permission Issues
| Symptom | Likely Cause | Resolution |
|---|
Authorization failed | Service connection expired | Renew ADO service connections |
| Pipeline not triggered | Tag trigger mismatch | Verify trigger in pipeline YAML |
| Template not found | Repo resource ref wrong | Check resources.repositories branch |
Diagnostic Commands
kubectl get pods -n <ns> -l app=<svc>
kubectl logs -n <ns> -l app=<svc> --tail=100
kubectl describe pod <pod> -n <ns>
kubectl rollout status deployment/<svc> -n <ns>
kubectl rollout undo deployment/<svc> -n <ns>
helm list -n <ns>
helm history <release> -n <ns>
Key File Locations
| File | Purpose |
|---|
.devops/azure-pipelines.release-*.yml | Release pipelines per service |
.devops/azure-pipelines.test-pr.yml | PR test pipeline |
.devops/templates/template.*.yml | Shared pipeline templates |
docker/<service>/Dockerfile | Docker build |
docker/<service>/k8s/{A,UAT,PAV}/values.yaml | Helm values per environment |
Directory.Build.props | Central MSBuild properties |
Directory.Packages.props | Central NuGet package versions |
global.json | .NET SDK version pinning |
Key Pipeline Variables
| Variable | Source | Purpose |
|---|
$(ACR) | Variable template | Azure Container Registry URL |
$(ConfigEnvironment) | Variable template | Target environment name |
$(ConfigVault) | Variable template | Key Vault name |
$(KubernetesServiceConnection) | Variable template | K8s service connection |
$(ConfixDecryptServiceConnectionName) | Variable template | Confix decrypt service connection |
$(HelmRepoName) | Variable template | Helm OCI registry name |
$(TeamsHookUri) | Variable template | Teams webhook |
$(Build.SourceBranchName) | Built-in | Git tag / branch name (image tag) |