# Hands-on: Container Application CI/CD with Azure Pipeline (.NET Container) **地區建議使用 Southeast Asia** ## 1/ 建立 Azure 上 Azure Container Registry 資源 - 連結到 **[Azure Portal](https://portal.azure.com/)** - 上方的搜尋列中搜尋 `Container Registry`,點選下方搜尋結果 **Container registries**  - 點選 **[+ Create]**  - 在 Resource Group 的欄位點選 **[+ Create New]**,自行填入要命名的資源群組名稱  - 將其餘資訊填寫完成,**[SKU]** 選擇為 **standard**,最後選擇 **Review + create**  - 確認資訊沒問題,選擇 **Create**  - 完成後到建立好的 Container Registry,選擇 Access Key,將 Admin user 開啟  <!-- - 完成後到建立好的 Container Registry 資源,點選 **Overview** 中的 **[Update]**  - 將 **Admin User** 更改為 **Enable** 後 Save  --> ## 2/ 建立 Build Pipeline ### 建立程式碼的第一條 Build Pipeline - 選擇左方選單列中 Pipelines 下的 **[Pipelines]**,點選 **[Create Pipeline]**  - 選擇畫面下方說明文字中的 **[Use the classic editor]**  - 選擇程式碼來源及分支,這裡無須特別操作,直接可以選擇 Continue  - 在右上方的搜尋欄位尋找 `docker`,找到 **Docker Container**,點選 **[Apply]**  <!-- - 點選在 **Agent Job 1** 旁邊的 **+**,選到第一個 **.NET Core** 按 **[Add]**  - 將 .NET Core 的 task 長按,用拖移方式移動到第一位  - 修改 .NET Core task 的內容 - **Command** : **test** - **Path to project(s)** : `**/**.UnitTest/**.csproj`  --> - 選到 Build an image,完成內容 - **Azure Subscription** : **<建立 ACR 資源時使用的訂閱>** - **Azure Container Registry** : **<建立的 ACR 名稱>**  - 選到 Push an image,完成內容 - **Azure Subscription** : **<建立 ACR 資源時使用的訂閱>** - **Azure Container Registry** : **<建立的 ACR 名稱>**  - 選擇 **Pipeline** 的地方,將 **Agent Specification** 選到 **Ubuntu-20.04** - 選擇上方列表的 **[Triggers]** tab,將畫面右方的 [Enable continuous integration] 打勾  - 完成後點選上方的 **[Save & queue]** ,選擇 **[Save & queue]** 後在跳出的視窗點選 **[Save and run]**  <!-- ### 紀錄 Bug - 執行到一半會發現顯示錯誤  - 點選上方 **[Tests]** 的 tab,點選下方 **[IndexPageTest]** 後會看到 Error message 顯示為: *`Assert.AreEqual failed. Expected:<DevOps Workshop>. Actual:<Success!>.`*  - 將錯誤訊息是窗關閉,點選頁面中 **[Bug]** 的按鈕,選擇 **[Create Bug]**  - 詳細錯誤訊息已自動帶入,點選 Related Work 欄位中的 **[+ Add link]** 並選擇 **[Existing item]**  - Link Type 選擇 **[Parent]**,Work items to link 選擇剛剛建立的 **[DevOps Workshop]** PBI  - 點選 **[Save & Close]**  - 點選左方選單的 **[Sprints]** 在剛剛建立的 Bug 那欄點選 **[+]**  - 填入標題 `更正標題為 DevOps Workshop`  - 點選剛剛建立的 task ,將以下資訊填寫到 Description,然後點選 **[Save & Close]** ``` 修改 Controllers / HomeController.cs 將標題修正 ```  ### 修復 Bug - 回到 Files ,點選到 *AspNetCore.Sample.Web* > *Controllers* > *HomeController.cs*    - 修改第 13 行,將原本的 "Success!" 修改為 "DevOps Workshop" ```csharp=11 public IActionResult Index() { ViewData["Message"] = "DevOps Workshop"; return View(); } ``` - 修改完成後點選右上方的 Commit  - **[Work items to link]** 欄位選擇先前建立的 `更正標題為 DevOps Workshop` task  - 此時回到 **[Pipeline]** 發現 pipeline 已自動執行,點選 pipeline  - 可看到有兩次執行紀錄,點選最新一次的執行紀錄  - 可以查第二次執行的內容,點選 **[Agent Job]**  - 可以查看各個 task 的 Log 細節  --> ## 3/ 建立 Azure 上 App Service 資源 - 回到首頁左方的選單列表,找到 App Service 並點選  - 點選 **[+ Create]**  - 在 Resource Group 的欄位選擇和建立 Container Registry 時同一個資源群組 - 將其餘資訊填寫完成 - **Publish** : Docker Container - **Region** : Southeast Asia - **Linux Plan (Southeast Asia)** 的欄位點選 **[Create new]**,並輸入自行定義的名稱  - **Pricing plan** 欄位點選 **[Explorer pricing plans]**  - 選擇 **Standard S1** 後點擊 **[Select]**  <!-- - Sku and size 欄位點選 **[Change size]**  - 在跳出的視窗選擇 **[Production]**,規格選擇 **[S1]**  --> - 完成後點選下方 **[Next: Docker >]** 的按鈕 - 將以下資訊填寫完成,完成後點選下方 **[Review + Create]** - **Image Source** : Azure Container Registry - **Registry** : (選擇先前建立的 Container Registry) - **Image** : (唯一選擇) - **Tag** : (唯一選擇) - **Satrup Command** : (留白即可)  <!-- - **Options**: Single Container - **Image Source**: Quickstart - **Sample**: NGINX  --> - 接下來會進入 review 的頁面,點選 **[Create]**  - 建立完成後會挑轉到資源正在建立中的頁面,先不要關閉 ### 利用 App Service 建立多個部屬環境 - 建立完成後會顯示資源已建立完成,點選 **[Go to resource]**  - 選擇 App Service 左方選單中 Deployment 區塊中的 **[Deployment Slots]**  - 點選上方的 [Add Slot],將 slot 的名稱設定為 `dev`,點選 **[Add]** 添加,並將 **Clone settings from** 設定為來自 Production,已獲取相關 ACR 的設定  <!--  --> - 出現 *Successfully created slot 'dev' 的訊息後,點選 **[Close]**  ## 4/ 建立 Release Pipeline ### Dev 環境 - 在左方選單列選擇 Pipelines 下的 **[Release]**,進入後點選 **[New Pipeline]**  - 找到 **[Azure App Service deplotment]**,點選 **[Apply]**  - 將 Stage name 更改為 `Dev`,完成後點選 **[X]** 關閉視窗  - 選擇 `Dev` stage 內的 **[1 job, 1 task]**  - Azure Subscription 的部分選擇建立 App Service 資源時所選擇的訂閱,選擇完成後點選藍色的 **[Authorize]** 按鈕  - 在 **[App Type]** 選擇 **Web App for Containers (Linux)**  - 等待授權完成,在 App Service name 找到剛剛建立的 App Serivce 資源,**Registry or Namespace** 填入`<Azure Container Registry Name>.azurecr.io` (Azure Container Registry Name 為先前建立的 ACR 資源) - 可在 Azure Portal 上,建立的 ACR 資源 Overview 中找到 **Login Server**  - 複製並填入為 Registry  - 在 Azure Portal 上的 Container Registry 資源中,左方欄位 [Repository] 找到要使用的 image 的 repository name  - 回到 Azure DevOps 將 **[Repository]** 填入 repository name  - 點選 **[Deploy Azure App Service]** 這個 task,將右邊欄位中的 **[Deploy to Slot or App Service Environment]** 打勾,Reource Group 選擇 App Service 的資源群組 (應該只會有一個),Slot 的部分將 Production 更改為 **[dev]**  - 完成後點選右上角的 **[Save]**,點選 **[OK]**  ### Production 環境 - 選擇上方列表的 **[Pipeline]** 列表  - 將鼠標移動到 **[Dev]** stage,會出現 **[+]**,點選添加一個新的 stage  - 選擇在 select a template 底下的 **[Empty job]**  - 將 stage 名稱更改為 `Production`,完成後點選 **[X]** 關閉  - 點選 Production 的 **[1 job, 0 task]**  - 點選在 Agent Job 中的 **[+]**  - 在 Add tasks 中選到 **[Deploy]**,找到 **[Azure App Service manage]**,點選 **[Apply]**  - 點選 **[Swap Slots:]** task,將欄位資訊填寫完整 - **Azure Subscription** : 建立 App Service 的訂閱 - **Action** : Swap Slots - **App Service Name** : 建立的 App Service 名稱 - **Resource Group** : 建立的 App Service 資源群組 - **Source Slot** : dev - 確保 **[Swap with Production]** 打勾  - 點選右上角的 **[Save]**,然後 **[OK]** - 點選上方列表的 **[Pipeline]**  ### 細節調整 <!-- - 點選在 Artifacts 方格中的 **[+ Add an artifact]** - **Source type** : Build - **Source (build pipeline)** : 先前建立的 build pipeline  - 選擇完成後點選 **[Add]** --> <!-- - 點選 Artifacts | + Add 的 **[+Add]** 再添加一個來源,選擇 **[6 more artifact types]** 展開  --> - 點選在 Artifacts 方格中的 **[+ Add an artifact]**,選擇 **[6 more artifact types]** 展開  - 選擇 **[Azure Container Registry]**,將下方欄位根據先前建立的資源依序填寫完成以連結至現有的 Azure Container Registry 資源,最後點選 **[+Add]** 添加完成  - 點選上步驟建立的 Azure Container Registry 來源方框中右上角的閃電符號,在 Continuous deployment trigger 下將 **[Disable]** 更改為 **[Enable]**,完成後點選 **[X]** 關閉視窗  - 再新增一個 Artifact 為 Build  - 在 Dev 的 stage 中點選右邊的人頭,在跳出的視窗中將 **[Post-deployment approvals]** 改為 **[Enabled]**,並在 **[Approvers]** 欄位中選擇自己,完成後點選 **[X]** 關閉視窗  - 在 Production 的 stage 中點選左邊的人頭,在跳出的視窗中將 **[Pre-deployment approvals]** 改為 **[Enabled]**,並在 **[Approvers]** 欄位中選擇自己,完成後點選 **[X]** 關閉視窗  - 將上方 All Pipelines > **[New release pipeline]** 修改為 `Release to Azure`  - 點選到上方列表的 **[Options]**,點擊到 **[Integrations]** 的欄位,將以下兩項目打勾 - [x] Report deployment status to Work - [x] Report deployment status to Boards - **Dev** > Testing - **Production** > Production  - 點選回 **[Pipeline]**  - 點選 Save  - 接著選擇 **[Create Release]**  - 在跳出的視窗中點選 **[Create]**  - 視窗上方會有一則訊息,點選 **[release 1]**,可以查看目前部屬進度  ### 環境驗證及審核 - 當 Dev stage 的部署狀態變更為 *Pending approval* 時(如一直未改變狀態可點選 **[Refresh]** 更新狀態),此時回到 **[Azure Portal](https://portal.azure.com)** 上,找到剛剛建立的資源群組,選擇 type 為 *App Service (slot)* 的 **dev** 資源  - 選擇頁面中 URL 的連結  - 顯示新的網頁已經完成部署  <!-- - 將網址列中的 `-dev` 拿掉,進入網頁  - Production 的環境尚未部屬,仍在舊的頁面  --> - 已確認在 Dev 環境中部署正確,回到 Azure DevOps 中點選 Dev stage 的 **[Approve]**  - 在跳出的視窗點選 **[Approve]**,然後 **[X]** 關閉  - 確認 Dev 完成  - 此時 Prodction 的狀態也會變更為 pending approval,點選 **[Approve]** 開始進行 Production 的部屬  - 確認 Production 的部署正確 ## 5/ 實際更新上版一次 <!-- - 回到 **[Pipelines]**,點選先前建立的 build pipeline  - 進入後點選右上角的 **[Edit]**  - 將鼠標移動到 **[dotnet test]** task 按右鍵,選擇 **[Disable selected task(s)]**,點選 **[Save]**  --> - 回到 Sprints,在 **[DevOps Workshop]** 的 PBI 中,新增一個 task 為 `將首頁標題添加今天日期`  - 回到 Files ,點選到 *AspNetCore.Sample.Web* > *Controllers* > *HomeController.cs* - 修改第 13 行,將原本的 "Success!" 修改為 "DevOps Workshop - <今天日期>",修改完成後點選 **[Commit]** ```csharp=11 public IActionResult Index() { ViewData["Message"] = "DevOps Workshop - 0824"; return View(); } ```  - **[Work items to link]** 欄位選擇先前建立的 `將首頁標題添加今天日期` task  - 此時回到 **[Pipeline]** 發現 pipeline 已自動執行  - 待 build pipeline 執行完成後回到 release pipeline 會發現已自動啟動部署流程  - 根據先前的步驟進行審核及檢查的動作 <!-- - 回到 **[Sprint]** 中,`將首頁標題添加今天日期` task 查看內容,可以在 Deployment 及 Development 中看到建置及部屬的狀況  --> ## 6/ Dashboard - 左邊選單列中的 Overview 下點選 **[Dashboards]**,點選 **[Add a widget]**  - 選擇 **[Assign to me]**,然後點選 **[Add]**  - 可再添加 **[Deployment Status]**、**[New Work Item]**,**[Query Tile]** 或自行添加其他項目    - 完成後選擇 **[Done Editing]**  - 點選 Deployment Status 進行設定,將 size 改為 **[3x2]**,並填入 **[Build pipeline]** 和 **[Linked release pipelines]**,設定完成後點選 **[Save]**  - 點選 **[Query Tile]**,**[Select Queries]** 選擇 **[Shared Query]** > **[Task in Progress]**(先前在 query 內建立的)  ## 7/ 清除資源 - 點選左方選單列表中的 **[Project Settings]**,捲到最下方有 **[Delete]** 的按鈕可以進行移除  - 到 [Azure Portal](https://portal.azure.com/) - 找到建立的資源群組,點選頁面中的 **[Delete resource group]**,在欄位中填入資源群組的名稱,選擇 **[Delete]** 即可完成清除  ## Reference - [Hands-on : Azure DevOps Service (.NET Core Web)](https://hackmd.io/@msazuredev/B1nlR8un_) - [Register free Azure account](https://azure.microsoft.com/zh-tw/free/) - [Azure DevOps Service 免費試用申請教學](https://hackmd.io/@msazuredev/HkaaHy2AO) - [Pipeline caching](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops) - [Sample Code (ASP .NET Core)](https://github.com/huier23/AspNetCoreSample.git) - [HelloWorld.Lib](https://github.com/huier23/HelloWorld.Lib.git) - [Azure DevOps Service Tag Released](https://devblogs.microsoft.com/devops/azure-devops-service-tag-released/) - [Hands-on : Azure DevOps Service (Azure Kubernetes Service)](https://hackmd.io/@msazuredev/ByonLS_mY)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up