/ .github / instructions / azure-devops-pipelines.instructions.md
azure-devops-pipelines.instructions.md
  1  ---
  2  description: 'Best practices for Azure DevOps Pipeline YAML files'
  3  applyTo: '**/azure-pipelines.yml, **/azure-pipelines*.yml, **/*.pipeline.yml'
  4  ---
  5  
  6  # Azure DevOps Pipeline YAML Best Practices
  7  
  8  Guidelines for creating maintainable, secure, and efficient Azure DevOps pipelines in PowerToys.
  9  
 10  ## General Guidelines
 11  
 12  - Use YAML syntax consistently with proper indentation (2 spaces)
 13  - Always include meaningful names and display names for pipelines, stages, jobs, and steps
 14  - Implement proper error handling and conditional execution
 15  - Use variables and parameters to make pipelines reusable and maintainable
 16  - Follow the principle of least privilege for service connections and permissions
 17  - Include comprehensive logging and diagnostics for troubleshooting
 18  
 19  ## Pipeline Structure
 20  
 21  - Organize complex pipelines using stages for better visualization and control
 22  - Use jobs to group related steps and enable parallel execution when possible
 23  - Implement proper dependencies between stages and jobs
 24  - Use templates for reusable pipeline components
 25  - Keep pipeline files focused and modular - split large pipelines into multiple files
 26  
 27  ## Build Best Practices
 28  
 29  - Use specific agent pool versions and VM images for consistency
 30  - Cache dependencies (npm, NuGet, Maven, etc.) to improve build performance
 31  - Implement proper artifact management with meaningful names and retention policies
 32  - Use build variables for version numbers and build metadata
 33  - Include code quality gates (lint checks, testing, security scans)
 34  - Ensure builds are reproducible and environment-independent
 35  
 36  ## Testing Integration
 37  
 38  - Run unit tests as part of the build process
 39  - Publish test results in standard formats (JUnit, VSTest, etc.)
 40  - Include code coverage reporting and quality gates
 41  - Implement integration and end-to-end tests in appropriate stages
 42  - Use test impact analysis when available to optimize test execution
 43  - Fail fast on test failures to provide quick feedback
 44  
 45  ## Security Considerations
 46  
 47  - Use Azure Key Vault for sensitive configuration and secrets
 48  - Implement proper secret management with variable groups
 49  - Use service connections with minimal required permissions
 50  - Enable security scans (dependency vulnerabilities, static analysis)
 51  - Implement approval gates for production deployments
 52  - Use managed identities when possible instead of service principals
 53  
 54  ## Deployment Strategies
 55  
 56  - Implement proper environment promotion (dev → staging → production)
 57  - Use deployment jobs with proper environment targeting
 58  - Implement blue-green or canary deployment strategies when appropriate
 59  - Include rollback mechanisms and health checks
 60  - Use infrastructure as code (ARM, Bicep, Terraform) for consistent deployments
 61  - Implement proper configuration management per environment
 62  
 63  ## Variable and Parameter Management
 64  
 65  - Use variable groups for shared configuration across pipelines
 66  - Implement runtime parameters for flexible pipeline execution
 67  - Use conditional variables based on branches or environments
 68  - Secure sensitive variables and mark them as secrets
 69  - Document variable purposes and expected values
 70  - Use variable templates for complex variable logic
 71  
 72  ## Performance Optimization
 73  
 74  - Use parallel jobs and matrix strategies when appropriate
 75  - Implement proper caching strategies for dependencies and build outputs
 76  - Use shallow clone for Git operations when full history isn't needed
 77  - Optimize Docker image builds with multi-stage builds and layer caching
 78  - Monitor pipeline performance and optimize bottlenecks
 79  - Use pipeline resource triggers efficiently
 80  
 81  ## Monitoring and Observability
 82  
 83  - Include comprehensive logging throughout the pipeline
 84  - Use Azure Monitor and Application Insights for deployment tracking
 85  - Implement proper notification strategies for failures and successes
 86  - Include deployment health checks and automated rollback triggers
 87  - Use pipeline analytics to identify improvement opportunities
 88  - Document pipeline behavior and troubleshooting steps
 89  
 90  ## Template and Reusability
 91  
 92  - Create pipeline templates for common patterns
 93  - Use extends templates for complete pipeline inheritance
 94  - Implement step templates for reusable task sequences
 95  - Use variable templates for complex variable logic
 96  - Version templates appropriately for stability
 97  - Document template parameters and usage examples
 98  
 99  ## Branch and Trigger Strategy
100  
101  - Implement appropriate triggers for different branch types
102  - Use path filters to trigger builds only when relevant files change
103  - Configure proper CI/CD triggers for main/master branches
104  - Use pull request triggers for code validation
105  - Implement scheduled triggers for maintenance tasks
106  - Consider resource triggers for multi-repository scenarios
107  
108  ## Example Structure
109  
110  ```yaml
111  # azure-pipelines.yml
112  trigger:
113    branches:
114      include:
115        - main
116        - develop
117    paths:
118      exclude:
119        - docs/*
120        - README.md
121  
122  variables:
123    - group: shared-variables
124    - name: buildConfiguration
125      value: 'Release'
126  
127  stages:
128    - stage: Build
129      displayName: 'Build and Test'
130      jobs:
131        - job: Build
132          displayName: 'Build Application'
133          pool:
134            vmImage: 'ubuntu-latest'
135          steps:
136            - task: UseDotNet@2
137              displayName: 'Use .NET SDK'
138              inputs:
139                version: '8.x'
140            
141            - task: DotNetCoreCLI@2
142              displayName: 'Restore dependencies'
143              inputs:
144                command: 'restore'
145                projects: '**/*.csproj'
146            
147            - task: DotNetCoreCLI@2
148              displayName: 'Build application'
149              inputs:
150                command: 'build'
151                projects: '**/*.csproj'
152                arguments: '--configuration $(buildConfiguration) --no-restore'
153  
154    - stage: Deploy
155      displayName: 'Deploy to Staging'
156      dependsOn: Build
157      condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
158      jobs:
159        - deployment: DeployToStaging
160          displayName: 'Deploy to Staging Environment'
161          environment: 'staging'
162          strategy:
163            runOnce:
164              deploy:
165                steps:
166                  - download: current
167                    displayName: 'Download drop artifact'
168                    artifact: drop
169                  - task: AzureWebApp@1
170                    displayName: 'Deploy to Azure Web App'
171                    inputs:
172                      azureSubscription: 'staging-service-connection'
173                      appType: 'webApp'
174                      appName: 'myapp-staging'
175                      package: '$(Pipeline.Workspace)/drop/**/*.zip'
176  ```
177  
178  ## Common Anti-Patterns to Avoid
179  
180  - Hardcoding sensitive values directly in YAML files
181  - Using overly broad triggers that cause unnecessary builds
182  - Mixing build and deployment logic in a single stage
183  - Not implementing proper error handling and cleanup
184  - Using deprecated task versions without upgrade plans
185  - Creating monolithic pipelines that are difficult to maintain
186  - Not using proper naming conventions for clarity
187  - Ignoring pipeline security best practices