前言
在開發專案的初期,除了環境設定以外,程式的參數設定會是初期需要處理的問題,不外乎是怎麼存?存哪裡?而在預設的 .NET Core 專案會是存在 appsettings.json 這一個檔案裡面,而專案越來越大或是越來越多子專案之後,就會延伸一個問題是參數的管理,可能在很多專案會用到一樣的參數,但是當這個參數要調整的時候,會需要每一個專案都記得去修改,這樣在管理上會相當的不方便,這時候就可以使用 Azure 上的 App Configuration 這一個服務來統一管理和設定參數,而最近微軟 Public Preview 一個新的功能,讓我們可以在不修改程式的情境下讓 App Service 的組態可以直接使用 App Configuration 內的參數,後面就來介紹該如何啟用這樣的功能。
實做
首先準備準備一個測試的 Web 站台,程式碼很簡單的就是去讀取一個參數值。
public class HomeController : Controller
{
private readonly IConfiguration _configuration;
public HomeController(IConfiguration configuration)
{
_configuration=configuration;
}
public IActionResult Index()
{
ViewBag.Test = _configuration.GetValue<string>("Test");
return View();
}
}
在 appsettings.json 也加上對應的參數。
{
"Test": "From appsettings.json"
}
而 View 也單純把參數印出來就好。
Config: @ViewBag.Test
然後部署到 App Service 上面,就可以看到參數顯示出來了,是從 appsettings.json 取得的。
這時候到 App Service 的組態設定一組參數,並輸入參數值 From App Service
。
儲存之後重新瀏覽網站就會看到我們程式吃到的設定值是來自於 App Service 上面設定的值了。
到這邊就完成基本的環境和程式的部署,接下來就是設定讓 App Service 可以支援從 App Configuration 取得設定的參數。
中文語系的話搜尋應用程式組態,英文語系則是 App Configuration ,點選建立來建立一個服務起來。
因為我們要測試使用,或是一開始還用不到比較多的功能,比如說軟刪除等,就可以先選擇免費方案,而免費方案在每個訂閱是有上限的,還有呼叫次數跟容量等限制,可以直接參考官方定價表文件,就不多說明了。
服務建立好之後先把 Endpoint 記錄下來,後面設定時候會用到。
接下來新增一個參數值,點選 Configuration explorer 來建立一個新的 Key-value 類型參數。
這邊 Label 我就留空白了,如果是正式一點的使用,就可以透過 Label 來設定 Production、Staging、Development 等環境的參數,方便我們統一管理。
再來新增一個受控身份識別,之後會透過這一個身份識別在 App Service 存取 App Configuration。
接下來分別在 App Service 和 App Configuration 中的身份識別都加上這一個使用者指派的設定。
再來開啟 Cloud Sell 來設定 App Service 可以支援 App Configuration,這段的操作,目前僅能透過指令來執行,暫時還無法用 UI 來設定。
首先第一段是取得前面設定的使用者指派授權的 ResourceId。
userAssignedIdentityResourceId=$(az identity show -g MyResourceGroupName -n MyUserAssignedIdentityName --query id -o tsv)
接下來是取的 App Service 的 ResourceId。
appResourceId=$(az webapp show -g MyResourceGroupName -n MyAppName --query id -o tsv)
最後是把使用者指派設定到 App Service 的參數上keyVaultReferenceIdentity
,就可以啟用 App Service 存取 App Configuration 了。
az rest --method PATCH --uri "${appResourceId}?api-version=2021-01-01" --body "{'properties':{'keyVaultReferenceIdentity':'${userAssignedIdentityResourceId}'}}"
再來回到 App Service 的組態設定,把參數的值設定成如下格式的參數,這時候就會用到我們前面記錄下來的 Endpoint 位址了。
@Microsoft.AppConfiguration(Endpoint=https://{YourEndPoint}.azconfig.io; Key={YouConfigKey}; Label={YourKeyLabel})
如果沒有或是不需要 Label 則是:
@Microsoft.AppConfiguration(Endpoint=https://{YourEndPoint}.azconfig.io; Key={YouConfigKey})
存檔之後再重新整理網站就可以看到參數值是從 App Configuration 來的參數了。
如果前面設定錯誤或是沒有該參數值,也不會導致網站出錯,但是會直接顯示參數的設定,這點可能需要注意一下,不然 Endpoint 就可能會洩漏了。
另外需要提的一點是當 App Configuration 參數修改的時候, App Service 會在任何會導致重新起動網站的操作 (點選重啟網站、修改組態、重新部署程式等) 的行為時候去重新取得參數值。
最後補充一個部分,這在官方文件沒有提到,如果不想使用的時候,想把設定恢復成原始狀態,其實只要把 keyVaultReferenceIdentity
這一個參數設定成 SystemAssigned
就好了,但是透過前面的指令修改之後執行卻是無法正確生效了,這時候只好使用 Azure Resource Exploer 來修改了。
底下修改請小心設定,不然會把 App Service 改壞掉。
依序找到對應的 App Service,點選上方的 Read/Write
來解除唯獨模式,就可以編輯下面的 App Service 設定的 Json 檔案,再點選 Edit 切換到編輯的方法。
接下來修改 keyVaultReferenceIdentity
成 SystemAssigned
。
回到最上面點選 PATCH 按鈕來儲存設定。
09/25 補充
在 Azure Portal App Service 組態設定上面如果有正確設定,會在上面顯示來源是金鑰保存庫參考,並且有綠色的打勾圖案,反之則是紅色的 X。
結論
透過 Azure 的服務不管是從 App Service 或是使用 App Configuration 都可以方便我們管理參數值,也可以避免把正式環境的參數值直接洩漏給開發人員或是寫在程式碼中進到版控,這些都可以提昇環境參數的安全性,如果有需要也可以把開發環境和正式環境用不同的 App Configuration,就只需要透露給開發人員知道開發環境的參數值就好,也可以統一開發人員使用的參數,不需要每一個人存著一份,對於參數管理和設定上就會每個人都可能有一版不同的參數,最後導致不知道是誰的參數有錯或是最完整的版本。
雖然本文介紹了不用改程式的方式來套用 App Configuration,但是建議還是可以修改程式讓程式直接套用 App Configuration 的方式來存取,這樣也才可以在開發階段就使用 App Configuration 來統一管理開發人員使用參數。