Skip to content

Patterns and Practices : Pipeline Naming and Organization

This document covers Azure DevOps patterns and practices for Pipeline naming and Organization.

Terminology and Concepts

Terminology

  1. Organization : The Top level tenant in Azure DevOps.
  2. Usually this resides in an Azure Subscription (for billing)
  3. It must have an Organization Owner
  4. you can use https://dev.azure.com/ORGANIZATION or https://ORGANIZATION.visualstudio.com/ to refer to it (however scripting/REST APIs require the former)
  5. Project : An Organization has one more more Projects.
  6. Project is the logical grouping of Boards, Work Items, Test Plans, Pipelines, Artifacts and Repos
  7. Some things span the Organization (Work Item numbering is Organization-wide. Artifact Feeds can be Organizationally scoped)
  8. Repo : Repo is the versioned object base in GIT
  9. Contains all branches and code for that Repo
  10. If TFVC, just one Repo per project, otherwise, many for GIT (default)

Pipeline Terminology

  1. Stage : The top most container of work in a Pipeline is a stage.
  2. A Pipeline can be declared without a stage, but then it's assumed just one stage
  3. Stages run in parallel unless denoted with "dependsOn:"
  4. Job : All pipelines need at least one job. This is the central container of work
  5. A Pipeline may have many jobs.
  6. Jobs run in parallel in Stages unless denoted with "dependsOn"
  7. Environments : The Pipeline Objects that contain Kubernetes clusters (which is a combination of Cluster and Namespace) and VM pools (under "Virtual Machines").
  8. These are used for deployment stages in Azure DevOps YAML based pipelines.
  9. They cannot be used by ClassicUI pipelines.
  10. Gates : The method of restricting usage to Environments.
  11. They are under the setting "Approvals and Checks" for an environment
  12. Presently, this includes:
    • Approvals: Users or Groups (teams) that can approve usage of this environment for deployment
    • Branch Control: Deployment limited to specific branches
    • Business Hours: Time based controls limiting deployments to time windows
    • Evaluate Artifact: Ensures artifacts match policies (e.g. container images only)
    • Exclusive Lock: limit access to a resource one stage at a time (needed for Blue Green)
    • Invoke Azure Function: invoke a function and check it's result
    • Invoke REST API: invoke a REST api with payload and verify its response
    • Query Azure Monitor Alerts: Check Azure Monitor rules for active alerts
    • Required Template: Ensure the Pipeline using this environment extends specific other pipelines (ref / path / repo)

*see more in Environments and Gating P&P

img/PnP-Naming-Org-Pipeline1.png Illustration 1: Pipeline running jobs in parallel in a single stage pipeline

Model Assumption

  1. ClassicUI vs YAML Pipelines : YAML
  2. ClassicUI, that still exists, is the "old" way and is going away.
  3. This had "Build" and "Release" pipelines
  4. "Release" pipelines still in use by Test Plans
  5. "Build Pipelines" in the old system are now just "Pipelines" in the YAML based model
  6. A YAML Pipeline is all encompassing and includes both compilation (build) and deployment (release)
  7. YAML Pipelines store the configuration (outside of gates) in Code and can vary by branches
  8. YAML Pipelines can be stored in any GIT repository including Gitlab, Github and Bitbucket, among others
  9. Many vs One Project
  10. The old model we used in CRHFSoftware was a single project for many teams
  11. The new model is Many Projects as described in Organizational - Structure, purpose and naming of Azure DevOps organization and team projects.
  12. Consider Projects now "Team Projects" instead of harboring "Teams" in a single Project
  13. There are many benefits (consult the linked confluence page for more)

Pipeline Naming

Pipeline and Repo names should be identical. Other than a "DEPRECATED" prefix, there is no reason to have a pipeline not named after the repo.

It's best to use lowercase just to avoid platform issues on some older computer systems, but not required. By default, when onboarding a pipeline from a repo, the name will match the repo.

Pipeline/Repo Naming

The pattern should include all relevant parts for a proper path.
Consider a FQDN, if you will, where we have service.company.tld.. such as confluence.medtronic.com. The top-level domain tells me Commercial (as opposed to say .uk for a UK based domain). The next is the company or entity. Lastly, the thing that resides within that entity, in this case, confluence.

Similarly, we want to name our repos in a fully qualified way so that when referencing them, including outside our project, they maintain uniqueness.

A good path would have: [Project]-[ACTIVITY_or_THING]-[TYPE]

Let's illustrate.

If I wished to have a template repository in a DevOps project in MDTProductDevelopment, the proper name would be devops-templates.

If the templates were of a type, such as Repos YAML templates, I might better make it as devops-repo-templates to avoid confusion with other templating technologies.

In our experience, there are a few high level types. Organizing by naming standards helps find the right code.

Top level types: - service - library - utility - poc

There are some specific suffixes based on particular needs: - subsystem - for the breakdown of legacy monolith TFVC into sub-component GIT repos - component - for core component testing

Exceptions

  1. Using "deprecated-" to indicate a pipeline is slated for termination
  2. visually, you can use "folders" in Azure DevOps to organize pipelines
    1. this just exists in the UI and is purely for your own ease in finding a pipeline
  3. Using -[trigger] to denote a scheduled pipeline. such as "-daily" or "-weekly"
  4. these are the exception - it would be better to add a schedule to the CI than have different pipelines
  5. however, there are some types of pipelines that due to their size and agent demands need special consideration

Considerations

Nothing is in stone. Pipelines can and will be renamed. - If a pipeline is named for a project that is not renamed. - A team assumed they would use one technology but now another is selected. - A name is ambiguous and needs more details to avoid user confusion

Consider users will have many repos checked out to their laptops. Having a clear name avoids confusion when looking at cloned repos.

FAQ

  1. What if I have many types of a project, for instance a java and dot net of a thing?
  2. If the thing in question is small, such as small utility, that when changed, should rebuild both the java and dotnet, create a single repo and use a build file to build both things
    • e.g. mdtproductdevelopment-devops-cli-utilities
    • azure-pipelines can use different agent types per stage so you could, for instance, build mac binaries on Mac OS, Android and iOS on another type, Windows binaries on Windows, Linux on Linux
  3. If the thing is developed independently - such that java changes just build java and the developers that update that tend to 'stay in their silo', it's worth having multiple repos
    • e.g mdtproductdevelopment-devops-cli-java-utilities and mdtproductdevelopment-devops-cli-dotnet-utilities
  4. What if I want to have many pipelines in a Repo?
  5. This causes many problems: What pipeline runs for a PR? How do you know which pipeline to run on code changes?
  6. Almost always this is an indication that either:
    • you need to break down a project repo into several new repos (this happens, small ideas grow to big ones)
    • you are really solving the needs better served with templates. Azure-pipelines.yaml, after all, is plural for a reason.
    • you can have stages tied to branches.
  7. You can use long lived branches for unique work.
    • e.g. project/altairr2 would build the "r2" lineage of a subsystem in the pipeline, and project/Zelda would build the same "azure-pipelines" file in its branch
    • we can use Gates on Environments to control deployments on Branch Names - this is a good and normal pattern
      • we cannot constrain deployments on subsystem builds (without significant hacking).
  8. Where do I put my testing?
  9. If it is integration testing - that is, the testing of may things together, that belongs in its own template or pipeline (depending on the nature of tests)
  10. you can use the Azure CLI with a PAT to invoke another pipeline, and bash to wait on completion (see infra-create for an example)
  11. Where do i put my templates?
  12. This is a good question and definitely depends on the scope of your shared work.
  13. Generally, start with them locally in a /templates path in a repo. If you see the use of sharing them with all of your project repos, you can create a "-templates" repo.
  14. If the general community could use them, share them into the shared template repo (in the old Org, this has been mlife-common-templates )