ä»æåºã¦ãã Azure ã®æ°ããã¢ããªã±ã¼ã·ã§ã³åããµã¼ãã¹ã® Azure App Configuration ããä»æã£ã¦ã課é¡ãããæãã«è§£æ±ºãã¦ãããããªã®ã§ããã¬ãã¥ã¼ã®ãã¡ã«ä¸éã触ã£ã¦ããã¾ããã
æ®é㯠ASP.NET Core ã® Configuration Provider ã ASP.NET ã® Configuration Builder ã使ã£ã¦è§¦ãã¯ããªã®ã§ãåºæ¬çãªé¨åã¯ããã¥ã¡ã³ãã ãã§ååã§ãããªã®ã§ç¹ã«è§¦ãã¾ããã
REST API ã®ããã¥ã¡ã³ã㯠GitHub ã«ç¨æããã¦ãã¾ãããProvider ãå©ãã¦ã API ãªã®ã§ãããããããªãè¨å®ãæåããã£ãå ´åã¯ãã£ã¡ãèªãã°å¤§ä½è§£æ±ºãã¾ããConsistency Model ã®è©±ã¯èå³æ·±ãã§ããã
App Configuration ã§è§£æ±ºã§ããããªèª²é¡ã¨ãã¦ãè¤æ°ã® App Service ã Azure Functions ã管çãã¦ããæã« App Settings ããã©ãã©ã«ãªã£ã¦äºæ ããããã¨ããåé¡ã§ããç¹ã«è¤æ°ãªã¼ã¸ã§ã³ã«ãããã¤ãã¦ããå ´åããæ¬çªã¨ã¹ãã¼ã¸ã³ã°ãªã©è¤æ°æã£ã¦ããå ´åãªã©ã§ã¯ç°¡åã«äºæ ãã¾ãã
ããã¾ã§ã Key Vault ã使ããã¨ã§åãããã«è§£æ±ºã§ãã¾ãããKey Vault ã¯ãã£ã¨å ãã¤ã¡ã¼ã¸ãããã¾ããManaged Identities ã¨ã®çµã¿åããã§ãKey Vault ã® secret ã使ãæ©ä¼ã¯æ¸ããããªäºæããã¾ãã
æã« Azure Storage ã使ã Configuration Provider ãæ¸ãããã¨ãããã¾ããããå®å ¨ã« App Configuration ã§ç½®ãæãå¯è½ãã¤ä¾¿å©ã§ããä½è£ã§ç§»è¡ããäºå®ã§ãã
App Configuration ã¯åãªã Key-Value Store ãªã®ã§ã大éæã«ã¯ Azure Table ã¨å¤ãããªãæããããã¾ãããã¯ã¨ãªãå å®ãã¦ãã¦æ´ã«å±¥æ´ãä¿æãã¦ãããã®ã§è¨å®åãã«æé©åããã¦ãã¾ãã
ãã®ãããã«ã¤ãã¦ã¯ããã¥ã¡ã³ãã«æ¸ãã¦ããã®ã§èªãã§ããã¦ãã ããã
å®éã«ããã¥ã¡ã³ãéãã«åããã¦ã¿ã¾ããããå½ç¶ãªãããã£ããåãã®ã§ç¹ã«æ¸ããã¨ã¯ãªãã§ãã
ASP.NET Core ã® Configuration ã¨åãæ§é ãæã£ã¦ããã®ã§ããã¼ã®åç §æã¯ä»¥ä¸ã®ããã«ç´æ¥ã§ã Section ãçµç±ãã¦ãæ±ãã¾ãããã®è¾ºããã馴æã¿ã§ããã
@Configuration["TestApp:Title"] <hr> @Configuration.GetSection("TestApp")["Title"]
ããã¥ã¡ã³ãã«ã¯ä»ã«ãåçã«è¨å®ãæ´æ°ããæ¹æ³ãããã¾ããããApp Configuration ãå¤æ´ããã£ãã¿ã¤ãã³ã°ã§ Push ãã¦ãããããã§ã¯ãªããåã«ã¯ã©ã¤ã¢ã³ãå´ã§ Polling ãã¦ãã ãã£ã½ãã®ã§ä½¿ãæ©ä¼ã¯ãã¾ããªãããã§ãã
ASP.NET Core ã§ã¯ IOptionsSnapshot<T>
ã§æèããã«æ±ãã¾ãããå®è¡ä¸ã«è¨å®ãå¤ãããã¨ãèæ
®ãã¦ä½ããããåèµ·åã§å¤ãã£ã¦ãããæ¹ãå人çã«ã¯å¥½ãã§ãã
ããããå ã¯æ°ã«ãªã£ãæ©è½ã«ã¤ãã¦èª¿ã¹ããã¨ãã¡ã¢ã¨ãã¦æ®ãã¦ããã¾ãã
Azure Portal ã§ä½¿ããæ©è½
History
App Configuration ã«è¿½å ãããã¼ã¯å±¥æ´ãæã¡ã¾ããã©ã®ãããæã¦ãã®ãã¯èª¿ã¹ã¦ãªãã§ãããæéãã¼ã¹ã§ã®ã¢ã¯ã»ã¹ãåºæ¥ãã®ã§ããããªãã®æéä¿æã§ããã®ã§ã¯ãªããã¨æã£ã¦ãã¾ãã
Configuration ç³»ã®ã©ã¤ãã©ãªã使ã£ã¦ããå ´åã¯æèããªãã§ãããETag ã使ã£ãæ¡ä»¶ä»ãã¢ã¯ã»ã¹ã REST API ã«ã¯å®è£
ããã¦ãã¾ããä¾ã«ãã£ã¦ If-Match / If-None-Match
ã使ãå½¢ã«ãªãã¾ãã
Import / Export
å°å³ã«æ¬²ããã£ãã®ã Import / Export ã§ãããASP.NET Core ããã¸ã§ã¯ãã«å«ã¾ãã¦ãã appsettings.json ãèªã¿è¾¼ã¾ããã¨ãç°¡åã« App Configuration ã¸ã®ç§»è¡ãåºæ¥ãã¯ãã§ãã
å°å³ã«ããããªãã©ã¼ãããã«å¯¾å¿ãã¦ãã¾ããproperties ãã¡ã¤ã«ã¯æè¿è¦ãªããªãã¾ããããWin Forms ã WPF ã§ä½¿ã£ã¦ãã XML ãã¼ã¹ã®ãã¤ã§ãã
ã¤ã³ãã¼ãããããã¡ã¤ã«ãã¢ãããã¼ãããã¨ãSeparator ã Prefix ãªã©ãæå®ã§ãã¾ãã
Label ã«é¢ãã¦ã¯ããããªä½¿ãéãããããã§ããããã¥ã¡ã³ãã§ã¯ãã¼ã¸ã§ã³çªå·ãè¨å®ãã¦ããããã¾ããããªã¼ã¸ã§ã³åãç°å¢å*1ãè¯ããããªæ°ããã¦ãã¾ãã
ã¨ã¯ã¹ãã¼ãããã¡ã¤ã«å½¢å¼ã Separator / Label ãæå®ããã ãã§ããç°¡åã§ããã
Compare Settings
å²ã¨ãããããã¿ã ã¨æãã®ã Production / Staging / Development ã§ä½æ ãè¨å®ããã¦ãããã¼ã®æ°ããç°å¢éä¾åã®ã¯ãã®è¨å®å¤ãç°ãªã£ã¦ãããã¨ã§ããæ¯è¼ããã®ãå²ã¨æéããããã®ã§ãåé¡ãèµ·ããã¾ã§æ¾ç½®ãããã¡ã§ããã追å ã ãããã¦åé¤ãããªãã®ãç¹å¾´ã ã¨æãã¾ãã
ãã㦠App Configuration ã§ã¯æ¯è¼ããæ©è½ãç¨æããã¦ã¾ãããããããã®ã欲ããã£ãã§ãã
ç¹å¾´ã¨ãã¦ã¯å¥ã® App Configuration ã¨ãæ¯è¼ã§ããç¹ã§ãããProduction / Staging ãªã©ããªã½ã¼ã¹ã°ã«ã¼ãåä½ã§åãã¦ããå ´åã«ã¯ãApp Configuration èªä½ãåãã¦ãããã¤ããã¯ãã§ããããããã£ãå ´åã§ããµã¯ãã¨å·®åã確èªã§ãã¾ãã
ã¡ãªã¿ã«æ¥ä»ãæå®ããã¨ããã®æç¹ã§ã®è¨å®å¤ã¨ã®æ¯è¼ãåºæ¥ã¾ãã
ã¯ã©ã¤ã¢ã³ãã§ä½¿ããæ©è½
Label Filter
Label ã®ä½¿ãéã¨ãã¦ãã¼ã¸ã§ã³çªå·ãä»ããã®ãããã¥ã¡ã³ãã«ããã¾ããããä»ãã Label ã使ãããã«ã¯ App Configuration Provider å´ã§è¨å®ãå¿ è¦ã§ãã
æ£ç´ã¡ã½ããåã¯åããã«ããã§ãããUse
ã使ãã¨ãã£ã«ã¿ãè¨å®ã§ãã¾ãã以ä¸ã®ä¾ã§ã¯ Label ã¨ã㦠1.0.0
ãä»ãã¦ãããã®ã ããæ¾ããã¨ãåºæ¥ã¾ãã
config.AddAzureAppConfiguration(options => { options.ConnectionString = settings["ConnectionStrings:AppConfig"]; // Label = 1.0.0 ãä»ãã¦ãããã®ã追å options.Use("*", "1.0.0"); });
ãã¼ã¸ã§ã³çªå·ã®å ´åã¯ãå ¨ã¦ã®ãã¼ã«å¯¾ãã¦åã Label ãç¨æããã¨æãã®ã§ä¸ã®ã³ã¼ãã§åé¡ãªãã§ããããªã¼ã¸ã§ã³ãç°å¢åã®å ´åã«ã¯ä¸é¨ã®å¤ã¯å ±éã«ãã¤ã¤ãç¹å®ã®ãã¼ã§ã¯å¥ã«ãããã±ã¼ã¹ãåºã¦ããã¨æãã¾ãããããã£ãå ´åã§ã¯å°ã工夫ãå¿ è¦ã«ãªãã¾ãã
ä¾ã¨ãã¦ä»¥ä¸ã®ããã« Label ç¡ãã®å ±éãã¼ã¨ Label ãä»ãããã¼ãç¨æãã¾ããã
å
±éãã¼ã使ãã¤ã¤ãç¹å®ã® Label ãä»ãããããã¼ã使ãå ´åã«ã¯ Use
ãè¤æ°åå¼ã³åºããã¨ã§å®ç¾ã§ãã¾ããå¼ã³åºãé çªãéè¦ãªã®ã§ãããã ãã¯æ³¨æãå¿
è¦ã§ãã
config.AddAzureAppConfiguration(options => { options.ConnectionString = settings["ConnectionStrings:AppConfig"]; // Configuration ã¯å¾ãã追å ãããã®ãåªå options.Use("*"); options.Use("*", "NewVer"); });
ããã§å®è¡ãã¦ã¿ãã¨ãLabel ãä»ãããããã¼ã®å¤ãåªå ãã¦ä½¿ããã¦ãããã¨ã確èªã§ãã¾ãã
ãã¼ã«ãªã¼ã¸ã§ã³ãç°å¢åãå ¥ããã®ã¯é·ããªãããå ±éã®ãã¼ãç¨æããã®ãæéãããã£ã¦ã¤ãã¤ãã ã¨æã£ã¦ããã®ã§ãä¸æã Label ã使ã£ã¦è§£æ±ºåºæ¥ããã§ãã
Time-Based Access
ä¸ã§ä½¿ã£ãUse
ã¡ã½ãã㧠preferredDateTime
ãæå®ããã¨ããã®æç¹ã§ã®å¤ãåã£ã¦ãããã¨ãåºæ¥ã¾ãããã ãä»ã®ãã¼ã¸ã§ã³ã§ã¯è±èª OS 以å¤ã ã¨ã¨ã©ã¼ã§åããªãã¨æããã¾ãã
config.AddAzureAppConfiguration(options => { options.ConnectionString = settings["ConnectionStrings:AppConfig"]; // ç¾å¨ã®ãã¼ã¸ã§ã³ (1.0.0-preview-007830001) ã§ã¯ã¨ã©ã¼ã«ãªã£ã¦åããªã options.Use("*", preferredDateTime: new DateTimeOffset(2019, 2, 28, 19, 0, 0, TimeSpan.FromHours(9))); });
ä¾å¤ã®å 容ãããã¦ã«ã«ãã£æå®ãå¿ãã¦ããã£ã½ãã§ããå ±åã¯ããã®ã§ GA ã¾ã§ã«ã¯å¤åç´ãã§ãããã
追è¨
Slack ã®ãã£ã³ãã«ã§å ±åããã Issue ãä¸ãã£ã¦ã¾ããã
åç¾ã§ãããããã®ã§ç´ãã¯ãã§ããWorkaround ãå ¬éãããã®ã§ãä¸å¿ã¯ããã§ã¨ã©ã¼ãåé¿ã§ãã¾ãã
Offline Cache
è¨å®ç³»ãå¤é¨ã®ãµã¼ãã¹ã«ä¾åããæã«åé¡ã¨ãªãã®ãããã®ãµã¼ãã¹ãè½ã¡ãæã§ããããã©ã«ãã§ã¯èµ·åæã« 1 åã ãèªã¿è¾¼ãã®ã§ã¤ã³ã¹ã¿ã³ã¹ãèµ·åãã¦ããéãã¯åé¡ã«ã¯ãªããªãã§ãããApp Service ã¯ã¡ããã¡ããã¤ã³ã¹ã¿ã³ã¹ãå¤ããã®ã§ãã¿ã¤ãã³ã°æ¬¡ç¬¬ã§ã¯èµ·åããªããªãã¾ãã
GA ããæã«ã¯ SLA ãæä¾ãããã¨æãã¾ããããµã¼ãã¹ãè½ã¡ãã¨ãã¯è½ã¡ãã®ã§æ¬çªç³»ã§ã¯ Offline Cache ãæå¹ã«ãã¦ãããæ¹ãè¯ãããã§ããååã®éãæå¾ã«ä½¿ã£ãè¨å®ãããªãã©ã¤ã³ã§ã使ããããã«ä¿åãã¦ããã¦ãããæ©è½ã§ãã
åºæ¬ã¯ SetOfflineCache
ãå¼ã¶ã ãã§ãããç¨æããã¦ããã®ã¯ãã¡ã¤ã«ã«ä¿åãã OfflineFileCache
ã¨ãªãã¾ããApp Service ã®å ´å㯠OfflineFileCache
ã®è¨å®ä¸è¦ã§åãã¦ãããã¿ããã§ãã
config.AddAzureAppConfiguration(options => { options.ConnectionString = settings["ConnectionStrings:AppConfig"]; // éçºç°å¢ä»¥å¤ã§ã¯ Offline Cache ãæå¹åãã if (!hostingContext.HostingEnvironment.IsDevelopment()) { options.SetOfflineCache(new OfflineFileCache()); } });
ãã¼ã«ã«éçºç°å¢ã§ã¯åãã¦æ¬²ãããªãã®ã§ if ã§å²ãã§ããã¾ãã
App Service 以å¤ã®å ´åã¯æ°¸ç¶åãããã¹ãã¬ã¼ã¸ã«æ¸ãè¾¼ãã§ããã°è¯ãã§ããé©å½ã« TEMP 以ä¸ã«æ¸ããããªã³ã¼ãã§è©¦ãã¦ã¿ã¾ããããä¿åå ´æã«ã¯æ³¨æãã¾ãããã
config.AddAzureAppConfiguration(options => { options.ConnectionString = settings["ConnectionStrings:AppConfig"]; // éçºç°å¢ä»¥å¤ã§ã¯ Offline Cache ãæå¹åãã if (!hostingContext.HostingEnvironment.IsDevelopment()) { options.SetOfflineCache(new OfflineFileCache(new OfflineFileCacheOptions { Path = Environment.ExpandEnvironmentVariables(@"%TEMP%\app-config-cache.json") })); } });
ã¡ãªã¿ã« Offline Cache ãæå¹ã«ãªãã®ã¯ãããã¯ã¼ã¯ç³»ã®ã¨ã©ã¼ã®æã ãã®ããã§ãã
æå ã§ãããã¯ã¼ã¯æ¥ç¶ãåã£ãå¾ã«å®è¡ãã¦ãã¢ããªã±ã¼ã·ã§ã³ãèµ·åãããã¨ã¯ç¢ºèªãã¾ããã
Managed Identities
App Configuration ã§è¨å®å¨ãã¯æ¥½ã«ãªã£ãã¨ãã£ã¦ããçµå±ã¯ App Configuration ã¸ã®ã¢ã¯ã»ã¹æ å ±ãæããªãã¨ãããªãã®ã§ãApp Service ã®å ´å㯠Managed Identities ãæå¹ã«ãã¦ä½¿ãã¾ãããã
AAD çµ±åããã¦ããããã§ã¯ãªããã¢ã¯ã»ã¹ãã¼ã Management API ã使ã£ã¦åå¾ãã¦ãã ãã¿ããã§ãã
èªåã®ç°å¢ã§ã¯ Visual Studio ã® Azure ãµã¼ãã¹èªè¨¼ã使ã£ãã¢ã¯ã»ã¹ã¯ã¨ã©ã¼ã§åããªãã£ãã®ã§ãããä»çµã¿ä¸ã¯å¯è½ãªã¯ããªã®ã§èªåã®ã¢ã«ã¦ã³ãã«åé¡ããã£ãã®ããç¥ãã¾ããã
*1:Production / Staging / Development ãªã©