{"id":57948,"date":"2019-11-05T08:11:57","date_gmt":"2019-11-05T16:11:57","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/devops\/?p=57948"},"modified":"2019-11-08T21:43:08","modified_gmt":"2019-11-09T05:43:08","slug":"improved-continuous-delivery-capabilities-and-caching-for-azure-pipelines","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/improved-continuous-delivery-capabilities-and-caching-for-azure-pipelines\/","title":{"rendered":"Improved Continuous Delivery capabilities and caching for Azure Pipelines"},"content":{"rendered":"<p>We are thrilled to announce a new set of updates for <a href=\"https:\/\/azure.com\/pipelines\">Azure Pipelines<\/a>, the Continuous Integration and Continuous Delivery platform part of Azure DevOps. Our team has been hard at work for the past few months to deliver new features, including some that were much-requested by our users.<\/p>\n<h2>Improved CD capabilities for multi-stage YAML pipelines<\/h2>\n<p>Developers using multi-stage YAML pipelines can now manage deployment workflows in separate pipelines and trigger them using resources. As part of this experience we have added support for consuming other pipelines and images from <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/container-registry\/\">Azure Container Registry<\/a> (ACR) as resources.<\/p>\n<h2>\u201cpipeline\u201d as a resource<\/h2>\n<p>If you have an Azure Pipeline that produces artifacts, you can consume the artifacts by defining a pipeline resource, and you can also enable your pipeline to be automatically triggered on the completion of that pipeline resource.<\/p>\n<pre><code class=\"yaml\">resources:\n  pipelines:\n  - pipeline: SmartHotel\n    source: SmartHotel-CI \n    trigger: \n      branches:\n      - 'releases\/*'\n      - master\n<\/code><\/pre>\n<p>You can find more details about pipeline resource <a href=\"https:\/\/aka.ms\/Pipelineresource\">here<\/a>.<\/p>\n<h2>Azure Container Registry as \u201ccontainer\u201d resource<\/h2>\n<p>You can also use Azure Container Registry (ACR) container images to trigger the execution of a pipeline in Azure Pipelines when a new image is published to ACR:<\/p>\n<pre><code class=\"yaml\">resources:\n  containers:\n  - container: MyACR  \n    type: ACR\n    AzureSubscription: RMPM\n    resourcegroup: contosoRG\n    registry: contosodemo\n    repository: alphaworkz\n    trigger: \n      tags:\n        include: \n        - 'production*'\n<\/code><\/pre>\n<p>You can find more details about ACR resource <a href=\"https:\/\/aka.ms\/ACRResource\">here<\/a>.<\/p>\n<p>Just like with repositories, we support complete traceability for both pipelines and ACR container resource. For example, you can see the changes and the work items that were consumed in a run and the environment they were deployed to.<\/p>\n<h2>New deployment strategies<\/h2>\n<p>One of the key advantages of continuous delivery of application updates is the ability to quickly push updates into production for specific microservices. This gives you the ability to quickly respond to changes in business requirements.<\/p>\n<p>With this update, we are announcing support for two new deployment strategies: canary for <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/kubernetes-service\/\">Azure Kubernetes Service<\/a> (AKS), and rolling for Virtual Machines (in private preview). This is in addition to the rolling deployment strategy support for AKS that we <a href=\"https:\/\/devblogs.microsoft.com\/devops\/whats-new-with-azure-pipelines\/\">introduced<\/a> in the spring. Support for blue-green deployments and other resource types is coming in a few months.<\/p>\n<p><img decoding=\"async\" width=\"1079\" height=\"750\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/word-image.png\" class=\"wp-image-57949\" srcset=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/word-image.png 1079w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/word-image-300x209.png 300w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/word-image-768x534.png 768w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/word-image-1024x712.png 1024w\" sizes=\"(max-width: 1079px) 100vw, 1079px\" \/><\/p>\n<p><strong>Canary<\/strong>: In this strategy, the newer version (canary) is deployed next to the current version (stable), but only a portion of traffic is routed to canary to minimize risk. Once canary is found to be good based on metrics and other parameters, the exposure to newer version is gradually increased.<\/p>\n<p>Previously, when the canary strategy was specified with the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/tasks\/deploy\/kubernetes-manifest?view=azure-devops\"><code>KubernetesManifest<\/code><\/a>\u00a0task, the task created baseline and canary workloads whose replicas equaled a percentage of the replicas used for stable workloads. This was not exactly the same as splitting traffic up to the desired percentage at the request level. To tackle this, we have now introduced support for\u00a0<a href=\"https:\/\/smi-spec.io\/\">Service Mesh Interface<\/a>-based canary deployments in <code>KubernetesManifest<\/code> task. Service Mesh Interface (SMI) abstraction allows for plug-and-play configuration with service mesh providers such as Linkerd and Istio, while the <code>KubernetesManifest<\/code> task takes away the hard work of mapping SMI&#8217;s <code>TrafficSplit<\/code> objects to the stable, baseline and canary services during the lifecycle of the deployment strategy. The desired percentage split of traffic between stable, baseline and canary is more accurate as the percentage traffic split is done at the request level in the service mesh plane.<\/p>\n<p>Consider the following pipeline for performing canary deployments on Kubernetes using the Service Mesh Interface in an incremental manner:<\/p>\n<pre><code class=\"yaml\">- deployment:\n  displayName:\n  pool:\n    vmImage: $(pool)\n  environment: ignite.smi\n  strategy:\n    canary:\n      increments: [25, 50]\n      deploy:\n        steps:\n        - checkout: self\n        - task: KubernetesManifest@0\n          displayName: Deploy canary\n          inputs:\n            action: $(strategy.action)\n            namespace: smi\n            strategy: $(strategy.name)\n            trafficSplitMethod: smi\n            percentage: $(strategy.increment)\n            baselineAndCanaryReplicas: 1\n            manifests: 'manifests\/*'\n            containers: '$(imageRepository):$(Build.BuildId)'\n      postRouteTraffic:\n        pool: server\n        steps:\n          - task: Delay@1\n            inputs:\n              delayForMinutes: '2'\n      on:\n        failure:\n          steps:            \n          - script: echo deployment failed...\n          - task: KubernetesManifest@0\n            inputs:\n              action: reject\n              namespace: smi\n              strategy: $(strategy.name)\n              manifests: 'manifests\/*'\n        success:\n          steps:\n          - script: echo 'Successfully deployed'\n\n<\/code><\/pre>\n<p>In this case, request are routed incrementally to the canary deployment (at 25%, 50%, 100%) while providing a way for the user to gauge the health of the application between each of these increments under the <code>postRouteTraffic<\/code> lifecycle hook.<\/p>\n<p>Both canary and rolling strategies support following lifecycle hooks: <code>preDeploy<\/code> (executed once), iterations with <code>deploy<\/code>, <code>routeTraffic<\/code> and <code>postRouteTraffic<\/code> lifecycle hooks, and <code>exit<\/code> with either success and failure hooks.<\/p>\n<p>To learn more, check out the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/process\/deployment-jobs?view=azure-devops#deployment-strategies\">YAML <\/a><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/process\/deployment-jobs?view=azure-devops#deployment-strategies\">schema for <\/a><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/process\/deployment-jobs?view=azure-devops#deployment-strategies\">deployment jobs<\/a> and the <a href=\"https:\/\/github.com\/microsoft\/azure-pipelines-yaml\/blob\/master\/design\/deployment-strategies.md\">deployment strategies design<\/a> document.<\/p>\n<p>We are looking for early feedback on support for Virtual Machine resource in environments and performing rolling deployment strategy across multiple machines, which is now available in private preview. You can <a href=\"mailto:rm_customer_queries@microsoft.com?subject=VMResourcePrivateBeta\">enroll here<\/a>.<\/p>\n<h2>Pipeline Artifacts and Pipeline Caching<\/h2>\n<p>Pipeline Artifacts and Pipeline Caching are now generally available.<\/p>\n<p>You can use <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/artifacts\/pipeline-artifacts?view=azure-devops&amp;tabs=yaml\">Pipeline Artifacts<\/a> to store build outputs and move intermediate files between jobs in your pipeline. You can also download the artifacts from a pipeline from the build page, for as long as the build is retained. Pipeline Artifacts are the new generation of build artifacts: they take advantage of existing services to dramatically reduce the time it takes to store outputs in your pipelines.\u00a0<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/caching\/?view=azure-devops\">Pipeline Caching<\/a> can help reduce build time by allowing the outputs or downloaded dependencies from one run to be reused in later runs, thereby reducing or avoiding the cost to recreate or re-download the same files again. Caching is especially useful in scenarios where the same dependencies are compiled or downloaded over and over at the start of each run. This is often a time-consuming process involving hundreds or thousands of network calls.<\/p>\n<h2>What\u2019s next<\/h2>\n<p>We\u2019re constantly at work to improve the Azure Pipelines experience for our users. You can take a sneak peek into the work that\u2019s planned for the next months by looking at our <a href=\"https:\/\/devblogs.microsoft.com\/devops\/azure-devops-roadmap-update-for-2019-q4\/\">updated roadmap<\/a> for this quarter.<\/p>\n<p>As always, please let us know if you have any feedback by posting on our <a href=\"https:\/\/developercommunity.visualstudio.com\/spaces\/21\/index.html\">Developer Community<\/a>, or by reaching out on Twitter at <a href=\"https:\/\/twitter.com\/AzureDevOps\">@AzureDevOps<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What&#8217;s new with Azure Pipelines. We&#8217;ve updated Continuous Delivery capabilities with triggers on other pipelines and Azure Container Registry, and implemented new deployment strategies for VMs and Kubernetes. We&#8217;re also making Pipeline Caching and Pipeline Artifacts generally available.<\/p>\n","protected":false},"author":62,"featured_media":57949,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[224,226],"tags":[],"class_list":["post-57948","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-ci"],"acf":[],"blog_post_summary":"<p>What&#8217;s new with Azure Pipelines. We&#8217;ve updated Continuous Delivery capabilities with triggers on other pipelines and Azure Container Registry, and implemented new deployment strategies for VMs and Kubernetes. We&#8217;re also making Pipeline Caching and Pipeline Artifacts generally available.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/57948","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/62"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=57948"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/57948\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/57949"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=57948"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=57948"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=57948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}