<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://www.brandonbarnett.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.brandonbarnett.io/" rel="alternate" type="text/html" /><updated>2021-02-12T20:31:37+00:00</updated><id>https://www.brandonbarnett.io/feed.xml</id><title type="html">BrandonBarnett.io</title><subtitle>Talking about the nuances of technology.</subtitle><entry><title type="html">How to write code like a consultant</title><link href="https://www.brandonbarnett.io/blog/2021/02/how-to-write-code-like-a-consultant/" rel="alternate" type="text/html" title="How to write code like a consultant" /><published>2021-02-12T00:00:00+00:00</published><updated>2021-02-12T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2021/02/how-to-write-code-like-a-consultant</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2021/02/how-to-write-code-like-a-consultant/">&lt;p&gt;&lt;img src=&quot;/images/2021-2-12-how-to-write-code-like-a-consultant/ask-listen-learn.png&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As software development continues to grow with the world around us and offers more stable and lucrative opportunities, new developers might wonder how to differentiate themselves in an industry that is fairly homogenous and stereotypical. How do you break the mold and stand out from your peers to find more success and happiness in your career?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;I have been working with development teams for over 10 years, including people of all shapes and sizes. My previous few jobs were in consulting, which means I always had clients who dictated what success looked like. Lately with Phoenix Sports Partners, it is up to our product teams and me to define what that means. The theme I have seen throughout for developers who have stuck out to me has come down to their ability to think critically and be consultative - &lt;strong&gt;they are thoughtful, ask good questions and are good communicators&lt;/strong&gt;. They also are detail oriented and have good code hygiene.&lt;/p&gt;

&lt;p&gt;This is an example of how a standout developer would take a feature from story-to-production:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Read the story title and description (and acceptance criteria if available). Think through what you interpret to be the problem and ask clarifying questions if you find any ambiguities. Remember: you are more than a story-to-code translator - it is up to you to determine the full scope of how to meet the objective of a user story. Make sure you understand what the story is trying to accomplish and why. This will influence your ability to find edge cases.&lt;/li&gt;
  &lt;li&gt;Branch from the latest commit on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;develop&lt;/code&gt; branch (make sure to pull first). This is important because it will ensure there are no other unrelated changes in the branch. I occasionally see unrelated changes which makes it difficult to test code.&lt;/li&gt;
  &lt;li&gt;Write some code, test thoroughly. Make sure you’re thinking through edge cases at this point to ensure you don’t have to return to this work later when bugs are filed.&lt;/li&gt;
  &lt;li&gt;Push your branch.&lt;/li&gt;
  &lt;li&gt;When it comes time to create the PR, please review your own code before submitting. Sometimes things get missed locally in your commits that need to be tidied up before PR creation (e.g., commented code, commits accidentally included from other work).&lt;/li&gt;
  &lt;li&gt;I am not overly strict about encapsulating your changes to &lt;em&gt;ONLY&lt;/em&gt; what’s written in the story. However, please help me out by explaining any changes that aren’t obviously connected.&lt;/li&gt;
  &lt;li&gt;Any code that is not self documenting needs to have code comments. Any PR changes that are not self evident (e.g., are not a part of the story/AC) need to have source control (GitHub, BitBucket, ADO) comments from you to explain. The goal is that a reviewer should have all the context available in the PR to review your code without needing to ask follow up questions.&lt;/li&gt;
  &lt;li&gt;A PR is meant to represent code that you think is ready for production - it’s not a staging area. If it’s not ready, it should not be in PR.&lt;/li&gt;
  &lt;li&gt;Test all changes once deployed to the first higher-level environment. Typically for me out of my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;develop&lt;/code&gt; branches that is a Dev environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Throughout this process, always be thinking through the end user experience, and never hesitate to ask questions. I would so much rather field lots of questions than have to throw away or create rework later because we weren’t completely aligned on what you’re supposed to be doing.&lt;/p&gt;</content><author><name></name></author><category term="consulting" /><category term="development" /><summary type="html">As software development continues to grow with the world around us and offers more stable and lucrative opportunities, new developers might wonder how to differentiate themselves in an industry that is fairly homogenous and stereotypical. How do you break the mold and stand out from your peers to find more success and happiness in your career?</summary></entry><entry><title type="html">Should you generalize or become an expert?</title><link href="https://www.brandonbarnett.io/blog/2019/08/should-you-generalize-or-become-an-expert/" rel="alternate" type="text/html" title="Should you generalize or become an expert?" /><published>2019-08-12T00:00:00+00:00</published><updated>2019-08-12T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/08/should-you-generalize-or-become-an-expert</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/08/should-you-generalize-or-become-an-expert/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UQyUt-4fFjc&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/UQyUt-4fFjc/0.jpg&quot; alt=&quot;Should you generalize or become an expert?&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is better for your career: spreading your learning time across many subjects at a surface level or going all in on 1-2 topics? Check out my video to see what I think!&lt;/p&gt;</content><author><name></name></author><category term="learning" /><category term="career" /><summary type="html">What is better for your career: spreading your learning time across many subjects at a surface level or going all in on 1-2 topics? Check out my video to see what I think!</summary></entry><entry><title type="html">Leaving features behind</title><link href="https://www.brandonbarnett.io/blog/2019/08/leaving-features-behind/" rel="alternate" type="text/html" title="Leaving features behind" /><published>2019-08-09T00:00:00+00:00</published><updated>2019-08-09T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/08/leaving-features-behind</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/08/leaving-features-behind/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7hbDsmdPmbE&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/7hbDsmdPmbE/0.jpg&quot; alt=&quot;Leaving features behind&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every project has constraints; be aware of what they are, and be relentless and practical in your approach. Don’t make too many assumptions on your customers’ behalf by overloading your product with your favorite features.&lt;/p&gt;</content><author><name></name></author><category term="product" /><category term="software" /><category term="development" /><summary type="html">Every project has constraints; be aware of what they are, and be relentless and practical in your approach. Don’t make too many assumptions on your customers’ behalf by overloading your product with your favorite features.</summary></entry><entry><title type="html">How I keep current with tech</title><link href="https://www.brandonbarnett.io/blog/2019/07/how-I-keep-current-with-tech/" rel="alternate" type="text/html" title="How I keep current with tech" /><published>2019-07-16T00:00:00+00:00</published><updated>2019-07-16T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/07/how-I-keep-current-with-tech</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/07/how-I-keep-current-with-tech/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=x_YQWhdxUOE&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/x_YQWhdxUOE/0.jpg&quot; alt=&quot;How I keep current with tech&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We all have a lot to do! How do I keep current with technology - an industry where the only constant is change? Check out my video for how I keep up. How do you do continuously learn?&lt;/p&gt;</content><author><name></name></author><category term="software" /><category term="development" /><summary type="html">We all have a lot to do! How do I keep current with technology - an industry where the only constant is change? Check out my video for how I keep up. How do you do continuously learn?</summary></entry><entry><title type="html">Simplifying with social vs technical constraints</title><link href="https://www.brandonbarnett.io/blog/2019/07/simplifying-with-social-vs-technical-constraints/" rel="alternate" type="text/html" title="Simplifying with social vs technical constraints" /><published>2019-07-12T00:00:00+00:00</published><updated>2019-07-12T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/07/simplifying-with-social-vs-technical-constraints</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/07/simplifying-with-social-vs-technical-constraints/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=dFc7k16yRFg&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/dFc7k16yRFg/0.jpg&quot; alt=&quot;Simplifying with social vs technical constraints&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our team has been working on a software product and - in an effort to simplify our investment - have come to categorize our requirements as social or technical constraints. Please watch my video and I’ll explain the concept and how it could help you!&lt;/p&gt;</content><author><name></name></author><category term="content" /><summary type="html">Our team has been working on a software product and - in an effort to simplify our investment - have come to categorize our requirements as social or technical constraints. Please watch my video and I’ll explain the concept and how it could help you!</summary></entry><entry><title type="html">How to start creating video content</title><link href="https://www.brandonbarnett.io/blog/2019/07/how-to-start-creating-video-content/" rel="alternate" type="text/html" title="How to start creating video content" /><published>2019-07-05T00:00:00+00:00</published><updated>2019-07-05T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/07/how-to-start-creating-video-content</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/07/how-to-start-creating-video-content/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=N-LXULSBRNY&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/N-LXULSBRNY/0.jpg&quot; alt=&quot;How to start creating video content&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lots of people want to create online content but for a variety of reasons, find that life gets in the way. Here are a few thoughts on how to actually create your first video!&lt;/p&gt;</content><author><name></name></author><category term="content" /><summary type="html">Lots of people want to create online content but for a variety of reasons, find that life gets in the way. Here are a few thoughts on how to actually create your first video!</summary></entry><entry><title type="html">The secret to painless software product releases</title><link href="https://www.brandonbarnett.io/blog/2019/06/the-secret-to-painless-software-product-releases/" rel="alternate" type="text/html" title="The secret to painless software product releases" /><published>2019-06-30T00:00:00+00:00</published><updated>2019-06-30T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/06/the-secret-to-painless-software-product-releases</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/06/the-secret-to-painless-software-product-releases/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=LlL69StK6jI&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/LlL69StK6jI/0.jpg&quot; alt=&quot;The secret to painless software product releases&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During my time in consulting and product development, there has been one consistent theme throughout all of the best releases I’ve been a part of. Check out my secret to painless software product releases and reach out on Twitter &lt;a href=&quot;https://twitter.com/brandonbarnett&quot;&gt;@brandonbarnett&lt;/a&gt; if you have questions!&lt;/p&gt;</content><author><name></name></author><category term="product" /><category term="software" /><summary type="html">During my time in consulting and product development, there has been one consistent theme throughout all of the best releases I’ve been a part of. Check out my secret to painless software product releases and reach out on Twitter @brandonbarnett if you have questions!</summary></entry><entry><title type="html">Creating successful products</title><link href="https://www.brandonbarnett.io/blog/2019/06/creating-successful-products/" rel="alternate" type="text/html" title="Creating successful products" /><published>2019-06-23T00:00:00+00:00</published><updated>2019-06-23T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/06/creating-successful-products</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/06/creating-successful-products/">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Ee8ws_vPCsQ&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/Ee8ws_vPCsQ/0.jpg&quot; alt=&quot;Creating successful products&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Four key thoughts on how to create successful products.&lt;/p&gt;</content><author><name></name></author><category term="product" /><summary type="html">Four key thoughts on how to create successful products.</summary></entry><entry><title type="html">Why isn’t Azure App Service Deploy copying files to my Web App’s wwwroot?</title><link href="https://www.brandonbarnett.io/blog/2019/02/why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/" rel="alternate" type="text/html" title="Why isn’t Azure App Service Deploy copying files to my Web App’s wwwroot?" /><published>2019-02-20T00:00:00+00:00</published><updated>2019-02-20T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/02/why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/02/why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/">&lt;p&gt;&lt;img src=&quot;/images/2019-2-20-why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/header.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I was recently working with a collegue to deploy a Sitecore app to Azure via Pipelines. The release was running successfully, but the deployed files didn’t seem to be overlaying the required, pre-loaded Sitecore files. When we viewed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/site/wwwroot&lt;/code&gt; from Kudu, we were seeing only the files from the build artifacts; when we viewed the same directory from FTP, we were seeing only the Sitecore files. What gives?&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;the-cause-azure-app-service-deploy-task-version&quot;&gt;The cause: Azure App Service Deploy task version&lt;/h2&gt;
&lt;p&gt;Sometime over the past few months, the Azure App Service Deploy release task versioned to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.*&lt;/code&gt;. In that release, the Microsoft team created an auto-detect feature that tries to guess the best method for code deployment to your Web App. In our case, it chose the new preferred method called &lt;em&gt;Run From Package&lt;/em&gt;, which has a few quirks.&lt;/p&gt;

&lt;h2 id=&quot;whats-new-in-version-4&quot;&gt;What’s new in version &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.*&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;These are the new features in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.*&lt;/code&gt; per the Azure DevOps UI at the time of writing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Supports Zip Deploy, Run From Package, War Deploy&lt;/li&gt;
  &lt;li&gt;Supports App Service Environments&lt;/li&gt;
  &lt;li&gt;Improved UI for discovering different App service types supported by the task&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/AzureRmWebAppDeploymentV4/README.md&quot;&gt;Click here  for more information.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most relevant for us is the &lt;em&gt;Run From Package&lt;/em&gt; feature.&lt;/p&gt;

&lt;h2 id=&quot;how-does-that-work&quot;&gt;How does that work?&lt;/h2&gt;
&lt;p&gt;When the release task deploys using &lt;em&gt;Run From Package&lt;/em&gt;, it does a few things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Zips build artifacts and uploads to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/SitePackages/&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Creates a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/SitePackages/packagename.txt&lt;/code&gt; file whose contents point to the deployed zip filename.&lt;/li&gt;
  &lt;li&gt;Sets a new Application Setting to the app of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEBSITE_RUN_FROM_PACKAGE=1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The effect of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEBSITE_RUN_FROM_PACKAGE&lt;/code&gt; setting is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/site/wwwroot/&lt;/code&gt; directory now vitually points to the deployed zip file, not to the actual underlying file system. Try it: download the package zip from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/SitePackages/&lt;/code&gt; and compare contents with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/site/wwwroot/&lt;/code&gt; in Kudu. If you extract FTP credentials from the publish profile and access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/site/wwwroot/&lt;/code&gt;, there is a completely different site of files. Here’s what I’m seeing from a fresh .NET Core MVC deployment:&lt;/p&gt;

&lt;h3 id=&quot;kudu&quot;&gt;Kudu&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/2019-2-20-why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/kudu-contents.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;ftp&quot;&gt;FTP&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/2019-2-20-why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/ftp-contents.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;/h2&gt;
&lt;p&gt;When Microsoft updated the release task, they made a major change to the default behavior of the task and hid the option under the &lt;em&gt;Additional Deployment Options&lt;/em&gt; section.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2019-2-20-why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/deployment-options.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When the &lt;em&gt;Select deployment method&lt;/em&gt; option is not checked, the task appears to prefer the &lt;em&gt;Run From Package&lt;/em&gt; option. Since I want to overlay my deployment files over existing files, the solution for us was to select the option and choose &lt;em&gt;Web Deploy&lt;/em&gt; as our deployment method.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2019-2-20-why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/web-deploy.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Web Deploy&lt;/em&gt; matches the previous behavior of the release task in that it overlays my build artifacts without removing any of the destination files:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2019-2-20-why-isnt-azure-app-service-deploy-copying-files-to-my-web-apps-wwwroot/new-ftp-contents.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I also noted that when I switched the deployment method to &lt;em&gt;Web Deploy&lt;/em&gt;, the release task automatically set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEBSITE_RUN_FROM_PACKAGE&lt;/code&gt; setting to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, which disabled the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/site/wwwroot/&lt;/code&gt; mismatch we observed.&lt;/p&gt;</content><author><name></name></author><category term="azure" /><category term="azure-devops" /><category term="pipelines" /><summary type="html">I was recently working with a collegue to deploy a Sitecore app to Azure via Pipelines. The release was running successfully, but the deployed files didn’t seem to be overlaying the required, pre-loaded Sitecore files. When we viewed /site/wwwroot from Kudu, we were seeing only the files from the build artifacts; when we viewed the same directory from FTP, we were seeing only the Sitecore files. What gives?</summary></entry><entry><title type="html">Accessing Azure Artifacts from a docker container in a Pipelines build</title><link href="https://www.brandonbarnett.io/blog/2019/01/accessing-azure-artifacts-from-a-docker-container-in-a-pipelines-build/" rel="alternate" type="text/html" title="Accessing Azure Artifacts from a docker container in a Pipelines build" /><published>2019-01-17T00:00:00+00:00</published><updated>2019-01-17T00:00:00+00:00</updated><id>https://www.brandonbarnett.io/blog/2019/01/accessing-azure-artifacts-from-a-docker-container-in-a-pipelines-build</id><content type="html" xml:base="https://www.brandonbarnett.io/blog/2019/01/accessing-azure-artifacts-from-a-docker-container-in-a-pipelines-build/">&lt;p&gt;&lt;img src=&quot;/images/2019-1-17-accessing-azure-artifacts-from-a-docker-container-in-a-pipelines-build/header.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In my &lt;a href=&quot;/blog/2019/01/2019-1-16-using-azure-pipelines-to-publish-nuget-packages-to-a-private-artifacts-feed/&quot;&gt;previous post&lt;/a&gt; I talked about how our team is publishing NuGet packages using Azure Pipelines to a DevOps Artifacts feed. Now it’s time to consume those packages. There are plenty of examples on how to connect to a feed in Build, but our case is a bit different because our applications are containerized. The purpose of this post is to share specifically how we authorize access to Artifacts from a docker build context in an Azure DevOps Build.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Please see &lt;a href=&quot;https://gist.github.com/brbarnett/c55c80dd63b89465cfd9bc6b74c0548e&quot;&gt;this Gist&lt;/a&gt; for full code references.&lt;/p&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;
&lt;p&gt;The purpose of using Azure Artifacts is to avoid a public package manager because the team is writing IP into shared libraries. It should then come as no surprise that there are a few additional steps required to ensure that your docker build context has appropriate access to Azure DevOps.&lt;/p&gt;

&lt;p&gt;The docker build context is isolated from Azure DevOps, meaning that it should be considered a sandboxed build that doesn’t share environment variables and access that typical Build tasks would. The trick to authorizing a docker build is to use a Personal Access Token as a rotatable key that tells Azure DevOps that it is authorized to pull packages from Artifacts. Start by creating a PAT: click your avatar in the upper right of DevOps then Security in the dropdown. &lt;strong&gt;Make sure it has access to Packaging.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;pipelines-variable-group&quot;&gt;Pipelines variable group&lt;/h2&gt;
&lt;p&gt;The next step is to create a group of variables that you can share between all Build definitions. I created an Artifacts group and added an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;artifactsAccessToken&lt;/code&gt; (this is your Private Access Token) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;artifactsEndpoint&lt;/code&gt; which I got from clicking &lt;em&gt;Connect to Feed&lt;/em&gt; from my Artifacts feed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2019-1-17-accessing-azure-artifacts-from-a-docker-container-in-a-pipelines-build/variable-group.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;ci-and-cd-builds&quot;&gt;CI and CD builds&lt;/h2&gt;
&lt;p&gt;Go ahead and create your CI and CD builds and feel free to use my files as a template. Note that I am specifically passing in the variables I created in the variable group above using the following method:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;...

variables:
- group: Artifacts

...

steps:
- task: Docker@1
  displayName: 'Build an image'
  inputs:
    ...
    arguments: '--build-arg ARTIFACTS_ENDPOINT=$(artifactsEndpoint) --build-arg ACCESS_TOKEN=$(artifactsAccessToken)'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This ensures that the variables get mapped to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; ARGS that we also need to define.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important: once you create the build in DevOps, you need to click through &lt;em&gt;Variables&lt;/em&gt; &amp;gt; &lt;em&gt;Variable groups&lt;/em&gt; and click &lt;em&gt;Link variable group&lt;/em&gt;. This is a security feature and is a required step.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2019-1-17-accessing-azure-artifacts-from-a-docker-container-in-a-pipelines-build/link-variable-group.jpg&quot; alt=&quot;_config.yml&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;dockerfile&quot;&gt;Dockerfile&lt;/h2&gt;
&lt;p&gt;Now that we have builds set up, create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; that defines how your app is build and run. To use the variables we passed in via Build above, create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACCESS_TOKEN&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARTIFACTS_ENDPOINT&lt;/code&gt; ARGS to accept them. The key changes from a typical &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; is that you need to install the &lt;a href=&quot;https://github.com/Microsoft/artifacts-credprovider&quot;&gt;Azure Artifacts Credential Provider&lt;/a&gt; and then set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VSS_NUGET_EXTERNAL_FEED_ENDPOINTS&lt;/code&gt; environment variables to let it do its job. Also, alter your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet restore&lt;/code&gt; task to use the new feed endpoint.&lt;/p&gt;

&lt;p&gt;Now run through the entire process and make sure everything works correctly. If so, you should have a new docker container image ready for deployment! Please reach out if you have any questions or a different approach.&lt;/p&gt;</content><author><name></name></author><category term="azure" /><category term="azure-devops" /><category term="pipelines" /><category term="nuget" /><category term="artifacts" /><category term="docker" /><summary type="html">In my previous post I talked about how our team is publishing NuGet packages using Azure Pipelines to a DevOps Artifacts feed. Now it’s time to consume those packages. There are plenty of examples on how to connect to a feed in Build, but our case is a bit different because our applications are containerized. The purpose of this post is to share specifically how we authorize access to Artifacts from a docker build context in an Azure DevOps Build.</summary></entry></feed>