利用 Azure DevOps Service 部署 ASP .NET Core:整合自動化 CI/CD — Azure Windows Server + IIS 篇

Where
18 min readApr 22, 2019

--

不管現在坐在電腦前的你,是一位工程師、PM、學生還是在床上發懶的一團肉,只要是一位極懶惰如作者的人,每天殷殷期盼的就是能少做一點就少做一點,多一點在床上耍廢的時間;因此,學習如何將整個開發部署的流程變成自動化,就是身為一個懶人畢生的宗旨了!

首先,你需要先有一個可以正常運作的 ASP .NET Core 的網頁,如果沒有也可以從底下的連結將範本 clone 來作為練習使用。

https://huier-teamservice@dev.azure.com/huier-teamservice/OpenRepository/_git/OpenRepository

Azure Virtual Machine Service

再來,到 Azure 上開啟這次部署所要使用的虛擬機器。這部份開啟的方式本篇不額外做介紹,這次的部署我開了兩台虛擬機器,使用 Azure 上所提供的 Windows Server 2016 Datacenter 的 OS 系統,並選用 Standard DS1 v2 (1 vcpus, 3.5 GB memory)的 Size,地點在 Southeast Asia。這邊提醒,設定Networking 的地方,要記得把 HTTP / HTTPs 的 Port 打開(預設是沒有的),才能透過瀏覽器瀏覽網頁喔!

Azure DevOps Service 計費

進入到 Azure DevOps Service,你可以選擇開啟一個新的專案,或使用既有的。如果還沒有帳號的朋友,就立馬手刀註冊一個吧!目前 Azure DevOps Service 提供一個組織內五人以下免費的優惠,可擁有私人的Repository 以及使用私有的 Agent 來做部署的功能。太佛啦~

Azure DevOps 的定價,2019/4/22。

目前 Azure DevOps Service 僅提供英文版的介面,如果需要中文的話可以使用 Chrome 然後右鍵翻譯成中文,搞定!

Azure DevOps Service Build Pipeline

在部署到虛擬機器上前,需要先將程式碼進行打包產生部署到虛擬機器上所需的檔案。點選 Pipeline > Build 後選擇 New Pipeline 可以新增一條新的建置管線。

接著,選擇要使用 Repository 的來源,可以選擇目前這個 Project 的Repository、在同一組織底下的其他 Project、GitHub、Subversion、或其他使用 Git 的程式碼版控庫。

另外,你也可以在每次驅動 Build Pipeline 時選擇不同支線的程式碼進行建置。

再來,選擇建置的 Template。Azure DevOps Service 除了 Microsoft 自家的C# 外,同時亦支援其他語言像是 Java、JavaScript、PHP、Python、Go、Ruby 等,並提供多元的 Template 來滿足你的建置需求,若是要建置 Mobile APP,同時也提供 Android、Xcode 等。倘若現有的 Template 還是無法滿足你的特殊需求,也可以選擇 Empty 來打造獨特的建置流程,而今天我使用的是 ASP .NET Core,就先使用官方所提供的 ASP .NET Template 來做。

點下 Apply 就會看到閃亮亮的流程已經幫你設計好啦!٩(ˊᗜˋ*)و

這邊大致的流程是會使用 NuGet 4.4.1 來幫你下載專案所需的套件,之後使用 Visual Studio 的 Build 工具來打包;如果專案裡有 Unit Test 的腳本,會在 Test Assembiles 的這個環節幫你跑測試,這個功能的好處在於,工程師可以在每次上版做 Build 的同時就先跑過測試,以降低之後程式出錯的機率,最後透過 Publish Artifact 來將建置好的程式碼提供給等一下部署時做使用。

另外,可以在 Agent Job 1 選擇你要使用哪種 OS 的 Agent 來做建置,若有設定 Private 的 Agent 也可以在這裡選擇。我這次使用的是由 Microsoft Host 的 Hosted VS2017

從官方的文章中我們可以了解到:

If your pipelines are in Azure Pipelines, then you’ve got a convenient option to build and deploy using a Microsoft-hosted agent. With Microsoft-hosted agents, maintenance and upgrades are taken care of for you. Each time you run a pipeline, you get a fresh virtual machine. The virtual machine is discarded after one use. Like self-hosted agents, Microsoft-hosted agents can run jobs directly on the VM or in a container.

簡單來說,當你採用的是官方 Host 的主機時,在進行建置的當下,會自動幫你在背後啟動一台虛擬機器來處理目前的工作流程,並在作業完成後自動砍掉這台機器。

好啦!通常,這時不太需要做其他的設定,直接爽快地給他點下 Save & queue 這個迷人的按鈕,就會自動幫你開始進行程式碼的建置

可惜,事情通常都沒有這麼容易。而我已先跳下這個坑為大家填平坑坑疤疤的路了。我們先不要衝動地按下按鈕,回來到其中的 Test Assembiles 這個Task。你會看到,預設的 Test Files 會指定在這個路徑:

**\$(BuildConfiguration)\*test*.dll
!**\obj\**

若你是使用自己的專案,就需要自行修改自己建置完以後測試的 dll 檔案路徑,而如果你是使用我所提供的程式碼,因為我的 UnitTest.dll 檔案會在更下一層的目錄中,因此需要多一個 *,將路徑設定成 :

*\$(BuildConfiguration)\**\*UnitTest.dll
!**\obj\**

到這邊,可以安安穩穩地按下 Save & queue 了!

燈燈燈!成功的果實就是如此美好~~

因為在這次的 Build 過程中有跑 Unit Test,所以選擇 Tests 的地方,可以看到已經自動幫我們跑了 Unit Test 的腳本。

如果你想要讓每次有新的程式碼 Commit 上來後自動 Trigger Build Pipeline 的啟動,可以在剛剛設計 Task 頁面中的 Triggers 來啟動 Enable Continuous Integration,並且可以選擇建置 Master 或是其他的 Brach。

在做部署動作前,因為使用的是 Azure 上虛擬機器的 Windows Server 環境,因此需要先在虛擬機器上安裝好 IIS(Internet Information Server) 及要 跑 ASP .NET Core 的環境,這邊你可以手動連線進去做設定,也可以透過 Pipeline 來做自動化的環境設定。

Azure DevOps Deployment Groups

這次我會使用 Azure DevOps Service 上的 Azure Resource Group Deployment 和 PowerShell Task 來做自動化的環境設定,在這之前,會需要使用到 Deployment Groups 這個功能,來將 Azure DevOps Service 的代理程式安裝到要部署的虛擬機器當中。

Pipeline > Deployment Groups > New 可以新增一個 Deployment Groups,然後就會看到以下畫面。

一般來說,你可以透過這個指令,直接連線進虛擬機器做安裝,而我們今天會使用 Pipeline 裡面的 Task 來做安裝

Azure DevOps Release Pipeline

選擇 Pipeline > Release > New Release Pipeline 來新增一條新的部署管線,然後使用 Empty Job 後點選 Stage1 來新增部署的 Task。

Agent Job 旁邊的 + 點選可以新增 Task,搜尋 Azure Resource Group Deployment 加入。

填入你要使用的 Azure Subscription、Resource Group 後,在 Action 的地方選擇 Configure virtual machine deployment options,這個動作可以幫你選定的 Resource Group 內的資源做一些設定的更新。

補充:

可以透過 Azure 的 ARM (Azure Resource Management) 的服務搭配上述 Azure Resource Group Deployment 中 Action 裡的 Create or update resource group來達到在 Azure 上開服務的流程自動化。

基本設定好後,再來要選擇將這些虛擬機器加到哪個 Deployment Group,在 Advanced deployment options for virtual machines 設定中分別做以下設定:

Team Project 選擇目前的這個 Project,Deployment Group 選擇剛剛建立好的 Deployment Group

為了要讓 Azure Pipelines 能取得組織的使用權限,因此在設定 Azure Pipelines / TFS service connection 這裡前,需要先去取得組織的 PAT (Personal Access Token)。

右上角的頭像點下去,選擇 Security

點選 New Token,設定名稱,而這邊你可以選擇要給予這個 Token 全部組織或單一組織多大的權限,這裡我是先選擇目前專案所在的這個組織和 Full Access 的權限。按下 Create 後就會出現 Token,這邊 Token 關掉以後就拿不到了

小提醒,若為正式環境建議不要使用 Full Access 的權限,依本篇的需求,可以設定 Deployment Groups 中的 Read & manage 即可。

取得了 PAT 後,回到剛剛 Release 設定 Azure Resource Group Deployment 的畫面。在 Azure Pipelines/TFS service connection 這個欄位旁邊的 New 來新增組織的連線設定,Connection URL 填入組織的網址,Personal Access Token 填入剛剛拿到的 Token。

點選 Stage 1 旁邊的符號新增一個 Add a deployment group job,用來進行接下來要對 Deployment Group 中的虛擬機器要設定環境的 Task。

在 Deployment Group 中你可以對特定的機器添加 Tag,如 Dev、UAT、Test等,然後在 Deploy Group Job 中的 Required tags 欄位來選擇擁有這些 Tag的機器做部署。

接著,在 Deployment Group Job 底下新增兩個 PowerShell 的 Task,一個用來在虛擬機器上安裝 IIS,一個用來安裝 .NET Core Runtime & Hosting Bundle。

參考此份文件,我們可以透過以下的 PowerShell 指令來安裝 IIS,你可以直接將指令寫在 Task 中或儲存成 .ps 的檔案上傳到 Repository 給 Task 讀取。

import-module servermanageradd-windowsfeature Web-Server, Web-WebServer, Web-Security,Web-Filtering,Web-Windows-Auth,Web-Basic-Auth,Web-Common-Http,Web-Http-Errors,Web-Static-Content,Web-Default-Doc,Web-Performance,Web-Stat-Compression,Web-Dyn-Compression,Web-Health,Web-Http-Logging,Web-Log-Libraries,Web-Request-Monitor,Web-Http-Tracing,Web-App-Dev,Web-Net-Ext45,Web-Asp-Net45,Web-WebSockets,Web-AppInit,Web-Mgmt-Tools,Web-Mgmt-Console

Type 的地方選擇 File Path 可以直接選取 PowerShell 腳本來讀取指令,或使用 Inline 直接填入指令。

根據上面的步驟,在第二個 PowerShell Task 填入以下指令來進行安裝 .NET Core Runtime & Hosting Bundle 的動作。

Invoke-WebRequest https://download.visualstudio.microsoft.com/download/pr/c4dcaead-1f81-49af-b824-e6a42b4dbe5a/0d292d75a11666d5e2ebeed4171d27a7/dotnet-hosting-2.2.4-win.exe -outfile $env:temp\DotNetCore.WindowsHosting.exeStart-Process $env:temp\DotNetCore.WindowsHosting.exe -ArgumentList '/quiet' -Wait

若有按照上面的步驟一步一步做的話,你可以看到最後你的 Release Pipeline會呈現這樣。紅色框的部分你可以自行修改名字,以方便後續管理。

Stage Tasks
Pipeline

然後,就可以放心地按下右上角的 Create Release,Release 完成後你可以在 Deployment Group 裡面看到兩台虛擬機器已經上線囉!

透過瀏覽器進入該台主機的位置,因為目前尚未將程式碼部署到主機上,你可以看到網頁現在會呈現 IIS 的歡迎畫面。

好!基本的環境設定好後,我們接著來設定程式碼的部署流程。回到剛剛的Release 頁面,為了不要和環境設定的 Pipeline 混在一起,我會重新再新增一條Pipeline,並選擇 IIS Website Deployment 的 Template。

在 Add an Artifact 的地方,選擇 Build Pipeline 的來源,即方才做打包程式碼動作的那條建置的管線,Default Version 選擇 Latest 最新版本。

Add an Artifact 右上角的地方有一個閃電可以設定啟動 CD 的 Trigger,當有新的 Build 釋出時會直接啟動目前這條 Release Pipeline。這邊的 Trigger 動作僅包含程式碼部署的部分,並未加入前面設定 IIS 和 .NET Core 環境的流程,若要將整體串接需再額外做設定。

同樣進入到 Stage 中來進行 IIS Website 部署的一些設定。在 IIS Deployment 的地方選擇要將程式碼部署到相對應的 Deployment Group 中,在 Required Tags 這邊,同樣的你可以選擇這次的程式碼是否只要部署到有該 Tag 的機器上就好,這邊因為我想同時部署到我 AspNetCoreSample 這個 Deployment Group 裡面的兩台機器上,所以我就先空著不填。

再來,到 IIS Web App Manage 的地方對 IIS 站台部署的設定。將 Create or update app pool 的選項打勾,因我使用的是 ASP .NET Core 2.2 的版本,根據官方 ASP .NET Core 在 Windows IIS 上執行的文件,因為 ASP .NET Core 2.2 會在獨立的 process 中 run 因此不會仰賴於 IIS上的 CLR。

因此,下方 .NET version 的地方選擇 No Managed Code,上面 Name 的地方可以自行命名。

設定完成,點選 Save 然後進行 Release

部署完成後點進去可以看到 Log,可以注意到左邊的欄位它已經自動地幫我們部署到我所選擇的 Deployment Group 中的兩台虛擬機器上。

接著連線到你的網站確認成功

後記

這樣的流程其實比較適合從無到有進行測試 Web 站台的虛擬機器,原則上會包含一些自動化的測試和刪除虛擬機器的流程,但因時間有限,希望未來能有時間再寫一篇教學 (。・_・)ノ

自動化的部分可以使用 ARM Template 或 Azure CLI 的指令自動在 Azure 上建立虛擬機器,再安裝 IIS 和 .NET Core 的相關套件,跑 UI Test ,最後使用 Azure CLI 將整個資源群組做移除,可以將以往在做程式測試時的流程自動化,減少不必要的時間浪費及錯誤率。

雖然這樣的流程亦可透過 Azure 的 SDK 自己一步一步刻出來,但藉由 Azure DevOps Service 的平台可以很容易的把整個 CI/CD 的自動化流程建立起來,並且結合 Azure DevOps Service 中 Boards 的功能,將工單、建置及部署的動作做串接。

--

--

No responses yet

Write a response