mdan-cli 2.5.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/AGENTS.md +76 -1
  2. package/README.md +274 -4
  3. package/agents/auto-orchestrator.md +343 -0
  4. package/agents/devops.md +511 -94
  5. package/cli/mdan.py +111 -6
  6. package/cli/mdan_crewai.py +539 -0
  7. package/core/crewai_orchestrator.md +419 -0
  8. package/core/debate-protocol.md +454 -0
  9. package/core/universal-envelope.md +113 -0
  10. package/integrations/__init__.py +33 -0
  11. package/integrations/crewai/__init__.py +27 -0
  12. package/integrations/crewai/agents/__init__.py +21 -0
  13. package/integrations/crewai/agents/architect_agent.py +264 -0
  14. package/integrations/crewai/agents/dev_agent.py +271 -0
  15. package/integrations/crewai/agents/devops_agent.py +421 -0
  16. package/integrations/crewai/agents/doc_agent.py +388 -0
  17. package/integrations/crewai/agents/product_agent.py +203 -0
  18. package/integrations/crewai/agents/security_agent.py +386 -0
  19. package/integrations/crewai/agents/test_agent.py +358 -0
  20. package/integrations/crewai/agents/ux_agent.py +257 -0
  21. package/integrations/crewai/flows/__init__.py +13 -0
  22. package/integrations/crewai/flows/auto_flow.py +451 -0
  23. package/integrations/crewai/flows/build_flow.py +297 -0
  24. package/integrations/crewai/flows/debate_flow.py +422 -0
  25. package/integrations/crewai/flows/discovery_flow.py +267 -0
  26. package/integrations/crewai/orchestrator.py +558 -0
  27. package/integrations/crewai/skills/__init__.py +8 -0
  28. package/integrations/crewai/skills/skill_router.py +534 -0
  29. package/integrations/crewai/tools/__init__.py +11 -0
  30. package/integrations/crewai/tools/file_tool.py +355 -0
  31. package/integrations/crewai/tools/serper_tool.py +169 -0
  32. package/integrations/crewai/tools/sql_tool.py +435 -0
  33. package/memory/CONTEXT-SAVE-FORMAT.md +328 -0
  34. package/memory/MEMORY-AUTO.json +66 -0
  35. package/memory/RESUME-PROTOCOL.md +379 -0
  36. package/package.json +1 -1
  37. package/phases/auto-01-load.md +165 -0
  38. package/phases/auto-02-discover.md +207 -0
  39. package/phases/auto-03-plan.md +509 -0
  40. package/phases/auto-04-architect.md +567 -0
  41. package/phases/auto-05-implement.md +713 -0
  42. package/phases/auto-06-test.md +559 -0
  43. package/phases/auto-07-deploy.md +510 -0
  44. package/phases/auto-08-doc.md +970 -0
  45. package/skills/azure-devops/skill.md +1757 -0
  46. package/templates/dotnet-blazor/README.md +415 -0
  47. package/templates/external-services/ExampleService.cs +361 -0
  48. package/templates/external-services/IService.cs +113 -0
  49. package/templates/external-services/README.md +325 -0
  50. package/templates/external-services/ServiceBase.cs +492 -0
  51. package/templates/external-services/ServiceProvider.cs +243 -0
  52. package/templates/prompts/devops-agent.yaml +327 -0
  53. package/templates/prompts.json +15 -1
  54. package/templates/sql-server/README.md +37 -0
  55. package/templates/sql-server/functions.sql +158 -0
  56. package/templates/sql-server/schema.sql +188 -0
  57. package/templates/sql-server/stored-procedures.sql +284 -0
@@ -0,0 +1,1757 @@
1
+ ---
2
+ name: azure-devops
3
+ description: Senior Azure DevOps engineering capabilities for comprehensive cloud DevOps operations. Use PROACTIVELY for Azure DevOps pipelines, Azure CLI commands, AKS deployments, infrastructure as code, and CI/CD workflows.
4
+ triggers:
5
+ - azure
6
+ - devops
7
+ - pipeline
8
+ - aks
9
+ - azure devops
10
+ - azdo
11
+ - az cli
12
+ - azure cli
13
+ - yaml pipeline
14
+ - azure repos
15
+ - azure boards
16
+ - azure artifacts
17
+ - service connection
18
+ - variable group
19
+ - agent pool
20
+ - bicep
21
+ - arm template
22
+ - terraform azure
23
+ ---
24
+
25
+ # Azure DevOps Skill
26
+
27
+ ## Overview
28
+
29
+ This skill provides senior-level Azure DevOps engineering capabilities. It covers the complete Azure DevOps ecosystem including Azure CLI, Azure DevOps CLI extension, YAML pipeline authoring, Infrastructure as Code, and enterprise CI/CD patterns.
30
+
31
+ ## Prerequisites
32
+
33
+ ### Required Tools
34
+ ```bash
35
+ # Azure CLI
36
+ brew install azure-cli # macOS
37
+ winget install Microsoft.AzureCLI # Windows
38
+
39
+ # Azure DevOps CLI extension
40
+ az extension add --name azure-devops
41
+
42
+ # Optional but recommended
43
+ brew install bicep # Bicep CLI
44
+ brew install terraform # Terraform
45
+ ```
46
+
47
+ ### Authentication
48
+ ```bash
49
+ # Login to Azure
50
+ az login
51
+
52
+ # Login with service principal (CI/CD)
53
+ az login --service-principal -u <app-id> -p <password-or-cert> --tenant <tenant-id>
54
+
55
+ # Set default subscription
56
+ az account set --subscription "<subscription-id-or-name>"
57
+
58
+ # Configure Azure DevOps defaults
59
+ az devops configure --defaults organization=https://dev.azure.com/<org> project=<project>
60
+ ```
61
+
62
+ ## Core Capabilities
63
+
64
+ ---
65
+
66
+ ## 1. Azure CLI Reference
67
+
68
+ ### Account & Subscription Management
69
+
70
+ ```bash
71
+ # List all subscriptions
72
+ az account list --output table
73
+
74
+ # Show current subscription
75
+ az account show
76
+
77
+ # Set subscription
78
+ az account set --subscription "<subscription-id>"
79
+
80
+ # List tenants
81
+ az account tenant list
82
+
83
+ # Clear account cache
84
+ az account clear
85
+ ```
86
+
87
+ ### Resource Groups
88
+
89
+ ```bash
90
+ # Create resource group
91
+ az group create --name myResourceGroup --location eastus
92
+
93
+ # List resource groups
94
+ az group list --output table
95
+
96
+ # Show resource group details
97
+ az group show --name myResourceGroup
98
+
99
+ # Delete resource group (DANGEROUS)
100
+ az group delete --name myResourceGroup --yes --no-wait
101
+
102
+ # Export template from resource group
103
+ az group export --name myResourceGroup > template.json
104
+
105
+ # Wait for resource group operations
106
+ az group wait --name myResourceGroup --created
107
+ ```
108
+
109
+ ### Resource Management
110
+
111
+ ```bash
112
+ # List all resources in a group
113
+ az resource list --resource-group myResourceGroup --output table
114
+
115
+ # Show specific resource
116
+ az resource show --ids <resource-id>
117
+
118
+ # Delete resource
119
+ az resource delete --ids <resource-id>
120
+
121
+ # Move resource to another group
122
+ az resource move --destination-group newGroup --ids <resource-id>
123
+
124
+ # Tag resources
125
+ az resource tag --ids <resource-id> --tags Environment=Production Team=Platform
126
+
127
+ # Lock resource (prevent deletion)
128
+ az lock create --name MyLock --resource-group myResourceGroup --resource-type Microsoft.Storage/storageAccounts --resource-name mystorageaccount --lock-type CanNotDelete
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 2. Azure DevOps CLI Extension
134
+
135
+ ### Organization & Project Management
136
+
137
+ ```bash
138
+ # List organizations
139
+ az devops organization list
140
+
141
+ # Show organization details
142
+ az devops organization show --org https://dev.azure.com/<org>
143
+
144
+ # Create project
145
+ az devops project create --name "MyProject" --description "Project description" --visibility private --source-control git --process Agile
146
+
147
+ # List projects
148
+ az devops project list --output table
149
+
150
+ # Show project
151
+ az devops project show --project "MyProject"
152
+
153
+ # Update project
154
+ az devops project update --project "MyProject" --description "New description"
155
+
156
+ # Delete project
157
+ az devops project delete --project "MyProject" --yes
158
+
159
+ # Get project properties
160
+ az devops project show --project "MyProject" --query "properties"
161
+ ```
162
+
163
+ ### Repositories (Azure Repos)
164
+
165
+ ```bash
166
+ # Create repository
167
+ az repos create --name "MyRepo" --project "MyProject"
168
+
169
+ # List repositories
170
+ az repos list --project "MyProject" --output table
171
+
172
+ # Show repository
173
+ az repos show --repository "MyRepo" --project "MyProject"
174
+
175
+ # Delete repository
176
+ az repos delete --repository "MyRepo" --project "MyProject" --yes
177
+
178
+ # Create branch policy
179
+ az repos policy branch create --project "MyProject" --repository-id <repo-id> --branch main --policy-type "Minimum number of reviewers" --settings '{"minimumApproverCount": 2, "creatorVoteCounts": false, "allowDownvotes": false}'
180
+
181
+ # List branch policies
182
+ az repos policy list --project "MyProject" --repository-id <repo-id> --branch main
183
+
184
+ # Create PR
185
+ az repos pr create --project "MyProject" --repository "MyRepo" --source-branch feature/my-feature --target-branch main --title "My PR" --description "PR description"
186
+
187
+ # List PRs
188
+ az repos pr list --project "MyProject" --repository "MyRepo" --status active
189
+
190
+ # Update PR
191
+ az repos pr update --id <pr-id> --status completed --merge-commit-message "Merged PR"
192
+
193
+ # Create PR reviewer
194
+ az repos pr reviewer add --id <pr-id> --reviewers <user-id>
195
+
196
+ # Create policy for required reviewers
197
+ az repos policy required-reviewer create --project "MyProject" --repository-id <repo-id> --branch main --enabled true --blocking true --settings '{"requiredReviewerIds": ["<user-id>"], "message": "Requires review"}'
198
+ ```
199
+
200
+ ### Pipelines
201
+
202
+ ```bash
203
+ # Create pipeline (from YAML file)
204
+ az pipelines create --name "MyPipeline" --project "MyProject" --repository "MyRepo" --repository-type tfsgit --branch main --yml-path azure-pipelines.yml
205
+
206
+ # List pipelines
207
+ az pipelines list --project "MyProject" --output table
208
+
209
+ # Show pipeline
210
+ az pipelines show --name "MyPipeline" --project "MyProject"
211
+
212
+ # Run pipeline
213
+ az pipelines run --name "MyPipeline" --project "MyProject" --branch main
214
+
215
+ # Run with parameters
216
+ az pipelines run --name "MyPipeline" --project "MyProject" --parameters env=production version=1.0.0
217
+
218
+ # Run with variables
219
+ az pipelines run --name "MyPipeline" --project "MyProject" --variables buildConfiguration=Release
220
+
221
+ # Delete pipeline
222
+ az pipelines delete --name "MyPipeline" --project "MyProject" --yes
223
+
224
+ # List pipeline runs
225
+ az pipelines runs list --project "MyProject" --pipeline-ids <pipeline-id>
226
+
227
+ # Show pipeline run
228
+ az pipelines runs show --id <run-id> --project "MyProject"
229
+
230
+ # Cancel pipeline run
231
+ az pipelines runs cancel --id <run-id> --project "MyProject"
232
+
233
+ # List pipeline definitions
234
+ az pipelines definition list --project "MyProject"
235
+
236
+ # Build (classic) commands
237
+ az pipelines build list --project "MyProject"
238
+ az pipelines build queue --definition-name "MyBuild" --project "MyProject"
239
+ az pipelines build show --id <build-id> --project "MyProject"
240
+ ```
241
+
242
+ ### Variable Groups
243
+
244
+ ```bash
245
+ # Create variable group
246
+ az pipelines variable-group create --name "MyVars" --project "MyProject" --variables env=production region=eastus --authorize true
247
+
248
+ # List variable groups
249
+ az pipelines variable-group list --project "MyProject" --output table
250
+
251
+ # Show variable group
252
+ az pipelines variable-group show --group-id <id> --project "MyProject"
253
+
254
+ # Update variable group
255
+ az pipelines variable-group update --group-id <id> --project "MyProject" --variables newVar=newValue
256
+
257
+ # Delete variable group
258
+ az pipelines variable-group delete --group-id <id> --project "MyProject" --yes
259
+
260
+ # Add variable to group
261
+ az pipelines variable-group variable create --group-id <id> --name "apiKey" --value "secret-value" --secret true
262
+
263
+ # Update variable in group
264
+ az pipelines variable-group variable update --group-id <id> --name "apiKey" --value "new-value" --secret true
265
+
266
+ # Delete variable from group
267
+ az pipelines variable-group variable delete --group-id <id> --name "apiKey" --yes
268
+ ```
269
+
270
+ ### Service Connections
271
+
272
+ ```bash
273
+ # Create Azure Resource Manager service connection (automatic)
274
+ az devops service-endpoint azurerm create --name "MyAzureConnection" --project "MyProject" --azure-rm-service-principal-id <app-id> --azure-rm-subscription-id <sub-id> --azure-rm-subscription-name <sub-name> --azure-rm-tenant-id <tenant-id>
275
+
276
+ # List service connections
277
+ az devops service-endpoint list --project "MyProject" --output table
278
+
279
+ # Show service connection
280
+ az devops service-endpoint show --id <connection-id> --project "MyProject"
281
+
282
+ # Delete service connection
283
+ az devops service-endpoint delete --id <connection-id> --project "MyProject" --yes
284
+
285
+ # Create GitHub service connection
286
+ az devops service-endpoint github create --name "MyGitHub" --project "MyProject" --github-url https://github.com --github-access-token <pat>
287
+ ```
288
+
289
+ ### Agent Pools
290
+
291
+ ```bash
292
+ # List agent pools
293
+ az pipelines pool list --output table
294
+
295
+ # Show agent pool
296
+ az pipelines pool show --pool-id <id>
297
+
298
+ # List agents in pool
299
+ az pipelines agent list --pool-id <id> --output table
300
+
301
+ # Show agent details
302
+ az pipelines agent show --pool-id <id> --agent-id <agent-id>
303
+
304
+ # Create agent pool
305
+ az pipelines pool create --name "MyPool" --pool-type automation --auto-provision false
306
+
307
+ # Delete agent pool
308
+ az pipelines pool delete --pool-id <id> --yes
309
+
310
+ # Create agent queue
311
+ az pipelines queue create --name "MyQueue" --project "MyProject" --pool-id <id>
312
+ ```
313
+
314
+ ### Environments
315
+
316
+ ```bash
317
+ # List environments
318
+ az pipelines environment list --project "MyProject" --output table
319
+
320
+ # Show environment
321
+ az pipelines environment show --environment-id <id> --project "MyProject"
322
+
323
+ # Create environment
324
+ az pipelines environment create --name "Production" --project "MyProject"
325
+
326
+ # Delete environment
327
+ az pipelines environment delete --environment-id <id> --project "MyProject" --yes
328
+ ```
329
+
330
+ ### Boards (Work Items)
331
+
332
+ ```bash
333
+ # Create work item
334
+ az boards work-item create --title "New Bug" --type "Bug" --project "MyProject" --description "Bug description" --area "MyArea" --iteration "Sprint 1"
335
+
336
+ # Show work item
337
+ az boards work-item show --id <work-item-id> --project "MyProject"
338
+
339
+ # Update work item
340
+ az boards work-item update --id <work-item-id> --project "MyProject" --state "In Progress" --assigned-to <user-email>
341
+
342
+ # List work items (query)
343
+ az boards query --project "MyProject" --wiql "SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.WorkItemType] = 'Bug'"
344
+
345
+ # Delete work item
346
+ az boards work-item delete --id <work-item-id> --project "MyProject" --yes
347
+
348
+ # List work item types
349
+ az boards work-item-type list --project "MyProject"
350
+
351
+ # List areas
352
+ az boards area project list --project "MyProject"
353
+
354
+ # Create area
355
+ az boards area project create --name "MyArea" --project "MyProject"
356
+
357
+ # List iterations
358
+ az boards iteration project list --project "MyProject"
359
+
360
+ # Create iteration
361
+ az boards iteration project create --name "Sprint 1" --project "MyProject" --start-date "2024-01-01" --finish-date "2024-01-14"
362
+
363
+ # List sprints
364
+ az boards sprint list --project "MyProject"
365
+
366
+ # Show sprint
367
+ az boards sprint show --id <sprint-id> --project "MyProject"
368
+ ```
369
+
370
+ ### Artifacts (Feeds & Packages)
371
+
372
+ ```bash
373
+ # List feeds
374
+ az artifacts universal list --project "MyProject" --output table
375
+
376
+ # Create feed
377
+ az artifacts feed create --name "MyFeed" --project "MyProject"
378
+
379
+ # Show feed
380
+ az artifacts feed show --feed "MyFeed" --project "MyProject"
381
+
382
+ # Delete feed
383
+ az artifacts feed delete --feed "MyFeed" --project "MyProject" --yes
384
+
385
+ # Publish universal package
386
+ az artifacts universal publish --feed "MyFeed" --name "MyPackage" --version "1.0.0" --description "Package description" --path ./artifacts
387
+
388
+ # Download universal package
389
+ az artifacts universal download --feed "MyFeed" --name "MyPackage" --version "1.0.0" --path ./download
390
+
391
+ # List package versions
392
+ az artifacts package list --feed "MyFeed" --project "MyProject"
393
+ ```
394
+
395
+ ### Test Plans
396
+
397
+ ```bash
398
+ # List test plans
399
+ az pipelines test-plan list --project "MyProject"
400
+
401
+ # Show test plan
402
+ az pipelines test-plan show --test-plan-id <id> --project "MyProject"
403
+
404
+ # Create test plan
405
+ az pipelines test-plan create --name "MyTestPlan" --project "MyProject"
406
+
407
+ # Delete test plan
408
+ az pipelines test-plan delete --test-plan-id <id> --project "MyProject" --yes
409
+ ```
410
+
411
+ ### Teams & Security
412
+
413
+ ```bash
414
+ # List teams
415
+ az devops team list --project "MyProject" --output table
416
+
417
+ # Show team
418
+ az devops team show --team "MyTeam" --project "MyProject"
419
+
420
+ # Create team
421
+ az devops team create --name "MyTeam" --project "MyProject"
422
+
423
+ # Add member to team
424
+ az devops team member add --team "MyTeam" --project "MyProject" --member <user-id>
425
+
426
+ # List team members
427
+ az devops team member list --team "MyTeam" --project "MyProject"
428
+
429
+ # List security groups
430
+ az devops security group list --project "MyProject" --output table
431
+
432
+ # Create security group
433
+ az devops security group create --name "MyGroup" --project "MyProject" --description "Custom group"
434
+
435
+ # Add member to security group
436
+ az devops security group membership add --group-id <group-id> --member-id <user-id>
437
+
438
+ # List security namespaces
439
+ az devops security namespace list --output table
440
+ ```
441
+
442
+ ---
443
+
444
+ ## 3. Pipeline Authoring
445
+
446
+ ### Basic Pipeline Structure
447
+
448
+ ```yaml
449
+ # azure-pipelines.yml
450
+ trigger:
451
+ branches:
452
+ include:
453
+ - main
454
+ - release/*
455
+ paths:
456
+ exclude:
457
+ - README.md
458
+ - docs/*
459
+
460
+ pr:
461
+ branches:
462
+ include:
463
+ - main
464
+ drafts: false
465
+
466
+ pool:
467
+ vmImage: 'ubuntu-latest'
468
+
469
+ variables:
470
+ buildConfiguration: 'Release'
471
+ dotnetVersion: '8.0.x'
472
+
473
+ steps:
474
+ - task: UseDotNet@2
475
+ inputs:
476
+ packageType: 'sdk'
477
+ version: $(dotnetVersion)
478
+
479
+ - script: dotnet build --configuration $(buildConfiguration)
480
+ displayName: 'Build project'
481
+
482
+ - script: dotnet test --configuration $(buildConfiguration) --no-build --logger trx
483
+ displayName: 'Run tests'
484
+
485
+ - task: PublishTestResults@2
486
+ inputs:
487
+ testResultsFiles: '**/*.trx'
488
+ testRunTitle: 'Unit Tests'
489
+ ```
490
+
491
+ ### Multi-Stage Pipeline
492
+
493
+ ```yaml
494
+ trigger:
495
+ - main
496
+
497
+ stages:
498
+ - stage: Build
499
+ displayName: 'Build Stage'
500
+ jobs:
501
+ - job: Build
502
+ displayName: 'Build Job'
503
+ pool:
504
+ vmImage: 'ubuntu-latest'
505
+ steps:
506
+ - script: echo "Building..."
507
+ - publish: $(Build.SourcesDirectory)/src
508
+ artifact: sourceCode
509
+
510
+ - stage: Test
511
+ displayName: 'Test Stage'
512
+ dependsOn: Build
513
+ jobs:
514
+ - job: UnitTests
515
+ displayName: 'Unit Tests'
516
+ steps:
517
+ - download: current
518
+ artifact: sourceCode
519
+ - script: echo "Running unit tests..."
520
+
521
+ - job: IntegrationTests
522
+ displayName: 'Integration Tests'
523
+ dependsOn: UnitTests
524
+ steps:
525
+ - download: current
526
+ artifact: sourceCode
527
+ - script: echo "Running integration tests..."
528
+
529
+ - stage: Deploy
530
+ displayName: 'Deploy Stage'
531
+ dependsOn: Test
532
+ condition: succeeded()
533
+ jobs:
534
+ - deployment: DeployWeb
535
+ displayName: 'Deploy Web App'
536
+ environment: 'Production'
537
+ strategy:
538
+ runOnce:
539
+ deploy:
540
+ steps:
541
+ - script: echo "Deploying to Production..."
542
+ ```
543
+
544
+ ### Pipeline Templates
545
+
546
+ **Template file (templates/build.yml):**
547
+ ```yaml
548
+ parameters:
549
+ - name: buildConfiguration
550
+ type: string
551
+ default: 'Release'
552
+ - name: projects
553
+ type: string
554
+ default: '**/*.csproj'
555
+ - name: dotnetVersion
556
+ type: string
557
+ default: '8.0.x'
558
+
559
+ steps:
560
+ - task: UseDotNet@2
561
+ inputs:
562
+ packageType: 'sdk'
563
+ version: ${{ parameters.dotnetVersion }}
564
+ displayName: 'Install .NET SDK'
565
+
566
+ - task: DotNetCoreCLI@2
567
+ inputs:
568
+ command: 'build'
569
+ projects: ${{ parameters.projects }}
570
+ arguments: '--configuration ${{ parameters.buildConfiguration }}'
571
+ displayName: 'Build Projects'
572
+
573
+ - task: DotNetCoreCLI@2
574
+ inputs:
575
+ command: 'test'
576
+ projects: ${{ parameters.projects }}
577
+ arguments: '--configuration ${{ parameters.buildConfiguration }} --no-build'
578
+ displayName: 'Run Tests'
579
+ ```
580
+
581
+ **Using the template:**
582
+ ```yaml
583
+ # azure-pipelines.yml
584
+ trigger:
585
+ - main
586
+
587
+ stages:
588
+ - stage: Build
589
+ jobs:
590
+ - job: BuildAPI
591
+ steps:
592
+ - template: templates/build.yml
593
+ parameters:
594
+ buildConfiguration: 'Release'
595
+ projects: 'src/API/*.csproj'
596
+ dotnetVersion: '8.0.x'
597
+
598
+ - job: BuildWorker
599
+ steps:
600
+ - template: templates/build.yml
601
+ parameters:
602
+ buildConfiguration: 'Release'
603
+ projects: 'src/Worker/*.csproj'
604
+ dotnetVersion: '8.0.x'
605
+ ```
606
+
607
+ ### Conditional Logic
608
+
609
+ ```yaml
610
+ variables:
611
+ ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
612
+ environment: 'Production'
613
+ ${{ if ne(variables['Build.SourceBranch'], 'refs/heads/main') }}:
614
+ environment: 'Development'
615
+
616
+ steps:
617
+ - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
618
+ - script: echo "Deploying to Production"
619
+ displayName: 'Production Deploy'
620
+
621
+ - ${{ if ne(variables['Build.SourceBranch'], 'refs/heads/main') }}:
622
+ - script: echo "Deploying to Development"
623
+ displayName: 'Development Deploy'
624
+
625
+ # Using conditions on steps
626
+ - script: echo "This runs only on main"
627
+ condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
628
+
629
+ # Using stage conditions
630
+ - stage: Deploy
631
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
632
+ ```
633
+
634
+ ### Matrix Strategy
635
+
636
+ ```yaml
637
+ strategy:
638
+ matrix:
639
+ linux:
640
+ imageName: 'ubuntu-latest'
641
+ dotnetVersion: '8.0.x'
642
+ windows:
643
+ imageName: 'windows-latest'
644
+ dotnetVersion: '8.0.x'
645
+ mac:
646
+ imageName: 'macos-latest'
647
+ dotnetVersion: '8.0.x'
648
+ maxParallel: 3
649
+
650
+ pool:
651
+ vmImage: $(imageName)
652
+
653
+ steps:
654
+ - task: UseDotNet@2
655
+ inputs:
656
+ packageType: 'sdk'
657
+ version: $(dotnetVersion)
658
+ ```
659
+
660
+ ### Deployment Jobs with Environments
661
+
662
+ ```yaml
663
+ stages:
664
+ - stage: Deploy
665
+ jobs:
666
+ - deployment: DeployApp
667
+ displayName: 'Deploy Application'
668
+ environment:
669
+ name: 'Production'
670
+ resourceType: VirtualMachine
671
+ tags: web
672
+ strategy:
673
+ runOnce:
674
+ deploy:
675
+ steps:
676
+ - script: echo "Deploying to Production"
677
+
678
+ - deployment: DeployWithApprovals
679
+ displayName: 'Deploy with Manual Approval'
680
+ environment: 'Staging'
681
+ strategy:
682
+ runOnce:
683
+ deploy:
684
+ steps:
685
+ - script: echo "Deploying to Staging"
686
+ ```
687
+
688
+ ### Blue-Green Deployment
689
+
690
+ ```yaml
691
+ stages:
692
+ - stage: DeployBlue
693
+ displayName: 'Deploy to Blue Environment'
694
+ jobs:
695
+ - deployment: DeployBlue
696
+ environment: 'Production-Blue'
697
+ strategy:
698
+ runOnce:
699
+ deploy:
700
+ steps:
701
+ - task: AzureWebApp@1
702
+ inputs:
703
+ azureSubscription: 'MyServiceConnection'
704
+ appName: 'myapp-blue'
705
+ package: $(Pipeline.Workspace)/drop/*.zip
706
+
707
+ - stage: SwitchTraffic
708
+ displayName: 'Switch Traffic to Blue'
709
+ dependsOn: DeployBlue
710
+ jobs:
711
+ - deployment: SwitchTraffic
712
+ environment: 'Production'
713
+ strategy:
714
+ runOnce:
715
+ deploy:
716
+ steps:
717
+ - task: AzureAppServiceManage@0
718
+ inputs:
719
+ azureSubscription: 'MyServiceConnection'
720
+ Action: 'Swap Slots'
721
+ WebAppName: 'myapp'
722
+ ResourceGroupName: 'myResourceGroup'
723
+ SourceSlot: 'blue'
724
+ TargetSlot: 'production'
725
+
726
+ - stage: DeployGreen
727
+ displayName: 'Deploy to Green Environment'
728
+ dependsOn: SwitchTraffic
729
+ jobs:
730
+ - deployment: DeployGreen
731
+ environment: 'Production-Green'
732
+ strategy:
733
+ runOnce:
734
+ deploy:
735
+ steps:
736
+ - task: AzureWebApp@1
737
+ inputs:
738
+ azureSubscription: 'MyServiceConnection'
739
+ appName: 'myapp-green'
740
+ package: $(Pipeline.Workspace)/drop/*.zip
741
+ ```
742
+
743
+ ### Canary Deployment
744
+
745
+ ```yaml
746
+ stages:
747
+ - stage: Canary
748
+ displayName: 'Canary Deployment (10%)'
749
+ jobs:
750
+ - deployment: Canary
751
+ environment: 'Production'
752
+ strategy:
753
+ canary:
754
+ increments: [10, 25, 50, 100]
755
+ preDeploy:
756
+ steps:
757
+ - script: echo "Pre-deploy checks"
758
+ deploy:
759
+ steps:
760
+ - task: KubernetesManifest@1
761
+ inputs:
762
+ action: 'deploy'
763
+ kubernetesServiceConnection: 'aks-connection'
764
+ namespace: 'production'
765
+ manifests: 'k8s/deployment.yml'
766
+ strategy: 'canary'
767
+ percentage: 10
768
+ postRouteTraffic:
769
+ steps:
770
+ - script: echo "Verify canary health"
771
+ - task: AzureMonitor@1
772
+ inputs:
773
+ resourceGroupName: 'myResourceGroup'
774
+ alertType: 'metric'
775
+ action: 'check'
776
+ on:
777
+ failure:
778
+ steps:
779
+ - script: echo "Rollback triggered"
780
+ success:
781
+ steps:
782
+ - script: echo "Canary successful"
783
+ ```
784
+
785
+ ### Container Jobs
786
+
787
+ ```yaml
788
+ resources:
789
+ containers:
790
+ - container: build
791
+ image: mcr.microsoft.com/dotnet/sdk:8.0
792
+ - container: test
793
+ image: mcr.microsoft.com/dotnet/sdk:8.0
794
+ options: --hostname test-container
795
+
796
+ jobs:
797
+ - job: BuildInContainer
798
+ container: build
799
+ steps:
800
+ - script: dotnet build
801
+ displayName: 'Build in Container'
802
+
803
+ - job: TestInContainer
804
+ container: test
805
+ dependsOn: BuildInContainer
806
+ steps:
807
+ - script: dotnet test
808
+ displayName: 'Test in Container'
809
+
810
+ # Custom container with service containers
811
+ - job: IntegrationTests
812
+ container:
813
+ image: mcr.microsoft.com/dotnet/sdk:8.0
814
+ services:
815
+ postgres:
816
+ image: postgres:15
817
+ env:
818
+ POSTGRES_PASSWORD: $(postgresPassword)
819
+ ports:
820
+ - 5432:5432
821
+ steps:
822
+ - script: dotnet test --filter "Category=Integration"
823
+ displayName: 'Run Integration Tests'
824
+ ```
825
+
826
+ ### Self-Hosted Agents
827
+
828
+ ```yaml
829
+ # Use self-hosted agent pool
830
+ pool:
831
+ name: 'MySelfHostedPool'
832
+ demands:
833
+ - agent.os -equals Linux
834
+ - npm
835
+
836
+ # Or with agent capabilities
837
+ pool:
838
+ name: 'MySelfHostedPool'
839
+ demands:
840
+ - Agent.OS -equals Linux
841
+ - Agent.Version -gtVersion 2.200.0
842
+
843
+ # Job-level pool override
844
+ jobs:
845
+ - job: Build
846
+ pool: 'MySelfHostedPool'
847
+ steps:
848
+ - script: echo "Building on self-hosted agent"
849
+
850
+ - job: Deploy
851
+ pool:
852
+ vmImage: 'ubuntu-latest'
853
+ steps:
854
+ - script: echo "Deploying on Microsoft-hosted agent"
855
+ ```
856
+
857
+ ### Service Connections in Pipelines
858
+
859
+ ```yaml
860
+ # Azure Resource Manager
861
+ - task: AzureWebApp@1
862
+ inputs:
863
+ azureSubscription: 'MyArmConnection' # Service connection name
864
+ appName: 'my-web-app'
865
+ package: $(Pipeline.Workspace)/drop/*.zip
866
+
867
+ # Kubernetes
868
+ - task: KubernetesManifest@1
869
+ inputs:
870
+ kubernetesServiceConnection: 'MyAksConnection'
871
+ action: 'deploy'
872
+ namespace: 'default'
873
+ manifests: 'k8s/*.yml'
874
+
875
+ # Docker Registry
876
+ - task: Docker@2
877
+ inputs:
878
+ containerRegistry: 'MyAcrConnection' # Docker registry service connection
879
+ repository: 'myapp'
880
+ command: 'buildAndPush'
881
+ Dockerfile: 'Dockerfile'
882
+ tags: |
883
+ $(Build.BuildId)
884
+ latest
885
+
886
+ # GitHub
887
+ - task: GitHubRelease@1
888
+ inputs:
889
+ gitHubConnection: 'MyGitHubConnection'
890
+ repositoryName: 'myorg/myrepo'
891
+ action: 'create'
892
+ tagSource: 'userSpecifiedTag'
893
+ tag: 'v$(Build.BuildId)'
894
+ ```
895
+
896
+ ### Key Vault Integration
897
+
898
+ ```yaml
899
+ # Azure Key Vault task
900
+ - task: AzureKeyVault@2
901
+ inputs:
902
+ azureSubscription: 'MyServiceConnection'
903
+ KeyVaultName: 'my-keyvault'
904
+ SecretsFilter: '*'
905
+ RunAsPreJob: false
906
+
907
+ # Use secrets in subsequent tasks
908
+ - script: |
909
+ echo "Database connection string: $(DatabaseConnectionString)"
910
+ env:
911
+ DB_CONNECTION: $(DatabaseConnectionString)
912
+
913
+ # Map secrets to variables
914
+ variables:
915
+ - group: 'MyVariableGroup'
916
+ - name: dbPassword
917
+ value: $[variables.DatabasePassword]
918
+ ```
919
+
920
+ ---
921
+
922
+ ## 4. Infrastructure as Code
923
+
924
+ ### Bicep Templates
925
+
926
+ **main.bicep:**
927
+ ```bicep
928
+ @description('Location for all resources')
929
+ param location string = resourceGroup().location
930
+
931
+ @description('Name of the storage account')
932
+ param storageAccountName string
933
+
934
+ @description('Storage account SKU')
935
+ param storageSku string = 'Standard_LRS'
936
+
937
+ @description('Tags to apply to resources')
938
+ param tags object = {
939
+ environment: 'production'
940
+ project: 'myapp'
941
+ }
942
+
943
+ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
944
+ name: storageAccountName
945
+ location: location
946
+ sku: {
947
+ name: storageSku
948
+ }
949
+ kind: 'StorageV2'
950
+ properties: {
951
+ accessTier: 'Hot'
952
+ minimumTlsVersion: 'TLS1_2'
953
+ supportsHttpsTrafficOnly: true
954
+ }
955
+ tags: tags
956
+ }
957
+
958
+ resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
959
+ name: '${storageAccountName}-plan'
960
+ location: location
961
+ sku: {
962
+ name: 'P1v3'
963
+ tier: 'PremiumV3'
964
+ capacity: 1
965
+ }
966
+ properties: {
967
+ reserved: false
968
+ }
969
+ tags: tags
970
+ }
971
+
972
+ resource webApp 'Microsoft.Web/sites@2023-01-01' = {
973
+ name: '${storageAccountName}-app'
974
+ location: location
975
+ properties: {
976
+ serverFarmId: appServicePlan.id
977
+ siteConfig: {
978
+ appSettings: [
979
+ {
980
+ name: 'StorageConnectionString'
981
+ value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=core.windows.net'
982
+ }
983
+ ]
984
+ httpsOnly: true
985
+ minTlsVersion: '1.2'
986
+ }
987
+ }
988
+ tags: tags
989
+ }
990
+
991
+ output storageAccountId string = storageAccount.id
992
+ output webAppUrl string = 'https://${webApp.defaultHostName}'
993
+ ```
994
+
995
+ **Deploy Bicep with Azure CLI:**
996
+ ```bash
997
+ # Validate template
998
+ az deployment group validate --resource-group myResourceGroup --template-file main.bicep --parameters storageAccountName=mystorage123
999
+
1000
+ # What-if deployment (preview changes)
1001
+ az deployment group what-if --resource-group myResourceGroup --template-file main.bicep --parameters storageAccountName=mystorage123
1002
+
1003
+ # Deploy
1004
+ az deployment group create --resource-group myResourceGroup --template-file main.bicep --parameters storageAccountName=mystorage123
1005
+
1006
+ # Deploy with parameter file
1007
+ az deployment group create --resource-group myResourceGroup --template-file main.bicep --parameters @parameters.json
1008
+ ```
1009
+
1010
+ **Bicep Pipeline:**
1011
+ ```yaml
1012
+ trigger:
1013
+ - main
1014
+
1015
+ pool:
1016
+ vmImage: 'ubuntu-latest'
1017
+
1018
+ stages:
1019
+ - stage: Validate
1020
+ jobs:
1021
+ - job: Validate
1022
+ steps:
1023
+ - task: AzureCLI@2
1024
+ inputs:
1025
+ azureSubscription: 'MyServiceConnection'
1026
+ scriptType: 'bash'
1027
+ scriptLocation: 'inlineScript'
1028
+ inlineScript: |
1029
+ az deployment group validate \
1030
+ --resource-group $(resourceGroup) \
1031
+ --template-file ./infrastructure/main.bicep \
1032
+ --parameters ./infrastructure/parameters.json
1033
+
1034
+ - stage: Deploy
1035
+ dependsOn: Validate
1036
+ jobs:
1037
+ - deployment: DeployInfrastructure
1038
+ environment: 'Production'
1039
+ strategy:
1040
+ runOnce:
1041
+ deploy:
1042
+ steps:
1043
+ - task: AzureCLI@2
1044
+ inputs:
1045
+ azureSubscription: 'MyServiceConnection'
1046
+ scriptType: 'bash'
1047
+ scriptLocation: 'inlineScript'
1048
+ inlineScript: |
1049
+ az deployment group create \
1050
+ --resource-group $(resourceGroup) \
1051
+ --template-file ./infrastructure/main.bicep \
1052
+ --parameters ./infrastructure/parameters.json
1053
+ ```
1054
+
1055
+ ### ARM Templates
1056
+
1057
+ ```json
1058
+ {
1059
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
1060
+ "contentVersion": "1.0.0.0",
1061
+ "parameters": {
1062
+ "storageAccountName": {
1063
+ "type": "string",
1064
+ "minLength": 3,
1065
+ "maxLength": 24,
1066
+ "metadata": {
1067
+ "description": "Name of the storage account"
1068
+ }
1069
+ },
1070
+ "location": {
1071
+ "type": "string",
1072
+ "defaultValue": "[resourceGroup().location]",
1073
+ "metadata": {
1074
+ "description": "Location for all resources"
1075
+ }
1076
+ },
1077
+ "storageSku": {
1078
+ "type": "string",
1079
+ "defaultValue": "Standard_LRS",
1080
+ "allowedValues": ["Standard_LRS", "Standard_GRS", "Premium_LRS"],
1081
+ "metadata": {
1082
+ "description": "Storage account SKU"
1083
+ }
1084
+ }
1085
+ },
1086
+ "variables": {
1087
+ "storageApiVersion": "2023-05-01"
1088
+ },
1089
+ "resources": [
1090
+ {
1091
+ "type": "Microsoft.Storage/storageAccounts",
1092
+ "apiVersion": "[variables('storageApiVersion')]",
1093
+ "name": "[parameters('storageAccountName')]",
1094
+ "location": "[parameters('location')]",
1095
+ "sku": {
1096
+ "name": "[parameters('storageSku')]"
1097
+ },
1098
+ "kind": "StorageV2",
1099
+ "properties": {
1100
+ "accessTier": "Hot",
1101
+ "minimumTlsVersion": "TLS1_2"
1102
+ }
1103
+ }
1104
+ ],
1105
+ "outputs": {
1106
+ "storageAccountId": {
1107
+ "type": "string",
1108
+ "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
1109
+ }
1110
+ }
1111
+ }
1112
+ ```
1113
+
1114
+ ### Terraform with Azure
1115
+
1116
+ **main.tf:**
1117
+ ```hcl
1118
+ provider "azurerm" {
1119
+ features {}
1120
+ subscription_id = var.subscription_id
1121
+ tenant_id = var.tenant_id
1122
+ }
1123
+
1124
+ resource "azurerm_resource_group" "main" {
1125
+ name = "${var.prefix}-rg"
1126
+ location = var.location
1127
+ tags = var.tags
1128
+ }
1129
+
1130
+ resource "azurerm_storage_account" "main" {
1131
+ name = "${var.prefix}storage"
1132
+ resource_group_name = azurerm_resource_group.main.name
1133
+ location = azurerm_resource_group.main.location
1134
+ account_tier = "Standard"
1135
+ account_replication_type = "LRS"
1136
+ min_tls_version = "TLS1_2"
1137
+
1138
+ tags = var.tags
1139
+ }
1140
+
1141
+ resource "azurerm_app_service_plan" "main" {
1142
+ name = "${var.prefix}-plan"
1143
+ location = azurerm_resource_group.main.location
1144
+ resource_group_name = azurerm_resource_group.main.name
1145
+ sku {
1146
+ tier = "PremiumV3"
1147
+ size = "P1v3"
1148
+ }
1149
+ tags = var.tags
1150
+ }
1151
+
1152
+ resource "azurerm_linux_web_app" "main" {
1153
+ name = "${var.prefix}-app"
1154
+ location = azurerm_resource_group.main.location
1155
+ resource_group_name = azurerm_resource_group.main.name
1156
+ service_plan_id = azurerm_app_service_plan.main.id
1157
+
1158
+ site_config {
1159
+ always_on = true
1160
+ application_stack {
1161
+ docker_image = "${var.acr_name}.azurecr.io/${var.image_name}"
1162
+ docker_image_tag = var.image_tag
1163
+ }
1164
+ }
1165
+
1166
+ app_settings = {
1167
+ "WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false"
1168
+ "DOCKER_REGISTRY_SERVER_URL" = "https://${var.acr_name}.azurecr.io"
1169
+ "DOCKER_REGISTRY_SERVER_USERNAME" = var.acr_username
1170
+ "DOCKER_REGISTRY_SERVER_PASSWORD" = var.acr_password
1171
+ }
1172
+
1173
+ tags = var.tags
1174
+ }
1175
+
1176
+ output "web_app_url" {
1177
+ value = azurerm_linux_web_app.main.default_hostname
1178
+ }
1179
+ ```
1180
+
1181
+ **Terraform Pipeline with Remote State:**
1182
+ ```yaml
1183
+ trigger:
1184
+ - main
1185
+
1186
+ variables:
1187
+ terraformVersion: '1.6.0'
1188
+ storageAccount: 'tfstate'
1189
+ container: 'tfstate'
1190
+ stateKey: 'terraform.tfstate'
1191
+
1192
+ stages:
1193
+ - stage: TerraformPlan
1194
+ displayName: 'Terraform Plan'
1195
+ jobs:
1196
+ - job: Plan
1197
+ steps:
1198
+ - task: TerraformInstaller@0
1199
+ inputs:
1200
+ terraformVersion: $(terraformVersion)
1201
+
1202
+ - task: TerraformTaskV4@4
1203
+ displayName: 'Terraform Init'
1204
+ inputs:
1205
+ provider: 'azurerm'
1206
+ command: 'init'
1207
+ backendServiceArm: 'MyServiceConnection'
1208
+ backendAzureRmResourceGroupName: 'terraform-state-rg'
1209
+ backendAzureRmStorageAccountName: $(storageAccount)
1210
+ backendAzureRmContainerName: $(container)
1211
+ backendAzureRmKey: $(stateKey)
1212
+
1213
+ - task: TerraformTaskV4@4
1214
+ displayName: 'Terraform Plan'
1215
+ inputs:
1216
+ provider: 'azurerm'
1217
+ command: 'plan'
1218
+ commandOptions: '-out=tfplan -var-file="$(Build.SourcesDirectory)/terraform/variables/$(environment).tfvars"'
1219
+ environmentServiceNameAzureRM: 'MyServiceConnection'
1220
+
1221
+ - stage: TerraformApply
1222
+ displayName: 'Terraform Apply'
1223
+ dependsOn: TerraformPlan
1224
+ condition: succeeded()
1225
+ jobs:
1226
+ - deployment: Apply
1227
+ environment: 'Production'
1228
+ strategy:
1229
+ runOnce:
1230
+ deploy:
1231
+ steps:
1232
+ - task: TerraformInstaller@0
1233
+ inputs:
1234
+ terraformVersion: $(terraformVersion)
1235
+
1236
+ - task: TerraformTaskV4@4
1237
+ displayName: 'Terraform Init'
1238
+ inputs:
1239
+ provider: 'azurerm'
1240
+ command: 'init'
1241
+ backendServiceArm: 'MyServiceConnection'
1242
+ backendAzureRmResourceGroupName: 'terraform-state-rg'
1243
+ backendAzureRmStorageAccountName: $(storageAccount)
1244
+ backendAzureRmContainerName: $(container)
1245
+ backendAzureRmKey: $(stateKey)
1246
+
1247
+ - task: TerraformTaskV4@4
1248
+ displayName: 'Terraform Apply'
1249
+ inputs:
1250
+ provider: 'azurerm'
1251
+ command: 'apply'
1252
+ commandOptions: '-auto-approve -var-file="$(Build.SourcesDirectory)/terraform/variables/$(environment).tfvars"'
1253
+ environmentServiceNameAzureRM: 'MyServiceConnection'
1254
+ ```
1255
+
1256
+ ---
1257
+
1258
+ ## 5. Best Practices
1259
+
1260
+ ### Branch Policies
1261
+
1262
+ ```bash
1263
+ # Configure comprehensive branch policies
1264
+ # 1. Minimum reviewers
1265
+ az repos policy branch create \
1266
+ --project "MyProject" \
1267
+ --repository-id <repo-id> \
1268
+ --branch main \
1269
+ --policy-type "Minimum number of reviewers" \
1270
+ --settings '{
1271
+ "minimumApproverCount": 2,
1272
+ "creatorVoteCounts": false,
1273
+ "allowDownvotes": false,
1274
+ "resetOnSourcePush": true
1275
+ }'
1276
+
1277
+ # 2. Build validation
1278
+ az repos policy build create \
1279
+ --project "MyProject" \
1280
+ --repository-id <repo-id> \
1281
+ --branch main \
1282
+ --build-definition-id <definition-id> \
1283
+ --display-name "Build Validation" \
1284
+ --enabled true \
1285
+ --manual-queue-only false \
1286
+ --queue-on-source-update-only true \
1287
+ --valid-duration 720
1288
+
1289
+ # 3. Required reviewers for specific paths
1290
+ az repos policy required-reviewer create \
1291
+ --project "MyProject" \
1292
+ --repository-id <repo-id> \
1293
+ --branch main \
1294
+ --enabled true \
1295
+ --blocking true \
1296
+ --settings '{
1297
+ "requiredReviewerIds": ["<security-group-id>"],
1298
+ "message": "Security team review required for infrastructure changes",
1299
+ "scope": [{"path": "/infrastructure/*", "repositoryId": null}]
1300
+ }'
1301
+
1302
+ # 4. Work item linking
1303
+ az repos policy work-item-linking create \
1304
+ --project "MyProject" \
1305
+ --repository-id <repo-id> \
1306
+ --branch main \
1307
+ --enabled true \
1308
+ --blocking true
1309
+
1310
+ # 5. Comment resolution
1311
+ az repos policy comment-required create \
1312
+ --project "MyProject" \
1313
+ --repository-id <repo-id> \
1314
+ --branch main \
1315
+ --enabled true \
1316
+ --blocking true
1317
+ ```
1318
+
1319
+ ### Security Scanning Integration
1320
+
1321
+ ```yaml
1322
+ # SonarCloud integration
1323
+ - task: SonarCloudPrepare@1
1324
+ inputs:
1325
+ SonarCloud: 'SonarCloud'
1326
+ organization: 'myorg'
1327
+ scannerMode: 'MSBuild'
1328
+ projectKey: 'my-project'
1329
+ projectName: 'My Project'
1330
+ extraProperties: |
1331
+ sonar.exclusions=**/bin/**,**/obj/**
1332
+ sonar.coverage.exclusions=**/Tests/**
1333
+
1334
+ # Run analysis
1335
+ - task: SonarCloudAnalyze@1
1336
+
1337
+ # Publish results
1338
+ - task: SonarCloudPublish@1
1339
+ inputs:
1340
+ pollingTimeoutSec: '300'
1341
+
1342
+ # OWASP Dependency Check
1343
+ - task: dependency-check-build-task@6
1344
+ inputs:
1345
+ projectName: 'My Project'
1346
+ scanPath: '$(Build.SourcesDirectory)'
1347
+ format: 'HTML'
1348
+ failOnCVSS: '7'
1349
+
1350
+ # Snyk security scan
1351
+ - task: SnykSecurityScan@1
1352
+ inputs:
1353
+ serviceConnectionEndpoint: 'SnykConnection'
1354
+ testType: 'app'
1355
+ monitorWhen: 'always'
1356
+ failOnIssues: true
1357
+
1358
+ # Trivy container scan
1359
+ - task: Docker@2
1360
+ inputs:
1361
+ command: 'build'
1362
+ dockerfile: 'Dockerfile'
1363
+ tags: 'scan-target:latest'
1364
+
1365
+ - script: |
1366
+ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
1367
+ aquasec/trivy:latest image --exit-code 1 --severity HIGH,CRITICAL scan-target:latest
1368
+ displayName: 'Trivy Container Scan'
1369
+ ```
1370
+
1371
+ ### Secret Management
1372
+
1373
+ ```yaml
1374
+ # Pipeline structure for secret management
1375
+ variables:
1376
+ - group: 'NonSecretVariables'
1377
+ - group: 'SecretVariables' # Key Vault linked variable group
1378
+
1379
+ stages:
1380
+ - stage: Build
1381
+ jobs:
1382
+ - job: Build
1383
+ steps:
1384
+ - task: AzureKeyVault@2
1385
+ inputs:
1386
+ azureSubscription: 'MyServiceConnection'
1387
+ KeyVaultName: 'my-keyvault'
1388
+ SecretsFilter: 'DatabasePassword,ApiKey'
1389
+ name: GetSecrets
1390
+
1391
+ - script: |
1392
+ echo "Using secrets..."
1393
+ # Never echo secrets directly
1394
+ env:
1395
+ DB_PASSWORD: $(DatabasePassword)
1396
+ API_KEY: $(ApiKey)
1397
+
1398
+ # Azure Key Vault linked variable group (created via CLI or UI)
1399
+ # az pipelines variable-group create --name "SecretVariables" --project "MyProject" --authorize true --keyvault "my-keyvault" --secrets "DatabasePassword,ApiKey"
1400
+ ```
1401
+
1402
+ ### CI/CD Strategies
1403
+
1404
+ ```yaml
1405
+ # Feature branch workflow
1406
+ trigger:
1407
+ branches:
1408
+ include:
1409
+ - main
1410
+ - release/*
1411
+ paths:
1412
+ exclude:
1413
+ - docs/*
1414
+ - README.md
1415
+
1416
+ pr:
1417
+ branches:
1418
+ include:
1419
+ - main
1420
+ paths:
1421
+ include:
1422
+ - src/*
1423
+
1424
+ # Semantic versioning pipeline
1425
+ variables:
1426
+ major: 1
1427
+ minor: $[counter(variables['major'], 0)]
1428
+ patch: $[counter(format('{0}.{1}', variables['major'], variables['minor']), 0)]
1429
+ version: $(major).$(minor).$(patch)
1430
+
1431
+ stages:
1432
+ - stage: Build
1433
+ jobs:
1434
+ - job: Build
1435
+ steps:
1436
+ - script: |
1437
+ echo "##vso[build.updatebuildnumber]$(version)"
1438
+ - script: dotnet build -p:Version=$(version)
1439
+ ```
1440
+
1441
+ ### AKS Deployment Pipeline
1442
+
1443
+ ```yaml
1444
+ trigger:
1445
+ - main
1446
+
1447
+ resources:
1448
+ repositories:
1449
+ - repository: templates
1450
+ type: git
1451
+ name: 'Pipelines/Templates'
1452
+
1453
+ variables:
1454
+ imageRepository: 'myapp'
1455
+ dockerfilePath: 'Dockerfile'
1456
+ tag: '$(Build.BuildId)'
1457
+ k8sNamespace: 'default'
1458
+
1459
+ stages:
1460
+ - stage: Build
1461
+ displayName: 'Build and Push'
1462
+ jobs:
1463
+ - job: Build
1464
+ displayName: 'Build Docker Image'
1465
+ pool:
1466
+ vmImage: 'ubuntu-latest'
1467
+ steps:
1468
+ - task: Docker@2
1469
+ displayName: 'Build and Push to ACR'
1470
+ inputs:
1471
+ containerRegistry: 'MyAcrConnection'
1472
+ repository: $(imageRepository)
1473
+ command: 'buildAndPush'
1474
+ Dockerfile: $(dockerfilePath)
1475
+ tags: |
1476
+ $(tag)
1477
+ latest
1478
+
1479
+ - stage: Deploy
1480
+ displayName: 'Deploy to AKS'
1481
+ dependsOn: Build
1482
+ condition: succeeded()
1483
+ jobs:
1484
+ - deployment: Deploy
1485
+ displayName: 'Deploy to AKS'
1486
+ environment: 'Production.myakscluster'
1487
+ strategy:
1488
+ runOnce:
1489
+ deploy:
1490
+ steps:
1491
+ - task: KubernetesManifest@1
1492
+ displayName: 'Create namespace'
1493
+ inputs:
1494
+ action: 'createSecrets'
1495
+ kubernetesServiceConnection: 'MyAksConnection'
1496
+ namespace: $(k8sNamespace)
1497
+ secretType: 'dockerRegistry'
1498
+ secretName: 'acr-secret'
1499
+ dockerRegistryEndpoint: 'MyAcrConnection'
1500
+
1501
+ - task: KubernetesManifest@1
1502
+ displayName: 'Bake and Deploy'
1503
+ inputs:
1504
+ action: 'deploy'
1505
+ kubernetesServiceConnection: 'MyAksConnection'
1506
+ namespace: $(k8sNamespace)
1507
+ manifests: |
1508
+ $(Pipeline.Workspace)/manifests/deployment.yml
1509
+ $(Pipeline.Workspace)/manifests/service.yml
1510
+ $(Pipeline.Workspace)/manifests/ingress.yml
1511
+ containers: 'myacr.azurecr.io/$(imageRepository):$(tag)'
1512
+
1513
+ - task: KubernetesManifest@1
1514
+ displayName: 'Verify Deployment'
1515
+ inputs:
1516
+ action: 'deploy'
1517
+ kubernetesServiceConnection: 'MyAksConnection'
1518
+ namespace: $(k8sNamespace)
1519
+ manifests: |
1520
+ $(Pipeline.Workspace)/manifests/deployment.yml
1521
+ rolloutStatusTimeout: '300s'
1522
+ ```
1523
+
1524
+ ---
1525
+
1526
+ ## 6. Common Workflows
1527
+
1528
+ ### Create New Project with Full CI/CD
1529
+
1530
+ ```bash
1531
+ #!/bin/bash
1532
+ # Setup complete Azure DevOps project
1533
+
1534
+ ORG="https://dev.azure.com/myorg"
1535
+ PROJECT="MyNewProject"
1536
+ REPO="MyApp"
1537
+ SERVICE_CONNECTION="Azure-Connection"
1538
+
1539
+ # Create project
1540
+ az devops project create \
1541
+ --name "$PROJECT" \
1542
+ --organization "$ORG" \
1543
+ --visibility private \
1544
+ --source-control git \
1545
+ --process Agile
1546
+
1547
+ # Create repository
1548
+ az repos create \
1549
+ --name "$REPO" \
1550
+ --project "$PROJECT" \
1551
+ --organization "$ORG"
1552
+
1553
+ # Create variable groups
1554
+ az pipelines variable-group create \
1555
+ --name "SharedVariables" \
1556
+ --project "$PROJECT" \
1557
+ --organization "$ORG" \
1558
+ --variables environment=development region=eastus \
1559
+ --authorize true
1560
+
1561
+ # Create service connection
1562
+ az devops service-endpoint azurerm create \
1563
+ --name "$SERVICE_CONNECTION" \
1564
+ --project "$PROJECT" \
1565
+ --organization "$ORG" \
1566
+ --azure-rm-service-principal-id $SP_ID \
1567
+ --azure-rm-subscription-id $SUB_ID \
1568
+ --azure-rm-subscription-name $SUB_NAME \
1569
+ --azure-rm-tenant-id $TENANT_ID
1570
+
1571
+ # Create build pipeline
1572
+ az pipelines create \
1573
+ --name "CI-Pipeline" \
1574
+ --project "$PROJECT" \
1575
+ --organization "$ORG" \
1576
+ --repository "$REPO" \
1577
+ --repository-type tfsgit \
1578
+ --branch main \
1579
+ --yml-path azure-pipelines.yml
1580
+
1581
+ # Setup branch policies
1582
+ REPO_ID=$(az repos show --repository "$REPO" --project "$PROJECT" --query id -o tsv)
1583
+
1584
+ az repos policy branch create \
1585
+ --project "$PROJECT" \
1586
+ --repository-id "$REPO_ID" \
1587
+ --branch main \
1588
+ --policy-type "Minimum number of reviewers" \
1589
+ --settings '{"minimumApproverCount": 2, "creatorVoteCounts": false}'
1590
+ ```
1591
+
1592
+ ### GitHub Integration
1593
+
1594
+ ```yaml
1595
+ # Pipeline triggered by GitHub
1596
+ resources:
1597
+ repositories:
1598
+ - repository: mygithub
1599
+ type: github
1600
+ name: myorg/myrepo
1601
+ endpoint: 'GitHubConnection' # GitHub service connection
1602
+ ref: main
1603
+
1604
+ trigger: none # Disable CI trigger, use resource trigger
1605
+
1606
+ stages:
1607
+ - stage: Build
1608
+ jobs:
1609
+ - job: Build
1610
+ steps:
1611
+ - checkout: mygithub
1612
+ - script: |
1613
+ echo "Building from GitHub repo"
1614
+ ```
1615
+
1616
+ ### Docker/ACR Workflow
1617
+
1618
+ ```yaml
1619
+ # Complete Docker workflow
1620
+ variables:
1621
+ imageName: 'myapp'
1622
+ acrName: 'myacr'
1623
+ acrLoginServer: 'myacr.azurecr.io'
1624
+
1625
+ stages:
1626
+ - stage: Build
1627
+ jobs:
1628
+ - job: BuildImage
1629
+ pool:
1630
+ vmImage: 'ubuntu-latest'
1631
+ steps:
1632
+ - task: Docker@2
1633
+ displayName: 'Login to ACR'
1634
+ inputs:
1635
+ command: login
1636
+ containerRegistry: 'MyAcrConnection'
1637
+
1638
+ - task: Docker@2
1639
+ displayName: 'Build Image'
1640
+ inputs:
1641
+ repository: $(imageName)
1642
+ command: build
1643
+ Dockerfile: Dockerfile
1644
+ tags: |
1645
+ $(Build.BuildId)
1646
+ latest
1647
+ arguments: '--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')'
1648
+
1649
+ - task: Docker@2
1650
+ displayName: 'Push Image'
1651
+ inputs:
1652
+ command: push
1653
+ repository: $(imageName)
1654
+ containerRegistry: 'MyAcrConnection'
1655
+ tags: |
1656
+ $(Build.BuildId)
1657
+ latest
1658
+
1659
+ - task: Docker@2
1660
+ displayName: 'Run Trivy Scan'
1661
+ inputs:
1662
+ command: build
1663
+ repository: $(imageName)
1664
+ tags: 'scan'
1665
+ Dockerfile: Dockerfile
1666
+ enabled: false
1667
+
1668
+ - script: |
1669
+ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
1670
+ aquasec/trivy image --exit-code 1 --severity HIGH,CRITICAL \
1671
+ $(acrLoginServer)/$(imageName):$(Build.BuildId)
1672
+ displayName: 'Security Scan'
1673
+ ```
1674
+
1675
+ ---
1676
+
1677
+ ## 7. Troubleshooting
1678
+
1679
+ ### Pipeline Failures
1680
+
1681
+ ```yaml
1682
+ # Debug pipeline issues
1683
+ steps:
1684
+ - script: |
1685
+ echo "Build ID: $(Build.BuildId)"
1686
+ echo "Build Number: $(Build.BuildNumber)"
1687
+ echo "Source Branch: $(Build.SourceBranch)"
1688
+ echo "Source Version: $(Build.SourceVersion)"
1689
+ env | sort
1690
+ displayName: 'Debug Environment Variables'
1691
+
1692
+ - script: |
1693
+ ls -la $(Build.SourcesDirectory)
1694
+ find $(Build.SourcesDirectory) -type f -name "*.yml" | head -20
1695
+ displayName: 'Debug Source Directory'
1696
+
1697
+ # Enable system.debug for detailed logging
1698
+ variables:
1699
+ system.debug: true
1700
+ ```
1701
+
1702
+ ### Common Error Solutions
1703
+
1704
+ | Error | Solution |
1705
+ |-------|----------|
1706
+ | `No hosted parallelism has been purchased` | Request free parallelism or purchase agents |
1707
+ | `The term 'az' is not recognized` | Install Azure CLI in pipeline: `UsePythonVersion@0` then `pip install azure-cli` |
1708
+ | `Service connection not found` | Verify exact name match, check permissions |
1709
+ | `Unable to find secret` | Check Key Vault permissions, verify secret name |
1710
+ | `Docker build failed` | Check Dockerfile syntax, verify base image availability |
1711
+ | `Kubernetes deployment timeout` | Increase `rolloutStatusTimeout`, check pod logs |
1712
+ | `Permission denied` | Verify service principal has required RBAC roles |
1713
+
1714
+ ### Diagnostic Commands
1715
+
1716
+ ```bash
1717
+ # Check service principal permissions
1718
+ az role assignment list --assignee <app-id> --output table
1719
+
1720
+ # Test service connection
1721
+ az devops service-endpoint show --id <connection-id> --project "MyProject"
1722
+
1723
+ # Check pipeline permissions
1724
+ az pipelines show --name "MyPipeline" --project "MyProject" --query "permissions"
1725
+
1726
+ # View agent capabilities
1727
+ az pipelines agent show --pool-id <pool-id> --agent-id <agent-id>
1728
+
1729
+ # Check recent failures
1730
+ az pipelines runs list --project "MyProject" --result failed --top 10
1731
+ ```
1732
+
1733
+ ---
1734
+
1735
+ ## 8. References
1736
+
1737
+ ### Official Documentation
1738
+ - [Azure DevOps Documentation](https://learn.microsoft.com/en-us/azure/devops/)
1739
+ - [Azure CLI Reference](https://learn.microsoft.com/en-us/cli/azure/)
1740
+ - [Azure DevOps CLI](https://learn.microsoft.com/en-us/azure/devops/cli/)
1741
+ - [YAML Schema Reference](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/)
1742
+ - [Bicep Documentation](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/)
1743
+ - [Terraform Azure Provider](https://registry.terraform.io/providers/hashicorp/azurerm/)
1744
+
1745
+ ### Task References
1746
+ - [Azure Pipelines Tasks](https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/)
1747
+ - [Marketplace Extensions](https://marketplace.visualstudio.com/search?term=devops&target=AzureDevOps&category=All%20categories)
1748
+
1749
+ ### Best Practices
1750
+ - [Azure DevOps Best Practices](https://learn.microsoft.com/en-us/azure/devops/boards/best-practices-github)
1751
+ - [Security Best Practices](https://learn.microsoft.com/en-us/azure/devops/organizations/security/security-best-practices)
1752
+ - [Pipeline Security](https://learn.microsoft.com/en-us/azure/devops/pipelines/security/secure-pipelines)
1753
+
1754
+ ### Tools
1755
+ - [Azure DevOps Demo Generator](https://azuredevopsdemogenerator.azurewebsites.net/)
1756
+ - [YAML Pipeline Designer](https://azuredevopsdemogenerator.azurewebsites.net/)
1757
+ - [Bicep Playground](https://bicepdemo.z22.web.core.windows.net/)