CosmosDB アップデート振り返り＆ARMテンプレートの機能を少し試す

# はじめに
de:code 2019行ってきました。1日目の混雑具合にはちょっとげんなり。

Azure Kinect DK欲しい。日本発売まだですか？！
Cosmos DBのアップデートにようやく追いつけた気がします

# 最近のCosmosDB アップデート（ざっくり、気になるところだけ）
## 2018/12/4
* [Azure Cosmos DB の開発者エクスペリエンスの更新 (2018 年 12 月)](https://azure.microsoft.com/ja-jp/blog/azure-cosmos-developer-experience-updates-december-2018/)
  * ⇒**データベースレベルのスループット割当て、最小値が 10,000から400に。**

## 2019/5/15
* [Cosmos 開発者向けの Azure Cosmos DB に関する最新発表](https://blogs.technet.microsoft.com/mssvrpmj/2019/05/23/a-cosmonaut-s-guide-to-the-latest-azure-cosmos-db-announcements/)
* [A Cosmonaut’s guide to the latest Azure Cosmos DB announcements](https://azure.microsoft.com/en-us/blog/a-cosmonaut-s-guide-to-the-latest-azure-cosmos-db-announcements/)
  * FixedからUnlimitedへの自動アップグレード<br>
    ⇒[非パーティション分割コンテナーをパーティション分割コンテナーに移行する](https://docs.microsoft.com/ja-jp/azure/cosmos-db/migrate-containers-partitioned-to-nonpartitioned)
  * V3 SDK 5月中GA(予定)<br>
[DP52
Azure Cosmos DB AMA](https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=DP52)で、中の人に聞いたら、["全部のプルリクがマージされた時がリリースだ"](https://github.com/Azure/azure-cosmos-dotnet-v3/pulls?q=is%3Apr+is%3Aopen+label%3A%22Required+for+GA%22)って言われました。<br>
    ⇒まだ[Azure/azure-cosmos-dotnet-v3 GA](https://github.com/Azure/azure-cosmos-dotnet-v3/projects/2)
  * [Azure Cosmos DB の強化された Azure Resource Manager のサポートを開始](https://azure.microsoft.com/ja-jp/updates/enhanced-azure-resource-manager-support-for-azure-cosmos-db-is-now-available/)<br>
    アカウントは前から作れましたが、データベース、コレクションもARMから作れるように。<br>
    ⇒[Resource Manager テンプレートから Azure Cosmos DB Core (SQL) API リソースを作成する](https://docs.microsoft.com/ja-jp/azure/cosmos-db/manage-sql-with-resource-manager)
 
* [Enhanced SQL API query functionality in Azure Cosmos DB is now available](https://azure.microsoft.com/en-us/updates/enhanced-sql-api-query-functionality-in-azure-cosmos-db-is-now-available/)
  * OFFSET/LIMITおよびDISTINCTキーワード **遂に!ようやく!**
  * 複数列ソート用の複合インデックス
  * EXISTSおよびARRAY式を含む相関サブクエリ

* [Notebook support for all Azure Cosmos DB APIs is in preview](
https://azure.microsoft.com/en-us/updates/notebook-support-for-all-azure-cosmos-db-apis-is-in-preview/)
  * 実はまだPrivatePreview
  * ↓みたいに新規作成時に申し込めます。(2週間たってもwaitlist)
  * NotebookだけとSpark with でどう違うんだろう。早く試したい…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260166/613658ae-5a8a-9da4-eb52-389c9bc1692e.png)


## その他CosmosDBの更新情報
https://azure.microsoft.com/ja-jp/updates/?product=cosmos-db

## Azure Function CosmosDB Binding関連
### [GitHub Azure/azure-webjobs-sdk-extensions Adding support for Partitioned Lease collections and monitoring #520](https://github.com/Azure/azure-webjobs-sdk-extensions/pull/520)(2019/1ごろ)


いままでLeaseコレクションにUnlimited(partitioned)コレクションが指定できなかった
＃自動で作成する場合 Fixedコレクションの400RUが指定されてた
＃手動で作成する場合、トリガの開始時にエラーが起きてた
⇒**パーティションキー＝"/id"なUnlimited(partitioned)コレクションを指定できるように。**

つまり、
いままで、CosmosDBTriggerなFunctionを使おうとした場合、
読み取り元のコレクション(最小400RU/s)+リースコレクション(最小400RU/s)で
800RU/s(5000円強/月)だったのが、Databaseに400RU/s割り当てだけで始められるようになった！


[nuget Microsoft.Azure.WebJobs.Extensions.CosmosDB 3.0.3](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.CosmosDB/3.0.3)

### [GitHub Azure/azure-webjobs-sdk-extensions Enabling Multi Master for leases in Cosmos DB Trigger #566](https://github.com/Azure/azure-webjobs-sdk-extensions/pull/566)(そろそろ？)
⇒3.0.4
マルチマスターのChangeFeedってどういう動きなんでしたっけ(…?)

# Build(と5/15のアナウンスで)発表された、ARMテンプレートの強化を試す

## 既存の公開情報
[GitHub Azure/azure-rest-api-specs(CosmosDB)](https://github.com/Azure/azure-rest-api-specs/blob/master/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/stable/2015-04-08/cosmos-db.json)
[GitHub Azure/azure-resource-manager-schemas(CosmosDB)](https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2015-04-08/Microsoft.DocumentDB.json)
[Docs Microsoft.DocumentDB resource types](https://docs.microsoft.com/ja-jp/azure/templates/microsoft.documentdb/allversions)


## ARMテンプレートを試す

CosmosDBTriggerなFunctionが400RU/sだけで動かせるよう、
CosmosDBアカウント,データベースレベルのスループット割り当て(400RU/s),コレクション２個を作ります。
東日本のリソースグループにデプロイ、西日本はRead専用にします。
  

```json:CosmosDB-Template.json
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {
        "cosmos": {
            "accountName": "cosmos-sql-201905-3",
            "locations": [
                "[resourceGroup().location]",
                "japanwest"
            ],
            "database": {
                "name": "database",
                "throughput": 400
            },
            "containers": [
                {
                    "Name": "container",
                    "PartitionKey": "/pk"
                },
                {
                    "Name": "leases",
                    "PartitionKey": "/id"
                }
            ]
        }
    },
    "resources": [
        {
            "type": "Microsoft.DocumentDB/databaseAccounts",
            "apiVersion": "2016-03-31",
            "name": "[variables('cosmos').accountName]",
            "location": "[variables('cosmos').locations[0]]",
            "kind": "GlobalDocumentDB",
            "properties": {
                "consistencyPolicy": {
                    "defaultConsistencyLevel": "Session"
                },
                "copy": [
                    {
                        "name": "locations",
                        "count": "[length(variables('cosmos').locations)]",
                        "input": {
                            "failoverPriority": "[copyIndex('locations')]",
                            "locationName": "[variables('cosmos').locations[copyIndex('locations')]]"
                        }
                    }
                ],
                "databaseAccountOfferType": "Standard",
                "enableAutomaticFailover": false,
                "enableMultipleWriteLocations": false
            }
        },
        {
            "type": "Microsoft.DocumentDB/databaseAccounts/apis/databases",
            "apiVersion": "2016-03-31",
            "name": "[concat(variables('cosmos').accountName,'/sql/',variables('cosmos').database.name)]",
            "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/', variables('cosmos').accountName)]"
            ],
            "properties": {
                "resource": {
                    "id": "[variables('cosmos').database.name]"
                },
                "options": {
                    "throughput": "[variables('cosmos').database.throughput]"
                }
            }
        },
        {
            "type": "Microsoft.DocumentDb/databaseAccounts/apis/databases/containers",
            "apiVersion": "2016-03-31",
            "name": "[concat(variables('cosmos').accountName,'/sql/',variables('cosmos').database.name,'/',variables('cosmos').containers[copyIndex()].name)]",
            "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/apis/databases', variables('cosmos').accountName, 'sql', variables('cosmos').database.name)]"
            ],
            "properties": {
                "resource": {
                    "id": "[variables('cosmos').containers[copyIndex()].name]",
                    "partitionKey": {
                        "paths": [
                            "[variables('cosmos').containers[copyIndex()].partitionKey]"
                        ],
                        "kind": "Hash"
                    },
                    "indexingPolicy": {
                        "indexingMode": "consistent",
                        "includedPaths": [
                            {
                                "path": "/*",
                                "indexes": [
                                    {
                                        "kind": "Range",
                                        "dataType": "Number",
                                        "precision": -1
                                    },
                                    {
                                        "kind": "Range",
                                        "dataType": "String",
                                        "precision": -1
                                    },
                                    {
                                        "kind": "Spatial",
                                        "dataType": "Point"
                                    }
                                ]
                            }
                        ],
                        "excludedPaths": [
                            {
                                "path": "/\"_etag\"/?"
                            }
                        ]
                    }
                }
            },
            "copy": {
                "name": "containers-loop",
                "count": "[length(variables('cosmos').containers)]"
            }
        }
    ]
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260166/a6a70d14-9ac0-13e2-7dad-ff5946341020.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260166/e84d584e-0812-b05a-10c5-9088874f9e0e.png)

いままで、ARMテンプレートデプロイ⇒コレクション作成⇒FunctioAppPublishだったのが、
ARMテンプレートデプロイ⇒FunctionAppPublishとシンプルになりました。

### Tips
* Microsoft.DocumentDB/databaseAccountsのproperties.locations.locationName

ARM REST APIなどでは`Japan East`とかDisplayNameですが、`japaneast`等のLocationNameで指定してもうごくっぽい。
ドキュメント外な動作だと思うので、だめになったらダサいけど↓みたいなvariables追加して置き換えるとよいと思う。

```json:variables
    "locationNames": {
      "eastasia": "East Asia",
      "southeastasia": "Southeast Asia",
      "centralus": "Central US",
      "eastus": "East US",
      "eastus2": "East US 2",
      "westus": "West US",
      "northcentralus": "North Central US",
      "southcentralus": "South Central US",
...
    }
```

# おわりに
あとはStorage QueueがARMテンプレートからできれば、だいたい自分のよく使うリソースほぼテンプレート化できそうなんですが。





# 参考
[Creating Cosmos DB Resources using ARM Templates](https://samcogan.com/creating-cosmos-db-resources-using-arm-templates/)
[ARM template support for Cosmos DB databases and collections &#8211; Henry Been](https://www.henrybeen.nl/arm-template-support-for-cosmos-db-databases-and-collections/)