2023年2月9日 星期四

透過Azure App Configuration實現Feature Toggle

Feature Toggle有很多名稱,也常被叫做 Feature Flag, Feature Switch…但不管他叫什麼名字,都無損他在這個時代的重要性。

為什麼重要?
他為這個時代所面對的問題,提供了適當的解決方案,這些問題包含:

  1. 實現A/B測試
  2. 實踐金絲雀佈署
  3. 實踐高強度的頻繁交付
  4. 實踐不同環境上的自動化佈署

乍看之下,上面這幾件事情都跟Feature Toggle無關,但實則有很大的關連性。在說明前,我們先理解一下 Feature Toggle 是甚麼?

Feature Toggle的建立

他是一個後台控制的開關,與我們的程式碼有所連動,簡單的說,就是在我們的程式中,加上一些簡單的Yes/No判斷敘述,然後依照這個開關在後台的on或off,來決定是否要執行這個功能。

圖片

這麼簡單的機制,為何和自動化佈署有關? 又為何可以幫助我們實踐 A/B 測試?

先談『高強度的頻繁交付』,以及『在不同環境上實現自動化佈署』這件事。

如果你對CI/CD或敏捷開發有概念,大概能夠理解近代軟體開發都希望能夠頻繁交付,頻繁的程度因團隊而異,高強度的頻繁交付,可能需要一天更版數次,而無論是一天更版數次,或是一周交付數次,都意味著開發團隊很可能每天多次合併程式碼,在這種狀況下,程式碼版控的多分支方案(例如gitflow)將變得不可行,而會慢慢收斂成單一分支(feature branch)或根本沒有分支的狀態,在這種狀況下,程式碼的整合和交付將可以變得非常頻繁。

但衍生出一個副作用,就是在這個狀況下,開發到一半的功能怎麼辦? 如果團隊需要急著修復用戶反饋的某一個bug, 必須立刻整合上版,但卻又同時需要等某幾個功能都做完,才能一次上線,這就產生了矛盾。

這時,feature toggle就會派上用場,它可以幫我們在正式環境上,先關掉不想開放的功能,等幾個具有相依性的功能都完成,再從後台一次打開開關放行。

這就是feature toggle在近代敏捷開發與CI/CD潮流下,非常重要的原因,因為它有效的分離了釋出(Release)與(Deployment)。

可以實現佈署(Deployment),但不開放(Release)功能的效果。

配合A/B測試 與 金絲雀佈署

你可能有聽過 A/B Testing,它指的是,我們會在production環境上,將用戶隨機或非隨機地分成兩組(或多組),然後讓這兩組用戶使用不同的功能設計,以便於鑑別出較好的設計。

而金絲雀佈署則是,我們把要新上線的功能,在正式機上,僅開放給特定一小群用戶來進行盲測(或明確告知其身為對照組也行),待測試無誤後,再開放給其他人。

A/B Testing為的是找到最佳的UI/UX模式,而金絲雀佈署則是為了降低上線新版功能可能造成的風險。

講到這邊你大概也知道,要實踐這些功能,最簡單的方式就是設計一個開關,對了,開關,那feature toggle不正是最好的選擇?

請看底下這個toggle的設定畫面:
圖片

你會發現Azure App Configuration的Feature toggle功能,可以針對特定比例的用戶群組、或特定使用者、特定時間區間來開放或關閉某一個功能,因此完全可以達成我們 A/B Testing 和 金絲雀佈署 的需求。

使用Feature Toggle

介紹過了Feature Toggle之後,我們來看使用的方法,底下這個影片介紹如何在Azure Portal當中,透過App Configuration 服務,來建立Feature Toggle,並且搭配程式碼來實現此功能:

2023年2月7日 星期二

好好使用Logic App, 沒事幹嘛寫程式?

不是所有東西都要寫程式的。

最近幾年,又開始流行No Code/Low Code Solutions,RPA(Robotic Process Automation, 機器人流程自動化)就是其中之一。

微軟在SaaS和PaaS平台都有相關的服務,M365的SaaS平台中,Power Automate就是RPA解決方案,可以讓power user用拖曳設計的方式,撰寫少量或幾乎不用撰寫程式碼,就可以完成一些自動化流程。

而PaaS平台上,就是Azure Portal中的Logic App

什麼是Logic App

技術人員可以把透過Logic App,用拖拉組合的方式,把一個流程設計出來,定時或在特定事件發生時,觸發後續的一連串動作。例如,當用戶把檔案上傳到 OneDrive,就自動進行圖像的人臉辨識,然後把辨識結果發送mail給特定人,如今這樣的流程,你完全不需要寫一行程式碼即可以完成。

透過這樣的方式,你可以大幅的簡化人工作業流程,乍聽之下,它跟Azure Functions, Power Automate都很像,但還是有些差異,Azure Functions雖然有binding功能,但主要還是透過撰寫function code來進行核心邏輯的處理,而Power Automate比起Logic App則比較偏向於End-User用戶端,Logic Apps中的connector和trigger則比較偏向雲端服務的整合。

具體差異可以參考微軟官方文件『Logic Apps、Functions、WebJobs 和 Power Automate 之間做選擇

建立Logic App服務

當你建立好一個Logic App服務之後,緊接著可以建立工作流程,底下影片展是如何在 Azure Portal 上 建立一個Logic App服務:

建立與使用Logic App自動化流程

建立好了服務之後,我們接著就可以建立一個流程,建立的過程中,我們需要選定 trigger 也就是觸發條件。

請看底下的例子,我們在用戶上傳檔案到 onedrive 的時候,觸發流程,然後透過 outlook connector 來進行後續的自動化動作,將上傳的檔案名稱與路徑寫入mail中發送給特定用戶:

從上面的設計展示影片中你可以看到,onedrive connector被我們用來作為trigger,觸發整個流程運行。而下一個步驟 則是 outlook connector,負責發送信件。請特別留意,我們可以從第一個 connector 產出的變數作為參數,帶入第二個connector作為email的標題(檔案名稱)或內文(檔案上傳路徑)。

運行Logic App

底下影片展示了運行的結果:

你會發現,果然在用戶上傳到 onedrive 的root目錄時,可以觸發流程,並且把檔案名稱和路徑,以outlook email給用戶。

從這邊你也會發現,Logic App的connector數量多寡,將大幅的影響實用性。微軟也知道,因此,目前已經有成千上萬的 connector 供您使用,底下網址有完整的清單:
https://learn.microsoft.com/en-us/connectors/connector-reference/connector-reference-logicapps-connectors

圖片

2023年2月6日 星期一

使用Azure App Configuration處裡微服務與容器化的配置設定

應用程式大致都會有環境變數,一般來說,我們在做網站時,除了把環境變數或是資料庫連線字串…等這些設定資訊,存放在 WebApp 的 App Config(組態設定)中,我們還有幾種不同的選擇。

Azure上獨立的App Config服務就是其中之一,中文名稱叫做『應用程式組態』。

建立『應用程式組態』服務

你可以透過 Azure Portal 建立該服務:

比起一般的config服務,從上面影片建立該服務的過程中,你也看到了,它額外具備了雲端特有的『異地備援』、『虛刪除』…等功能,讓資訊的保存更加安全可靠。

此外,它除了組態總管(Configuration Explorer),還有功能管理員(Feature Management):

圖片

你只需要透過端點(endpoint)與金鑰匙(Key)就可以存取該服務。當然,存取的過程中,需要建立類似資料庫的連線字串:
圖片

保存在該服務裡的組態資料,都是以 key-valut pair 的形式被建立的,你可以透過組態總管來建立:
圖片

撰寫程式碼抓取config資訊

建立好組態資料,接著就是在程式碼中存取。要在程式碼當中抓取存放於雲端的config資料,也相當容易,我們嘗試建立一個console app來測試:

md testappconfig
cd testappconfig
dotnet new console
dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration 
code .

上面這幾行CLI指令,會建立出一個 console application,並從NuGet引用’Microsoft.Extensions.Configuration.AzureAppConfiguration’套件。

然後,我們透過VS Code 開啟該專案,並且撰寫底下程式碼:

using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
namespace appConfigTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder(); 
            builder.AddAzureAppConfiguration("Endpoint=https://_________.azconfig.io;___;Secret=____");
            var config = builder.Build();
            Console.WriteLine(config["TestApp:Settings:Message"] );
        }
    }
}

由於我們在上面程式碼13行中,使用到了名稱為’TestApp:Settings:Message’的組態變數,因使,你只需要再透過『組態總管』,建立一個名稱為 ‘TestApp:Settings:Message’ 的索引鍵/值『索引鍵/值』,並且把上述程式碼中11行的連線字串換掉,就可以測試了。

請看底下的影片,我們展示了整個過程:

你會發現,程式碼中輕鬆地使用SDK,即可抓取雲端 Azure App Configuration 中建立好的設定,只需要透過連線字串即可。

為何需要統一管理config資訊?

你可能會疑惑,原本的 Web App 就已經有組態設定功能,若是安全性的考量,可以採用 Key Vault,那為何又需要這個Azure App Configuration 呢?

你可能猜到了,因為微服務和容器化。

過去,應用程式大多是一個大系統,系統之間合作的關聯性不是沒有,但如今當你的應用程式變成類似微服務的架構設計之後,往往比起以前更需要有一個統籌管理的組態設定後台,來進行各樣的配置。

再加上,現在的網路服務大多是全球維運環境,除了測試環境、正式環境等典型的環境差異,可能還有位於不同國家的資料中心的分散式設計,環境變數會變得比以往複雜很多,因此更需要一個統籌的管理機制。

這時候,Azure App Configuration就是一個很好的選擇。了解之後,你大概也不難理解,為何key-valut pair的組態的設定取名會變成類似底下這樣以冒號(:)的方式隔開:

TestApp:Service1:ConfigA
or
ErpApp:EastAsia:DbConnection

因為系統可能有各種不同hierarchy的設定需求。

此外,你大概也可以設想的到,透過雲端方式來儲存config資訊,若沒有處理好Cache機制,系統效能很可能會被大幅拖慢,所以Azure App Configuration整體的SDK設計,都便於建立Cache與非同步機制,以確保應用程式效能不受影響。

透過Azure AD實踐網站單一登入機制

無論是實踐單一登入(SSO)所需要的身分驗證,或是採用OAuth機制,讓用戶授權第三方應用程式來存取受管理的資源,都會從『建立一個應用程式』開始。

Google, 微軟, Twitter, LINE…都有自己的OAuth機制。Google 位於API Console, 微軟位於Azure AD,而LINE 則是使用LINE Login…這也是你常常會看到現在許多網站都有支援各種SSO身分驗證機制的原因:
圖片

在Azure AD註冊應用程式

底下我們以微軟的身分驗證機制,拿Web類型的第三方應用程式來做例子,這段影片,示範了如何在Azure AD上建立一個應用程式:

從上面的展示,你會看到我們在Azure Portal上建立好一個 App, 並設定Redirect URL,並取得App ID。建立時,身分驗證類型有四種:
圖片

分別是:
A. 企業用,只支援該AAD所屬企業
B. 企業用,支援所有具有AAD的企業
C. 企業(to B)+個人(to C),上述B加上個人帳號(例如hotmail.com, outlook.com, msn.com…等)
D. 僅限個人帳號登入,例如 hotmail.com, outlook.com, msn.com…等

接著,我們要建立並取得待會Web應用程式需要進行身分驗證時,所需要的 App Secret:

另外別忘了,再次檢查設定好的redirect URL,測試階段我們先用 localhost:
圖片

完成之後,我們就可以來測試一下,如何使用OAuth的身分驗證機制來取得access token。

OAuth Authorization Code Flow

依照OAuth的Authorization code flow流程,我們的作業流程分成兩個階段,
A> 第一個階段我們做身分驗證,並取得代碼(code),
B> 第二階段再拿code去跟伺服器端要access token。

第一階段,我們需要提供底下這些資訊(剛才都已經蒐集到):

  1. App Clinet ID
  2. redirect URL

微軟AAD使用的 endpoint 為:

https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id=[your_app_id]
&redirect_uri=http://localhost&scope=openid https://graph.microsoft.com/user.read

我們可以直接把上面的endpoint中的your_app_id換掉即可,因為這段endpoint是可以透過瀏覽器運行的,所以我們先以瀏覽器來測試:

請看上面影片中的展示,我們組出一個身分驗證與授權的URL,由於是 http redirect的URL,因此直接貼上瀏覽器運行,接著,用戶會被導入登入頁面,由用戶輸入帳號密碼,應用程式即可從網址列取得code。

取得code之後,我們要拿這個code換取token,這部分為了安全起見,OAuth Authorization Code Flow的定義是採用後端以http post方式來呼叫,因此我們採用 postman 來模擬。

這個階段,也需要底下這些資訊(一開始也蒐集到了):

  1. App Clinet ID
  2. redirect URL
  3. App Secret

整個操作影片如下:

從上面的影片中你會看到,取得 token 之後,就可以使用 token 來取得用戶資訊了。

小結

上面這幾段影片,展示了從建立App,但透過app以flow取得code,接著再用code換取token,並且拿token取得用戶個人資料(name & email),這意味著,透過這樣的流程,你不僅僅可以在安全的前提下驗證用戶身分,且第三方應用程式,可以透過取得的token取得用戶被管理的資源。

上面的流程是採用瀏覽器與postman模擬呼叫的方式來進行,若你真的要應用在自己開發的第三方應用程式,只需要把上面的流程改為透過程式碼來運行即可。 可參考 https://github.com/isdaviddong/HOL-DotNetCore/blob/master/Auth/使用 .net core 搭配 AAD 進行MS SSO身分驗證.md

2023年2月2日 星期四

建立與使用Azure Storage Account(儲存體帳戶)

Azure Storage 是 Azure中主要的儲存體,擔任一切儲存的任務。Azure Storage本身具有四種不同的存儲形式,分別是:

  • Files
    可模擬SMB檔愛存取機制,類似雲端硬碟。
  • Blobs
    適合存取各種檔案,類如影片、圖檔、文件、logs…etc.
  • Tables
    NoSQL形式的資料儲存體。
  • Queue
    FIFO(先進先出的佇列儲存體)

典型的Storage durability形式有底下幾種:

  • LRS(本地備援儲存體) - 單一資料中心內備援三份
    圖片

  • ZRS(區域備援儲存體) - 將資料同步複寫至三個不同的區域。每個區域具備獨立的電源、冷卻和網路的不同實體位置
    圖片

  • GRS(異地備援儲存體 - 基於LRS,再將資料以非同步方式複製到位於數百英哩外的另一個位置,實現真正的異地備援。
    圖片

  • RA-GRS - 基於GRS加上可從異地支援讀取功能。

底下影片示範如何建立azure storage,並且建立一個 container,以及上傳檔案(blob)到container中。觀察影片中的操作,你會發現,當我們把 container的存取權限調整之後,blob檔案的URL就可以存取了,否則會變成找不到上傳的檔案:

Container 的 匿名存取層級有三種:

  • 無公用讀取權限︰只能讓有授權的用戶存取容器及其 Blob檔案。(此選項是預設值)
  • 僅對 Blob 有公用讀取權限:您可以透過匿名要求讀取容器內的 Blob,但您無法匿名使用容器資料。 匿名用戶無法得知容器中有哪些blob檔案。
  • 容器及其 Blob 的公用讀取存取權限:匿名要求可以讀取該容器中所有 Blob 檔案,也可以列出容器中有哪些blob檔案。

Shared Access Signature (SAS)

針對特定的 blob 檔案,可以產生具有SAS(簽章)的連結,可讓特定IP在特定時間內,存取該blob檔案。

產生SAS簽章的方式如下:

透過具有簽章的連結,可以在特定時間區間內,從特定的IP位置存取該blob檔案,是控制權限很好的方式。

參考資料:
https://learn.microsoft.com/zh-tw/azure/storage/common/storage-redundancy

2023年1月31日 星期二

使用Visual Studio開發支援容器化的 .net 網站

在 .net 開發技術中,若要產生支援 Linux Container 的 Image 非常容易,你只需要底下幾個步驟即可:

圖片

上圖中的 Image Registry,可以是私有的,也可以是公用的。目前坊間公用的 Registry 典型像是 Docker Hub,若你把Image上傳到Docker Hub,人人都可以下載使用。許多軟體和框架的開發商,都已經把自己所建立的SDK, Runtime上傳至Docker Hub:
圖片

私有的Registry則適合企業存放僅供內部使用的Image。開發人員可以透過軟體自建Private Image Registry,或是採用雲端現成的服務,像是Azure 上的ACR(Azure Container Registry)。

使用Docker File建立image

docker file是一份文件,透過docker file我們可以建置出docker image,你可以透過手動方式,以docker CLI來建立,若採用開發工具,在 Visual Studio 中,只需要將專案加入docker支援,即可自動建立 docker file:

圖片

Visual Studio自動建立出來的 docker file,會依照 .net 版本有所不同。例如,底下是 .net 5 的 docker file:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["testdocker.csproj", "."]
RUN dotnet restore "./testdocker.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "testdocker.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "testdocker.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "testdocker.dll"]

建立的過程中,如果出現OS選擇,請選擇 linux:
圖片

上面的 docker file 被稱為 multi-stage build, 主要分成四個段落。有了docker file之後,我們就可以將我們開發出來的網站,建立出Image了。

使用Visual Studio建立並發佈Image

你可以在 Visual Studio中,直接透過方案總管來建置 Image 影像檔,完成後,該應用程式的image檔案會出現在 local 的 docker desktop工具中:

完成後,即可建立出image

注意,你的Visual Studio環境必須安裝有 docker desktop才行。

前面提到過,建立出來的Image,可以先發佈到 Image Registry,以便於未來將應用程式佈署到正式環境執行。

你可以透過 docker push 指令,把Image推送到Registry,不過我們有Visual Studio,可以更方便的完成這個動作。

你可以先在Azure Portal建立好私有(Privately)的Registry,建立方式如下:

接著,我們可以透過Visual Studio直接把Image建置好並發佈到Azure ACR,過程如下:

從ACR佈署到ACI

將建立好的Image放上 ACR,同時也有另一個好處,就是我們保留了每一個不同時期產出的網站,就好比把一個個的不同版本的artifacts封存,我們可以藉由ACR,進行每一個可運行的網站的版本控管。

除了隨時將最新版的部屬到正式機環境執行,我們也隨時可以進行roll-back退回上一版,甚至隨時找到任何一個需要的版本。

若您想將發佈到ACR上的image,實際上佈署到容器中運行,可以參可底下做法,下面展示將ACR發佈到ACI,成為一個實際可執行的網站:

2023年1月30日 星期一

使用VMSS實踐負載平衡

我們知道,可以透過串聯多台虛擬機,加上traffic routing,實踐負載平衡,讓你的應用程式的可用性得以提升。

不過,在Azure當中有比手動實踐更方面的選擇,那就是
VMSS( Virtual Machine Scale Set)。Azure VMSS可幫助我們建立一套內建負載平衡的 VM組。執行個體的數目可以視需要自動或手動增加、減少,可輕易地實現 Auto Scale或Fail-over。

建立VMSS

建立一組VMSS的方式很簡單,請參考底下影片:

建立過程中,我們分別透過底下PS指令,在兩台伺服器上建立IIS服務,並建立預設網頁:

Add-WindowsFeature Web-Server
Set-Content -Path "C:\inetpub\wwwroot\Default.htm" -Value "Hello world from host $($env:computername) !"

網頁會分別顯示機器名稱,從上面的有片中,你會看到,我們試著停掉其中一台機器,另一台VM會即時接手執行,自動實現 fail-over 之效果。

熱門文章