この記事に書いてあることを実現するために、Azureのテンプレートファイルを生成する必要がある。
テンプレートファイルはJSON形式。例えば、WebAppsは以下のURLにある通り。(この記事を書いた時点でのURLなので、将来変わるかも)
https://docs.microsoft.com/ja-jp/azure/templates/microsoft.web/allversions
そこで、要求されているパラメータをクラスのメンバーにして、Newtonsoft.Jsonを使ってモデルクラスをJSONにシリアライズすればいいかな、と考えた。
1. SDKからモデルを拝借
でも、テンプレートファイルの形式に沿った自前でクラス作ると、Azure側の変更とかに追従しなきゃいけなくなったりして面倒。
なにか簡単な方法ないかな・・・・ということで、.NET SDKのモデルクラスを借りることにした。例えば以下。
これを見ると、テンプレートのMicrosoft.Web sites templateにかなり近い構造を持っていることがわかる。
なので、このクラスを継承した独自のクラスを作れば・・・・!
usingMicrosoft.Azure.Management.WebSites.Models;//...(中略)...classSiteModel:Microsoft.Azure.Management.WebSites.Models.Site{publicstringtype="Microsoft.Web/sites";publicstringapiVersion="2019-08-01";publicSiteModel(){}
2. 発生した問題と解決法
継承したモデルを使ってWebAppsの名前を設定するプロパティに値を入れようとしたら、getしか認められていない・・・・
つまり、WebAppsに好きな名前を設定できない。
なので、外部からWebAppsの名前を設定したかったら、コンストラクタを生成する段階で名前を入れておく必要がある。
コンストラクタの引数はバカ多いものの、幸い必須なのはlocationだけのようなので、locationとnameだけを指定できるようコンストラクタを追加。
publicSiteModel(stringlocation,stringname):base(location:location,name:name){}
3. JSON形式にシリアライズ
準備はできた。早速シリアライズや!
usingNewtonsoft.Json;usingSystem;namespacejsontest2{classProgram{staticvoidMain(string[]args){varsite=newSiteModel(location:"Japan East",name:"testSite");stringjson=JsonConvert.SerializeObject(site,Formatting.Indented);Console.WriteLine(json);}}}
出力は以下。
{
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"properties.state": null,
"properties.hostNames": null,
"properties.repositorySiteName": null,
"properties.usageState": null,
"properties.enabled": null,
"properties.enabledHostNames": null,
"properties.availabilityState": null,
"properties.hostNameSslStates": null,
"properties.serverFarmId": null,
"properties.reserved": null,
"properties.isXenon": null,
"properties.hyperV": null,
"properties.lastModifiedTimeUtc": null,
"properties.siteConfig": null,
"properties.trafficManagerHostNames": null,
"properties.scmSiteAlsoStopped": null,
"properties.targetSwapSlot": null,
"properties.hostingEnvironmentProfile": null,
"properties.clientAffinityEnabled": null,
"properties.clientCertEnabled": null,
"properties.clientCertExclusionPaths": null,
"properties.hostNamesDisabled": null,
"properties.outboundIpAddresses": null,
"properties.possibleOutboundIpAddresses": null,
"properties.containerSize": null,
"properties.dailyMemoryTimeQuota": null,
"properties.suspendedTill": null,
"properties.maxNumberOfWorkers": null,
"properties.cloningInfo": null,
"properties.resourceGroup": null,
"properties.isDefaultContainer": null,
"properties.defaultHostName": null,
"properties.slotSwapStatus": null,
"properties.httpsOnly": null,
"properties.redundancyMode": null,
"properties.inProgressOperationId": null,
"identity": null,
"id": null,
"name": "testSite",
"kind": null,
"location": "Japan East",
"tags": null
}
いやプロパティがバカ多いな。いらないやつは出さなくていいぞい。
実際、自前のWebAppsをテンプレート化してみたら「hostNameSslState」とか無かったし。
パラメータ自体はフルセットだから当然クソほどあるんだろうけど、実際すべてのパラメータをフルに使うなんてそうそうない気がする。
というわけで、シリアライズ時に引数を渡します。
stringjsonExcludeNull=JsonConvert.SerializeObject(site,newJsonSerializerSettings{NullValueHandling=NullValueHandling.Ignore,Formatting=Formatting.Indented});
こうすると、出力が以下のように。
{
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"name": "testSite",
"location": "Japan East"
}
いいんじゃないのこれー!?!?!?テンプレートファイルみたいにできるかも!!!
あとは階層構造みたいなんがうまくいけば、もうコレほぼ完成だろコレおい。
・・・・とテンションが上がったところで今日は終わります。
あと、全然関係ないけどAZ-103受けたら合格した。
PaaSばっか触っててあんまIaaSとか詳しくないけど、1か月くらいそれなりに勉強したら受かりました。
うぇい。