Should you replace Azure Pipelines with self-hosted Jenkins?
Replace Azure Pipelines with self-hosted Jenkins when you need build and secret data to stay on infrastructure you control and your team can run Jenkins and its plugins well. Azure Pipelines fits best when your code, boards and pipelines already live in Azure DevOps, your builds are Microsoft-centric, and you are happy with parallel-job billing and Microsoft-hosted or managed agents. Self-hosted Jenkins fits best when a renewal, a parallel-job bill, a data residency rule or a lock-in concern is pushing you to own the controller, agents and credentials. Jenkins is distributed under the MIT License, so you can run it without a per-seat or per-job licence fee, but you then carry the server, agent and plugin work yourself.
The decision turns on three things. First, where build and secret data may live: Azure Pipelines secret variables and service connections cannot be read back once set, so you should confirm with your security team whether values must stay in your own network and which credential store Jenkins will use. Second, whether your team can operate Jenkins: the controller holds all configuration, plugins and secrets in $JENKINS_HOME, and you need a named owner for backups, plugin updates and the Java and LTS upgrade cycle. Third, how much of Azure DevOps moves with CI: if your repositories, boards and service connections stay in Azure, Jenkins will need to reach them through credentials and webhooks you build and maintain, and you should map those integrations before committing to a date.
Which scenarios favor Azure Pipelines and which favor Jenkins
This table maps common team situations to the platform that usually fits them better, along with the condition that drives the choice. Read each row against your own repositories, network rules and staffing, since the right answer often depends on one or two constraints rather than on the tool itself. Most teams find that the deciding factor is where their code, boards and build data must live.
| Scenario | Better fit | Condition that drives the choice |
|---|---|---|
| Azure Repos and Azure Boards across the whole engineering organization | Azure Pipelines | Keeping source, work items, pipelines and approvals in one vendor console avoids integration work, and moving CI alone means building a bridge from Azure Repos to Jenkins. |
| Regulated team that must keep build logs, artifacts and secrets inside its own network | Jenkins | Self-hosted controllers and agents keep logs and credentials in your environment, but you must confirm how your Azure DevOps contract and data residency terms apply to the current setup. |
| Windows and .NET build farm with MSBuild, Visual Studio and signing tools on the agents | Azure Pipelines | Microsoft-hosted Windows images and agent tooling reduce the number of machines you maintain, while Jenkins on Windows agents is workable but needs your team to manage the toolchain. |
| Kubernetes-heavy estate with containerized builds and ephemeral build capacity | Jenkins | Jenkins can run agents as Kubernetes pods through the Kubernetes plugin, which suits teams that already operate clusters and want build capacity to scale with them. |
| Mixed Linux and cloud workloads with many plugin-based integrations | Jenkins | The plugin ecosystem covers many tools, but each plugin adds upgrade and security work that someone on your team must own. |
| Small team with little platform staff and no dedicated DevOps engineer | Azure Pipelines | Hosted pipelines remove controller upkeep, backups and plugin updates, so the operating burden stays with the vendor, though parallel-job billing will grow with usage. |
| Team that wants pipelines defined in code and must leave a hosted service with minimal downtime | Jenkins | Jenkinsfiles live in the repository and can be migrated stage by stage, so you can run both systems in parallel during cutover. |
What changes for data control, hosting and compliance
Moving CI from Azure Pipelines to Jenkins changes where build logs, artifacts and secrets live, who operates the machines that run jobs, and how access is granted. Each card below covers one of those decisions and the checks to make before cutover. Confirm current Azure DevOps data residency and retention terms with Microsoft, since they set the baseline you are comparing against.
Logs, artifacts and secrets storage
In Azure Pipelines, run logs, artifacts and secret variables sit in Microsoft's service, and secret values cannot be read back once set. With Jenkins, build history, logs and credentials live in $JENKINS_HOME on the controller, so that directory becomes the data you must back up, encrypt and protect. Confirm where Jenkins credentials are stored and who can read the controller file system before you choose the storage layout. Plan an export of run history and artifacts before cutover, because secret values must be re-created rather than copied.
Hosting: Microsoft-hosted against your own agents
Azure Pipelines runs jobs on Microsoft-hosted agents by default, with self-hosted agents as an option. Jenkins has no hosted service of its own: you run the controller and build agents in your cloud account, data center or air-gapped network, and decide where each job executes. This gives you full control of network paths and image contents, but it also makes you responsible for patching, capacity and isolation of every agent. Decide early which network zone each agent type may reach, including artifact repositories and deployment targets.
Identity and access integration
Azure Pipelines uses Microsoft Entra ID and Azure DevOps permissions, so project membership and service connections follow the organization's directory. Jenkins authenticates users through its own security realm, which you can connect to your existing identity provider, and authorizes them through a matrix or role-based strategy you configure. Map each Azure DevOps group to a Jenkins role before migration, and confirm that service accounts used by pipelines are scoped to a single project. Test single sign-on and removal of leavers in a staging controller first.
Compliance evidence you must produce
Azure DevOps supplies some platform controls, but the audit evidence for your pipelines is still your responsibility after the move. With Jenkins, you need to show how the controller was configured, which plugins and versions run, how changes were approved, and how secrets and backups are protected. DeployOpen prepares controls and evidence for compliance assessments, but independent auditors issue any attestation or certification. Ask your auditor which of these artifacts they expect before work starts.
How the core capabilities compare
This table sets Azure Pipelines beside self-hosted Jenkins across the capabilities that most often decide a migration. Where the researched facts do not settle a point, the cell tells you what to confirm with Microsoft or in your own test environment. Use it to find the rows that matter for your estate, then test those rows before committing.
| Capability | Azure Pipelines | Self-hosted Jenkins |
|---|---|---|
| Pipeline definition | YAML pipelines stored in the repository, plus classic pipelines defined in the web UI | Jenkinsfile committed to source control, written in Declarative or Scripted syntax made of stages and steps |
| Agents and parallel execution | Microsoft-hosted or self-hosted agents, with parallel jobs as the billing unit | Controller plus build agents you run on machines or Kubernetes; parallelism depends on the capacity you provision |
| Plugin ecosystem | Marketplace extensions and built-in tasks; confirm coverage for your specific tools | More than 2,300 community-contributed plugins, which you install, update and secure yourself |
| Windows and .NET builds | Native Windows agent images and .NET tooling; confirm current image contents with Microsoft | Runs on Windows agents, but MSBuild, SDK and signing tooling must be installed and maintained by your team |
| Deployment and release stages | Classic release pipelines and YAML environments with approvals; classic creation is restricted in new organizations | Deployment stages written as pipeline code, with approvals and credentials defined through plugins or the pipeline itself |
| Configuration as code | Organization and project settings managed through the service and its API | Configuration as Code plugin reads YAML from CASC_JENKINS_CONFIG; it does not install plugins, so pair it with Docker images or the Helm chart |
| Kubernetes-based agents | Kubernetes agents are possible through self-hosted agent setups; confirm the supported pattern with Microsoft | Kubernetes plugin provisions agents as pods on demand; you size and monitor the cluster |
| Operating effort | Microsoft operates the service; your team manages agents, pools and service connections | Your team patches the controller, upgrades plugins and backs up $JENKINS_HOME, which holds configuration, plugins and secrets |
How YAML pipelines map to Jenkinsfiles
A Jenkinsfile is committed to the project's source control repository in the same way an Azure Pipelines YAML file sits beside the code, so the build definition travels with the code and is reviewed in the same pull requests. Stages and steps translate most directly: the stages of a YAML pipeline become Declarative stages and steps blocks, and jobs with their dependencies map to parallel stages or branches. Templates are the piece that needs a deliberate choice. Repeated YAML templates usually become a Jenkins shared library, which holds reusable Groovy functions and is loaded by name in each Jenkinsfile. Before migrating, inventory every template reference in your repositories, because each one becomes a library version you must pin and maintain.
Some concepts do not carry over and need redesign. Service connections and variable groups become Jenkins credentials, stored in the controller's credential store and referenced by ID in the Jenkinsfile, so the secret values must be re-entered by someone with access to the source system. Azure Pipelines agent pools have no one-to-one equivalent: they become Jenkins agents, or Kubernetes pod agents if you use the Kubernetes plugin. Confirm which agent operating systems and tools your current pools provide before choosing the agent design. The Jenkins Configuration as Code plugin can express controller settings such as security realm, credentials references and agent definitions in YAML, located through CASC_JENKINS_CONFIG. It does not install plugins, so the plugin set must come from your Docker images or the Helm chart, and that list belongs in version control alongside the Jenkinsfiles.
What each option costs over time and what drives it
Azure Pipelines and self-hosted Jenkins spread cost differently: one is a metered service, the other is software you operate. The cards below separate what you pay a vendor, what you run yourself, and what a move costs once, so you can ask for the right quote from each side.
Azure Pipelines licensing and compute
Azure Pipelines charges for parallel jobs, and you pick Microsoft-hosted or self-hosted agents, which means you also pay for the machines behind them. Check the current Microsoft price page for parallel job rates and any Azure DevOps user or add-on charges, since those change and depend on your tenant. The main cost drivers are the number of concurrent jobs, build minutes on hosted agents, and how many agent VMs you keep running. Ask Microsoft for a projected monthly figure based on your peak concurrency, not your average.
Jenkins software license
Jenkins is distributed under the MIT License, so the software itself carries no license fee. The recurring cost is everything around it: the controller, the build agents and the people who run them. Confirm with your legal team that MIT terms fit your policy for internal use, and check whether any plugins you depend on carry their own licenses. Vendor distributions such as CloudBees CI add a commercial subscription on top, so ask whether you need one before you budget.
Jenkins operations and upkeep
Running Jenkins recurs every month: controller and agent compute, storage for build history and artifacts, and staff time for plugin upgrades that follow each LTS line. Back up $JENKINS_HOME on the controller, because configuration, plugins and secrets all live there. Costs rise with the number of plugins, teams sharing one controller and the number of agents you scale to. Ask your platform team to estimate the hours for quarterly LTS upgrades and plugin testing, since that work is the largest hidden item.
One-time migration effort
Moving costs are mostly one-time: converting YAML pipelines into Jenkinsfiles, re-creating service connections and variable groups as Jenkins credentials, and rebuilding release stages. Azure Pipelines does not let you read secret values back, so plan to re-enter them and rotate them at the same time. Export run history, logs and artifacts before you switch off the old service, because retention limits and access changes make later exports harder. Ask any implementation partner for a fixed scope listing pipeline count, secret count and history depth.
What running Jenkins and its plugins asks of your team
Running Jenkins is recurring work, and the largest part of it is keeping the controller current. Jenkins LTS releases follow a fixed rhythm: the project picks a new LTS baseline every 12 weeks from a recent weekly release, then ships three LTS releases for that baseline in four-week cycles that contain only backported fixes. Your team should plan a standing upgrade slot against that cadence rather than treating upgrades as occasional projects. The Java support policy lists Java 21 (planned end of support September 2027) and Java 25 (planned end of support September 2029) as supported, and it marks 2.541.3 as the final LTS release for Java 17. If your controller or agents run Java 17, that is a dated migration item. Confirm the Java runtime on every controller and agent image before you schedule an upgrade.
Plugins are where most upgrade effort sits. LTS 2.580.1 stopped bundling several plugins, including the bouncycastle API, SSH server and JUnit plugins, so any pipeline that depends on them must install them through the plugin manager after the upgrade. Export your installed plugin list with versions and mark each one as bundled, third-party, or unused. Then test the pipelines that use each plugin in a staging controller. The effort depends on how many plugins you run and how many of them your Jenkinsfiles call directly, so estimate it from your own list instead of from a general figure. The Jenkins homepage describes more than 2,300 community plugins, and the count of plugins your team actually depends on is the number that matters.
Reduce risk with two controls. First, run a primary and a backup controller behind a proxy such as HAProxy or F5, which routes traffic to the backup if the primary fails. The scaling guide also recommends dedicated build agents so the controller only handles HTTP requests and manages the build environment, which keeps build load off the component you most need to keep available. Second, back up $JENKINS_HOME on a schedule and test restores. The scaling guide notes that configuration, plugins and secrets all live there, so a backup is your only recovery path for the controller. Confirm with your security team where those secrets are stored and who can read the backups, because $JENKINS_HOME holds credentials that you will need to re-create on any platform change.
What a move from Azure Pipelines to Jenkins involves
The sequence turns Azure Pipelines definitions, secrets and run history into Jenkins controllers, agents and Jenkinsfiles that have been checked against live results before the cutover.
Inventory pipelines, connections, variable groups and agent pools
List every pipeline, its trigger, the repositories it builds, each service connection, every variable group and the agent pools that run the jobs. Your team and DeployOpen's engineers review the list together and mark which pipelines are still in use. The inventory is done when every pipeline has an owner, a target and a named set of credentials it depends on, and the list is signed off in writing before any export begins.
Export definitions, run history, logs and artifacts
Copy YAML definitions from the repositories, which already hold them under version control, and export classic pipeline definitions through the REST API. Pull run history, logs and artifacts before the retention window on each item closes, since hosted build artifacts are kept only for limited periods on most CI services. Store the exports in your own archive. The step is complete when a checksum-verified copy of each item is held outside Azure DevOps and an index maps each export to its pipeline.
Re-create secrets and service connections in Jenkins credentials
Azure DevOps does not return secret variable values or service connection secrets, so the owners of each credential must supply the values again from their source systems, such as the cloud account, the registry or the deployment target. Store them as Jenkins credentials with the narrowest scope that works. The step is done when each recreated credential has been tested against its target and the owner has recorded where the original secret is kept.
Convert pipelines to Jenkinsfiles and shared libraries
Rewrite YAML stages, jobs and templates as Declarative Jenkinsfiles committed to each project's repository. Move reusable steps into a shared library so that common build and deploy logic lives in one place. Classic release stages become Jenkins deployment stages with approval gates. Each converted pipeline should pass a peer review and a dry run on a non-production branch. The output is a set of Jenkinsfiles and one versioned shared library that reviewers have approved.
Set up Jenkins controllers and build agents
Install the Jenkins controller and configure its plugins, using Configuration as Code files where your standards require repeatable setup. Provision build agents separately, for example as Kubernetes pod agents or Windows and Linux machines that match the platforms the old agent pools covered. Back up the controller's home directory, which holds configuration, plugins and secrets. The step closes when a test pipeline runs on every agent type and a restore from backup has been demonstrated.
Run both systems in parallel until results match
Keep Azure Pipelines active while Jenkins builds the same commits. Compare build outcomes, test counts, artifact checksums and deployed versions for an agreed run period. Investigate every mismatch, which often comes from environment variables, tool versions or Windows-specific paths. The step is complete when the team has signed off that the differences are explained and no open defects remain against the converted pipelines.
Cut over and retire the Azure pipelines
Switch triggers and deployment targets to Jenkins one pipeline group at a time, starting with lower-risk services. Disable the matching Azure pipelines after each switch rather than deleting them, so you can roll back. Repositories and Azure Boards can stay where they are during this work, because Jenkins connects to the repositories and the cutover only changes which system runs the builds. The step is done when every in-scope pipeline runs on Jenkins, the rollback path has been tested, and the cutover record is filed.
Questions buyers ask before switching from Azure Pipelines to Jenkins
What drives the cost of moving from Azure Pipelines to Jenkins?
The cost of moving is driven mainly by the number of pipelines, how much of each pipeline depends on Azure DevOps features, and how many agents you need to run. The one-time work covers converting YAML and classic release definitions to Jenkinsfiles and deployment stages, re-creating service connections and variable groups as Jenkins credentials, and validating builds on the new controller and agents. The recurring costs are the infrastructure for the controller and agents, storage for build history, plugin upkeep and the staff time to operate Jenkins. Ask any implementation partner for a written scope that lists the pipeline inventory, the agent platforms and the systems that must be verified before work starts, because those items determine the quote.
How long does a migration from Azure Pipelines to Jenkins take?
There is no fixed duration, because the timeline depends on pipeline count, complexity and how many deployment targets and approvals are involved. A team with a small set of standard YAML builds usually has a much shorter path than one with many classic release pipelines, custom task groups and deployment groups. Parallel work is possible when pipelines are grouped by application. Before agreeing on a schedule, ask for a pipeline inventory, a list of every external integration, and a plan for a parallel run where both systems build the same commits until results match. The written scope should state the timeline and its assumptions.
What does the migration need from our own team?
The work needs three groups of people from your side. Azure DevOps administrators are needed to export pipeline definitions, identify the variable groups, service connections and environments in use, and confirm which project permissions map to which Jenkins roles. A Jenkins operator is needed to own the controller, plugins, backups and agent images after handover, since everything that must be backed up lives in the Jenkins home directory on the controller. Security reviewers should approve how credentials, signing keys and deployment identities are stored and rotated in Jenkins. Your team also needs to confirm change windows and the approval path for production deployments.
Can our own team do the migration without an outside partner?
Yes, a capable internal team can do the migration, and the Jenkins Pipeline documentation covers Declarative and Scripted syntax in detail. The main risks for an internal team are the time needed to learn Jenkins plugins and shared libraries, the work of rebuilding approvals and environment gates, and the lack of a tested rollback plan. Teams that choose to do it alone should still run a parallel build period, document the Jenkins configuration and back up the controller before cutover. An outside partner is useful when the team wants fixed-scope delivery, hardening, backup design and documentation handed over in writing. DeployOpen plans, implements, hardens and documents self-hosted platforms in the client's own infrastructure, under a written scope.
Can Jenkins keep building our Windows and .NET applications?
Jenkins can run .NET builds, but whether it can replace your Windows build workflow depends on your environment, and this must be confirmed in your own setup. Jenkins uses agents, so Windows build agents would need to be connected and configured with the .NET SDKs, MSBuild versions, signing tools and any Windows-only test runners your projects use. Ask for a test build of your heaviest solution on a Windows agent before committing, and confirm how the team will run and patch those agents. Some Azure Pipelines tasks have no direct Jenkins equivalent, so the inventory should flag every task used in the YAML definitions.
How are secrets handled when we move from Azure Pipelines to Jenkins?
Secret values from Azure Pipelines cannot be exported, so they must be re-created in Jenkins. Secret variables and service connection credentials in Azure DevOps can be replaced or deleted but not read back, so the owners of each secret must supply the values again from their source systems, such as a vault or the identity provider. Store them as Jenkins credentials and restrict access by folder or job, and rotate any secret that has been copied through a shared file or chat. The security reviewer should check that the Jenkins credential store, the controller backup and the agent images do not expose these values.
What happens to our build history and artifacts during the move?
Build history and artifacts should be exported before the move because they are not carried over automatically. Azure Pipelines run logs, artifacts and classic pipeline definitions can be retrieved through its tools and REST API, and the team should decide which records must be kept for audit or support purposes. Jenkins keeps its own build records on the controller, so retention settings, disk capacity and backup schedules must be set deliberately. Ask your implementation partner to include an export plan for run history, logs and artifacts in the scope, and confirm with your compliance owner how long each record must be retained.
Who keeps Jenkins running after the migration is finished?
After cutover, your team owns the Jenkins controller, plugins, agents, backups and upgrades, unless you contract ongoing support. Jenkins publishes LTS releases on a regular cycle, and the LTS changelog notes that some plugins were removed from the bundle and must be installed separately, so upgrades need testing against your plugin set. Plan for recurring work on security patches, plugin updates, Java version support and agent maintenance. DeployOpen offers ongoing support, upgrades and continuous testing as retainers, and the scope and service level should be agreed in writing.
How DeployOpen helps evaluate, implement or migrate
DeployOpen is a Chainscore Labs company that plans, implements, hardens, backs up and documents self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For teams weighing Azure Pipelines against a self-hosted Jenkins controller and agents, we work from a written scope that covers pipeline conversion, agent design and the operating model around them.
How we scope
- Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
- We inventory existing YAML pipelines, classic release definitions, agent pools and parallel-job usage before proposing a Jenkins design.
- The written scope states which pipelines move, which stay on Azure Pipelines during a transition and who owns each decision.
- Quotes follow from the written scope, so cost drivers such as pipeline count and agent needs are visible to your procurement team.
How we build
- We convert YAML stages, jobs and templates into Jenkinsfiles and shared libraries, then test each converted pipeline against its original results.
- We design controller and build agent layout, including Kubernetes pod agents where your environment supports them, and document the sizing assumptions.
- Jenkins Configuration as Code files are written so controller settings live in version control, with plugins pinned and installed through your chosen image or chart.
- Secrets are re-created in Jenkins credentials from your own records, since Azure Pipelines secret values cannot be read back for export.
How we hand over
- Handover includes runbooks for backing up the controller home directory, restoring it and rotating credentials on a documented schedule.
- We document the plugin inventory, upgrade path across Jenkins LTS releases and the Java version your controller runs on.
- Your team receives the pipeline catalog, agent diagrams and a list of Azure Pipelines assets that were archived or retired, with evidence of each test run.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after the initial handover.
- Retainers can cover plugin upgrades, LTS baseline moves, agent image updates and backup restore exercises on a schedule you agree.
- We prepare systems, controls and evidence for compliance assessments, while independent auditors and certification bodies issue any audit reports.

