{"id":3212,"date":"2022-04-25T12:05:19","date_gmt":"2022-04-25T12:05:19","guid":{"rendered":"https:\/\/exceedthecloud.com\/?p=3212"},"modified":"2022-04-25T13:29:51","modified_gmt":"2022-04-25T13:29:51","slug":"configuring-pipelines-as-code-with-yaml","status":"publish","type":"post","link":"https:\/\/exceedthecloud.com\/?p=3212","title":{"rendered":"Configuring Pipelines as Code with YAML"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p>Many teams prefer to define their build and release pipelines using YAML. This allows them to access the same pipeline features as those using the visual designer, but with a markup file that can be managed like any other source file. YAML build definitions can be added to a project by simply adding the corresponding files to the root of the repository. Azure DevOps also provides default templates for popular project types, as well as a YAML designer to simplify the process of defining build and release tasks.<\/p>\n\n\n\n<p>After you complete this lab, you will be able to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>configure CI\/CD pipelines as code with YAML in Azure DevOps<\/li><\/ul>\n\n\n\n<p><strong>Review applications required for this lab<\/strong><\/p>\n\n\n\n<p>Identify the applications that you\u2019ll use in this lab:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Microsoft Edge<\/li><\/ul>\n\n\n\n<p><strong>Set up an Azure DevOps organization.<\/strong><\/p>\n\n\n\n<p>If you don\u2019t already have an Azure DevOps organization that you can use for this lab, create one by following the instructions available at\u00a0<a href=\"https:\/\/exceedthecloud.com\/?p=2937\" target=\"_blank\" rel=\"noreferrer noopener\">Create an organization or project collection<\/a>.<\/p>\n\n\n\n<p><strong>Prepare an Azure subscription<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Identify an existing Azure subscription or create a new one.<\/li><li>Verify that you have a Microsoft account or an Azure AD account with the Owner role in the Azure subscription and the Global Administrator role in the Azure AD tenant associated with the Azure subscription. For details, refer to\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/role-based-access-control\/role-assignments-list-portal\" target=\"_blank\" rel=\"noreferrer noopener\">List Azure role assignments using the Azure portal<\/a>\u00a0and\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/roles\/manage-roles-portal#view-my-roles\" target=\"_blank\" rel=\"noreferrer noopener\">View and assign administrator roles in Azure Active Directory<\/a>.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Lab 0: Configure the lab prerequisites<\/strong><\/p>\n\n\n\n<p>In this Lab, you will set up the prerequisites for the lab, which consist of the preconfigured Parts Unlimited team project based on an Azure DevOps Demo Generator template and Azure resources, including an Azure web app and an Azure SQL database.<\/p>\n\n\n\n<p><strong>Task 1: Configure the team project<\/strong><\/p>\n\n\n\n<p>In this task, you will use Azure DevOps Demo Generator to generate a new project based on the&nbsp;<strong>PartsUnlimited-YAML<\/strong>&nbsp;template.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On your lab computer, start a web browser and navigate to\u00a0<a href=\"https:\/\/azuredevopsdemogenerator.azurewebsites.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">Azure DevOps Demo Generator<\/a>. This utility site will automate the process of creating a new Azure DevOps project within your account that is prepopulated with content (work items, repos, etc.) required for the lab.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: For more information on the site, see\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/demo-gen\" target=\"_blank\" rel=\"noreferrer noopener\">What is the Azure DevOps Services Demo Generator?<\/a>.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>Click\u00a0<strong>Sign in<\/strong>\u00a0and sign in using the Microsoft account associated with your Azure DevOps subscription.<\/li><li>If required, on the\u00a0<strong>Azure DevOps Demo Generator<\/strong>\u00a0page, click\u00a0<strong>Accept<\/strong>\u00a0to accept the permission requests for accessing your Azure DevOps subscription.<\/li><li>On the\u00a0<strong>Create New Project<\/strong>\u00a0page, in the\u00a0<strong>New Project Name<\/strong>\u00a0textbox, type\u00a0<strong>Configuring Pipelines as Code with YAML<\/strong>, in the\u00a0<strong>Select organization<\/strong>\u00a0dropdown list, select your Azure DevOps organization, and then click\u00a0<strong>Choose template<\/strong>.<\/li><li>In the list of templates, in the toolbar, click\u00a0<strong>General<\/strong>, select the\u00a0<strong>PartsUnlimited-YAML<\/strong>\u00a0template and click\u00a0<strong>Select Template<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"287\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture1-8.png\" alt=\"\" class=\"wp-image-3213\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture1-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture1-8-300x138.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Back on the\u00a0<strong>Create New Project<\/strong>\u00a0page, click\u00a0<strong>Create Project<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"324\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture2-8.png\" alt=\"\" class=\"wp-image-3214\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture2-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture2-8-300x156.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: Wait for the process to complete. This should take about 2 minutes. In case the process fails, navigate to your DevOps organization, delete the project, and try again.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the\u00a0<strong>Create New Project<\/strong>\u00a0page, click\u00a0<strong>Navigate to project<\/strong>.<\/li><\/ul>\n\n\n\n<p>Task 2: Create Azure resources<\/p>\n\n\n\n<p>In this task, you will create an Azure web app and an Azure SQL database by using the Azure portal.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>From the lab computer, start a web browser, navigate to the\u00a0<a href=\"https:\/\/portal.azure.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Azure Portal<\/strong><\/a>, and sign in with the user account that has the Owner role in the Azure subscription you will be using in this lab and has the role of the Global Administrator in the Azure AD tenant associated with this subscription.<\/li><li>In the Azure portal, in the toolbar, click the\u00a0<strong>Cloud Shell<\/strong>\u00a0icon located directly to the right of the search text box.<\/li><li>If prompted to select either\u00a0<strong>Bash<\/strong>\u00a0or\u00a0<strong>PowerShell<\/strong>, select\u00a0<strong>Bash<\/strong>.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: If this is the first time you are starting&nbsp;<strong>Cloud Shell<\/strong>&nbsp;and you are presented with the&nbsp;<strong>You have no storage mounted<\/strong>&nbsp;message, select the subscription you are using in this lab, and select&nbsp;<strong>Create storage<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"4\"><li>From the\u00a0<strong>Bash<\/strong>\u00a0prompt, in the\u00a0<strong>Cloud Shell<\/strong>\u00a0pane, run the following command to create a resource group (replace the\u00a0&lt;region>\u00a0placeholder with the name of the Azure region closest to you such as \u2018eastus\u2019).<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LOCATION='eastus'<\/code><\/pre>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RESOURCEGROUPNAME='exceedm11l01-RG'\naz group create --name $RESOURCEGROUPNAME --location $LOCATION\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"283\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture3-8.png\" alt=\"\" class=\"wp-image-3215\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture3-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture3-8-300x136.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>To create a Windows App service plan by running the following command:<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SERVICEPLANNAME='exceedl11a-sp1'\naz appservice plan create --resource-group $RESOURCEGROUPNAME --name $SERVICEPLANNAME --sku B3\n<\/code><\/pre>\n\n\n\n<p><strong>Note<\/strong>: If the\u00a0az appservice plan create\u00a0command fails with an error message starting with\u00a0ModuleNotFoundError: No module named &#8216;vsts_cd_manager&#8217;, then run the following commands and then re-run the failed command.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"304\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture4-8.png\" alt=\"\" class=\"wp-image-3216\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture4-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture4-8-300x146.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>az extension remove -n appservice-kube\naz extension add --yes --source \"https:\/\/aka.ms\/appsvc\/appservice_kube-latest-py2.py3-none-any.whl\"\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"110\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture5-8.png\" alt=\"\" class=\"wp-image-3217\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture5-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture5-8-300x53.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Create a web app with a unique name.<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WEBAPPNAME=partsunlimited$RANDOM$RANDOM\naz webapp create --resource-group $RESOURCEGROUPNAME --plan $SERVICEPLANNAME --name $WEBAPPNAME\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Next, create an Azure SQL Server.<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>USERNAME=\"Student\"\nSQLSERVERPASSWORD=\"Pa55w.rd1234\"\nSERVERNAME=\"partsunlimitedserver$RANDOM\"\n\naz sql server create --name $SERVERNAME --resource-group $RESOURCEGROUPNAME \\\n--location $LOCATION --admin-user $USERNAME --admin-password $SQLSERVERPASSWORD\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"189\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture6-8.png\" alt=\"\" class=\"wp-image-3218\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture6-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture6-8-300x91.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>The web app needs to be able to access the SQL server, so we need to allow access to Azure resources in the SQL Server firewall rules.<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>STARTIP=\"0.0.0.0\"\nENDIP=\"0.0.0.0\"\naz sql server firewall-rule create --server $SERVERNAME --resource-group $RESOURCEGROUPNAME \\\n--name AllowAzureResources --start-ip-address $STARTIP --end-ip-address $ENDIP\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"166\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture7-8.png\" alt=\"\" class=\"wp-image-3219\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture7-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture7-8-300x80.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Now create a database within that server.<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>az sql db create --server $SERVERNAME --resource-group $RESOURCEGROUPNAME --name PartsUnlimited --service-objective S0\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"239\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture8-8.png\" alt=\"\" class=\"wp-image-3220\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture8-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture8-8-300x115.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>The web app you created needs the database connection string in its configuration, so run the following commands to prepare and add it to the app settings of the web app.<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CONNSTRING=$(az sql db show-connection-string --name PartsUnlimited --server $SERVERNAME \\\n--client ado.net --output tsv)\n\nCONNSTRING=${CONNSTRING\/\/&lt;username>\/$USERNAME}\nCONNSTRING=${CONNSTRING\/\/&lt;password>\/$SQLSERVERPASSWORD}\n\naz webapp config connection-string set --name $WEBAPPNAME --resource-group $RESOURCEGROUPNAME \\\n-t SQLAzure --settings \"DefaultConnectionString=$CONNSTRING\" \n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"178\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture9-8.png\" alt=\"\" class=\"wp-image-3221\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture9-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture9-8-300x86.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Lab 1: Configure CI\/CD Pipelines as Code with YAML in Azure DevOps<\/strong><\/p>\n\n\n\n<p>In this Lab, you will configure CI\/CD Pipelines as code with YAML in Azure DevOps.<\/p>\n\n\n\n<p><strong>Task 1: Delete the existing pipeline<\/strong><\/p>\n\n\n\n<p>In this task, you will delete the existing pipeline.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the lab computer, switch to the browser window displaying the\u00a0<strong>Configuring Pipelines as Code with YAML<\/strong>\u00a0project in the Azure DevOps portal and, in the vertical navigational pane, select the\u00a0<strong>Pipelines<\/strong>.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: Before configuring YAML pipelines, you will disable the existing build pipeline.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>On the\u00a0<strong>Pipelines<\/strong>\u00a0pane, select the\u00a0<strong>PartsUnlimited<\/strong>\u00a0entry.<\/li><li>In the upper right corner of the\u00a0<strong>PartsUnlimited<\/strong>\u00a0blade, click the vertical ellipsis symbol and, in the drop-down menu, select\u00a0<strong>Delete<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"291\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture10-8.png\" alt=\"\" class=\"wp-image-3222\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture10-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture10-8-300x140.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Write\u00a0<strong>PartsUnlimited<\/strong>\u00a0and click\u00a0<strong>Delete<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"261\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture11-8.png\" alt=\"\" class=\"wp-image-3223\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture11-8.png 470w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture11-8-300x167.png 300w\" sizes=\"auto, (max-width: 470px) 100vw, 470px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In the vertical navigational pane, select the\u00a0<strong>Repos > Files<\/strong>. Make sure you are in the\u00a0<strong>master<\/strong>\u00a0branch (dropdown on top of\u00a0<strong>Files<\/strong>\u00a0window), on the\u00a0<strong>azure-pipelines.yml<\/strong>\u00a0file, click the vertical ellipsis symbol and, in the drop-down menu, select\u00a0<strong>Delete<\/strong>. Commit the change on the master branch by clicking on\u00a0<strong>Commit<\/strong>\u00a0(leaving default options).<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"299\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture12-8.png\" alt=\"\" class=\"wp-image-3224\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture12-8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture12-8-300x144.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"471\" height=\"837\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture13-7.png\" alt=\"\" class=\"wp-image-3225\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture13-7.png 471w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture13-7-169x300.png 169w\" sizes=\"auto, (max-width: 471px) 100vw, 471px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Task 2: Add a YAML build definition<\/strong><\/p>\n\n\n\n<p>In this task, you will add a YAML build definition to the existing project.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Navigate back to the\u00a0<strong>Pipelines<\/strong>\u00a0pane in of the\u00a0<strong>Pipelines<\/strong>\u00a0hub.<\/li><li>In the\u00a0<strong>Create your first Pipeline<\/strong>\u00a0window, click\u00a0<strong>Create pipeline<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"373\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture14-6.png\" alt=\"\" class=\"wp-image-3226\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture14-6.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture14-6-300x179.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Note<\/strong>: We will use the wizard to automatically create the YAML definition based on our project.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the\u00a0<strong>Where is your code?<\/strong>\u00a0pane, click\u00a0<strong>Azure Repos Git (YAML)<\/strong>\u00a0option.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"560\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture15-7.png\" alt=\"\" class=\"wp-image-3227\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture15-7.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture15-7-300x269.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>On the\u00a0<strong>Select a repository<\/strong>\u00a0pane, click\u00a0<strong>PartsUnlimited<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"277\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture16-6.png\" alt=\"\" class=\"wp-image-3228\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture16-6.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture16-6-300x133.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>On the\u00a0<strong>Configure your pipeline<\/strong>\u00a0pane, click **ASP.NET** to use this template as the starting point for your pipeline. This will open the **Review your pipeline YAML** pane.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"688\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture17-6.png\" alt=\"\" class=\"wp-image-3229\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture17-6.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture17-6-272x300.png 272w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Note<\/strong>: The pipeline definition will be saved as a file named\u00a0<strong>azure-pipelines.yml<\/strong>\u00a0in the root of the repository. The file will contain the steps required to build and test a typical ASP.NET solution. You can also customize the build as needed. In this scenario, you will update the **pool** to enforce the use of a VM running Windows 2019.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Make sure\u00a0trigger\u00a0is\u00a0<strong>master<\/strong>.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: Review in Repos if your repository has&nbsp;<strong>master<\/strong>&nbsp;or&nbsp;<strong>main<\/strong>&nbsp;branch, organizations could choose default branch name for new repos:&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/repos\/git\/change-default-branch?view=azure-devops#choosing-a-name\">Change the default branch<\/a>.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>On the\u00a0<strong>Review your pipeline YAML<\/strong>\u00a0pane, in line\u00a0<strong>10<\/strong>, replace\u00a0vmImage: &#8216;windows-latest&#8217;\u00a0with\u00a0vmImage: &#8216;windows-2019&#8217;.<\/li><li>Remove the\u00a0<strong>VSTest@2<\/strong>\u00a0task: &#8220;`yaml<ul><li>task: VSTest@2 inputs: platform: \u2018$(buildPlatform)\u2019 configuration: \u2018$(buildConfiguration)\u2019 &#8220;`<\/li><\/ul><\/li><li>On the\u00a0<strong>Review your pipeline YAML<\/strong>\u00a0pane, click\u00a0<strong>Save and run<\/strong>.<\/li><li>On the\u00a0<strong>Save and run<\/strong>\u00a0pane, accept the default settings and click\u00a0<strong>Save and run<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"840\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture18-6.png\" alt=\"\" class=\"wp-image-3230\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture18-6.png 466w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture18-6-166x300.png 166w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<p>On the pipeline run pane, in the\u00a0<strong>Jobs<\/strong>\u00a0section, click\u00a0<strong>Job<\/strong>\u00a0and monitor its progress and verify that it completes successfully.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"323\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture19-5.png\" alt=\"\" class=\"wp-image-3231\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture19-5.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture19-5-300x155.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Note<\/strong>: Each task from the YAML file is available for review, including any warnings and errors.<\/p>\n\n\n\n<p><strong>Task 3: Add continuous delivery to the YAML definition<\/strong><\/p>\n\n\n\n<p>In this task, you will add continuous delivery to the YAML-based definition of the pipeline you created in the previous task.<\/p>\n\n\n\n<p><strong>Note<\/strong>: Now that the build and test processes are successful, we can now add delivery to the YAML definition.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the pipeline run pane, click the ellipsis symbol in the upper right corner and, in the dropdown menu, click\u00a0<strong>Edit pipeline<\/strong>.<\/li><li>On the pane displaying the content of the\u00a0<strong>azure-pipelines.yaml<\/strong>\u00a0file, in line\u00a0<strong>8<\/strong>, following the\u00a0trigger\u00a0section, add the following content to define the\u00a0<strong>Build<\/strong>\u00a0stage in the YAML pipeline.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: You can define whatever stages you need to better organize and track pipeline progress.<\/p>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>stages:\n- stage: Build\n  jobs:\n  - job: Build\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Select the remaining content of the YAML file and press the\u00a0<strong>Tab<\/strong>\u00a0key twice to indent it four spaces (it should be placed with same identation as\u00a0job: Build).<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: This way, everything starting with the&nbsp;pool&nbsp;section becomes part of the&nbsp;job: Build.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>At the bottom of the file, add the configuration below to define the second stage.<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- stage: Deploy\n  jobs:\n  - job: Deploy\n    pool:\n      vmImage: 'windows-2019'\n    steps:\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Set the cursor on a new line at the end of the YAML definition.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: This will be the location where new tasks are added.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>In the list of tasks on the right side of the code pane, search for and select the\u00a0<strong>Azure App Service Deploy<\/strong>\u00a0task.<\/li><li>In the\u00a0<strong>Azure App Service deploy<\/strong>\u00a0pane, specify the following settings and click\u00a0<strong>Add<\/strong>:<ul><li>in the\u00a0<strong>Azure subscription<\/strong>\u00a0drop-down list, select the Azure subscription into which you deployed the Azure resources earlier in the lab, click\u00a0<strong>Authorize<\/strong>, and, when prompted, authenticate by using the same user account you used during the Azure resource deployment.<\/li><li>in the\u00a0<strong>App Service name<\/strong>\u00a0dropdown list, select the name of the web app you deployed earlier in the lab.<\/li><li>in the\u00a0<strong>Package or folder<\/strong>\u00a0text box, type\u00a0$(System.ArtifactsDirectory)\/drop\/*.zip.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: This will automatically add the deployment task to the YAML pipeline definition.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"4\"><li>With the added task still selected in the editor, press the\u00a0<strong>Tab<\/strong>\u00a0key twice to indent it four spaces, so that it listed as a child of the\u00a0<strong>steps<\/strong>\u00a0task.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: The&nbsp;<strong>packageForLinux<\/strong>&nbsp;parameter is misleading in the context of this lab, but it is valid for Windows or Linux.<\/p>\n\n\n\n<p><strong>Note<\/strong>: By default, these two stages run independently. As a result, the build output from the first stage might not be available to the second stage without additional changes. To implement these changes, we will use one task to publish the build output at the end of the build stage and another to download it in the beginning of the deploy stage.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"5\"><li>Place the cursor on a blank line at the end of the build stage to add another task. (right below\u00a0task: VSBuild@1\u00a0)<\/li><li>On the\u00a0<strong>Tasks<\/strong>\u00a0pane, search for and select the\u00a0<strong>Publish build artifacts<\/strong>\u00a0task.<\/li><li>On the\u00a0<strong>Publish build artifacts<\/strong>\u00a0pane, accept the default settings and click\u00a0<strong>Add<\/strong>.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: This will publish the build artifacts to a location that will be downloadable under the alias&nbsp;<strong>drop<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"8\"><li>With the added task still selected in the editor, press the\u00a0<strong>Tab<\/strong>\u00a0key twice to indent it four spaces (or press the\u00a0<strong>Tab<\/strong>\u00a0until task is indented as the ones above).<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: You may also want to add an empty line before and after to make it easier to read.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"9\"><li>Place the cursor on the first line under the\u00a0<strong>steps<\/strong>\u00a0node of the\u00a0<strong>deploy<\/strong>\u00a0stage.<\/li><li>On the\u00a0<strong>Tasks<\/strong>\u00a0pane, search for and select the\u00a0<strong>Download build artifacts<\/strong>\u00a0task.<\/li><li>Click\u00a0<strong>Add<\/strong>.<\/li><li>With the added task still selected in the editor, press the\u00a0<strong>Tab<\/strong>\u00a0key twice to indent it four spaces.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: Here as well you may also want to add an empty line before and after to make it easier to read.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"13\"><li>Add a property to the download task specifying the\u00a0artifactName\u00a0of\u00a0drop\u00a0(make sure to match the spacing):<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>artifactName: 'drop'<\/code><\/pre>\n\n\n\n<p>Click\u00a0<strong>Save<\/strong>, on the\u00a0<strong>Save<\/strong>\u00a0pane, click\u00a0<strong>Save<\/strong>\u00a0again to commit the change directly into the master branch.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"465\" height=\"834\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture20-4.png\" alt=\"\" class=\"wp-image-3232\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture20-4.png 465w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture20-4-167x300.png 167w\" sizes=\"auto, (max-width: 465px) 100vw, 465px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Note<\/strong>: This will automatically trigger a new build.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>The pipeline will look similar to this example (<strong>Reference your own subscription and webapp on last task<\/strong>):<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: The indentation needs to be correct to make it work, copy and pasting may modify it.<\/p>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>trigger:\n- master\n\nstages:\n- stage: Build\n  jobs:\n  - job: Build\n    pool:\n        vmImage: 'windows-2019'\n\n    variables:\n        solution: '**\/*.sln'\n        buildPlatform: 'Any CPU'\n        buildConfiguration: 'Release'\n\n    steps:\n    - task: NuGetToolInstaller@1\n\n    - task: NuGetCommand@2\n      inputs:\n        restoreSolution: '$(solution)'\n\n    - task: VSBuild@1\n      inputs:\n        solution: '$(solution)'\n        msbuildArgs: '\/p:DeployOnBuild=true \/p:WebPublishMethod=Package \/p:PackageAsSingleFile=true \/p:SkipInvalidConfigurations=true \/p:PackageLocation=\"$(build.artifactStagingDirectory)\"'\n        platform: '$(buildPlatform)'\n        configuration: '$(buildConfiguration)'\n\n    - task: PublishBuildArtifacts@1\n      inputs:\n        PathtoPublish: '$(Build.ArtifactStagingDirectory)'\n        ArtifactName: 'drop'\n        publishLocation: 'Container'\n\n- stage: Deploy\n  jobs:\n  - job: Deploy\n    pool:\n        vmImage: 'windows-2019'\n    steps:\n    - task: DownloadBuildArtifacts@0\n      inputs:\n        buildType: 'current'\n        downloadType: 'single'\n        downloadPath: '$(System.ArtifactsDirectory)'\n        artifactName: 'drop'\n    - task: AzureRmWebAppDeployment@4\n      inputs:\n        ConnectionType: 'AzureRM'\n        azureSubscription: 'YOUR-AZURE-SUBSCRIPTION'\n        appType: 'webApp'\n        WebAppName: 'YOUR-WEBAPP-NAME'\n        packageForLinux: '$(System.ArtifactsDirectory)\/drop\/*.zip'\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the web browser window displaying the Azure DevOps portal, in the vertical navigational pane, select the\u00a0<strong>Pipelines<\/strong>.<\/li><li>On the\u00a0<strong>Pipelines<\/strong>\u00a0pane, click the entry representing the newly configured pipeline.<\/li><li>Click on the most recent run (automatically started).<\/li><li>On the\u00a0<strong>Summary<\/strong>\u00a0pane, monitor the progress of the pipeline run.<\/li><li>If you notice a message stating that\u00a0<em>This pipeline needs permissions to access a resource before this run can continue to Deploy<\/em>, click\u00a0<strong>View<\/strong>, in the\u00a0<strong>Waiting for review<\/strong>\u00a0dialog box, click\u00a0<strong>Permit<\/strong>, and, in the\u00a0<strong>Permit access?<\/strong>\u00a0pane, click\u00a0<strong>Permit<\/strong>\u00a0again.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"406\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture21-4.png\" alt=\"\" class=\"wp-image-3233\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture21-4.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/Picture21-4-300x195.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>At the bottom of the\u00a0<strong>Summary<\/strong>\u00a0pane, click the\u00a0<strong>Deploy<\/strong>\u00a0stage to view details of the deployment.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: Once the task completes, your app will be deployed to an Azure web app.<\/p>\n\n\n\n<p><strong>Task 4: Review the deployed site<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Switch back to web browser window displaying the Azure portal and navigate to the blade displaying the properties of the Azure web app.<\/li><li>On the Azure web app blade, click\u00a0<strong>Overview<\/strong>\u00a0and, on the overview blade, click\u00a0<strong>Browse<\/strong>\u00a0to open your site in a new web browser tab.<\/li><li>Verify that the deployed site loads as expected in the new browser tab.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Review<\/strong><\/p>\n\n\n\n<p>In this lab, you configured CI\/CD pipelines as code with YAML in Azure DevOps.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><mark class=\"kt-highlight\">Reminder: Don\u2019t forget to delete or shutdown all unused Azure resources after your labs for cost saving<\/mark><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many teams prefer to define their build and release pipelines using YAML. This allows them to access the same pipeline features as those using the visual designer, but with a markup file that can be managed like any other source &hellip; <a href=\"https:\/\/exceedthecloud.com\/?p=3212\">Continued<\/a><\/p>\n","protected":false},"author":1,"featured_media":3236,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"kt_blocks_editor_width":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[16,4],"tags":[8,109,105,107,108],"class_list":["post-3212","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-practical-labs-series","tag-azure","tag-ci-cd","tag-devops","tag-pipelines","tag-yaml"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/04\/istockphoto-1329089418-612x612-1.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts\/3212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3212"}],"version-history":[{"count":3,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts\/3212\/revisions"}],"predecessor-version":[{"id":3237,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts\/3212\/revisions\/3237"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/media\/3236"}],"wp:attachment":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}