Azure SQL データベースのスケールアウトについて

# はじめに
## ことの発端
今のお仕事の案件でAzureSQLデータベース（以降AzureDB）を使用しているのですが、データベースの使用率が70%を超え始めたのでデータをスケールアウト出来ないか？と言うお話しが浮上しました。


## Azureって？
Azureはマイクロソフト社が提供しているクラウドサービスになります。
仮想サーバの作成等をWEB（Azureポータル）上からポチポチ作る事ができます。

その中でAzureDBはその名の通りデータベースサーバになります。
中身は「SQLServer」なので「SQL Server Management Studio」を使用して接続・データの確認を行います。


## DBの要領を増やす方法
AzureDBの要領を増やす場合はAzureのポータルサイトから作成したAzureDBを選択して「価格レベルの変更」から増やす事ができます。
俗に言うスケールアップです。

マイクロソフト社のドキュメントを確認すると「どんどん要領増やせますよ」みたいな図があります。
![single_db_dtus.png](https://qiita-image-store.s3.amazonaws.com/0/223359/22784ce5-f005-9330-62e1-ede84c01bc90.png)

- 価格表抜粋

| 価格レベル |  DTU  |最大ストレージ |    最大料金    |
|:---------|-------:|-----------:|:-------------:|
| B        |      5 |        2G |   ~¥565.90/月 |
| S0       |     10 |      250G |   ~¥1,701.10/月 |
| P1       |    125 |        1T |     ~¥52,731.45/月 |
| P6       |  1,000 |        1T |     ~¥421,851.60/月 |
| P15      |  4,000 |        4T |  ~¥1,817,471.09/月 |
※ DTUとはざっくりサーバスペックを数値化したものと思ってください。

- 他の価格帯はこちらを参照ください  
[SQL Database の価格](https://azure.microsoft.com/ja-jp/pricing/details/sql-database/)

表を見ても分かる通りいくら最大４T使えるとは言え、月に200万近くのお金は出せないのでスケールアウトをすることになりました。


## スケールアウト
AzureDBももちろんスケールアウトは行なえます。
これはいきなり月200万近くもお金を出すのは無理！少しずつ増やして行こうよ。という場合にとても便利です。
たとえば同じ4Tを使いたい場合、スケールアウト先のスペックは高くなくて良ければ

```
P1*3(52,731.45*3) + P6*1(421,851.60*1) = 580,045.95円
```
となるのでP15単体で使用するよりも安く済むことが分かります。（マイクロソフトさんすみません）



# 実際スケールアウトのするにはどうすればよいのか？
## マイクロソフト公式のドキュメントを確認
**[シャード マップ マネージャーでデータベースをスケールアウトする](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-elastic-scale-shard-map-management)**

を確認するとJavaやC#のコードが書かれており「ふむふむ。この言語で出来るのか」となると思うのですが、シャードマップマネージャの作成方法が以下から確認すると

**[既存のデータベースを移行してスケール アウト](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-elastic-convert-to-use-elastic-tools)**

なんとPowerShellでサンプルコードが書かれています。
概要では**「JavaやC#を使って書けるよ！」**と言っておきながらサンプルコードは**「PowerShellでこうやるんだよ！」**と書かれていました…

正直どうしようか悩みましたが、私はサンプルコードが無いと不安になるので一先ず**PowerShell**で作業を進めることにしました。


## スケールアウトするのに必要なモノ
まずスケールアウトに必要なモノについてですが、

- スケールアウトを行うDB
- ShardMapManager用のDB
- スケールアウト先に設定するDB

の３つになります。
「スケールアウトを行うDB」は現在使用しているモノで良いのですが、それとは別にDBが（最低）2つ必要になりますので気をつけてください。


## ShardMapManagerの作成
MSから提供されているサンプルファイルを修正して「ShardMapManager」作成用のPowerShellファイルを作成します。

### １．サンプルスクリプトのダウンロード
以下URLから「Elastic DB tool scripts.zip」をダウンロードします。
https://gallery.technet.microsoft.com/scriptcenter/Azure-SQL-DB-Elastic-731883db

### ２．ZIPファイルを展開
ダウンロードしたZIPファイルを任意の場所に移動して展開します。
例）¥Documents¥work

### ３．スクリプトの作成
展開したフォルダの中にある「GetMappings.ps1」をコピーして「CreateShardMapManager.ps1」と言うファイルを作成します。

### ４．不要な行の削除
検索から「PowerShell」を検索し「Windows PowerShell ISE」を起動します。
ツールが起動したらファイルを開くから先ほど作成した「CreateShardMapManager.ps1」を開きます。

ファイル内の「Import modules」までを残して以降を削除します。（37行目あたり）

````powershell:CreateShardMapManager.ps1
param (
    [parameter(Mandatory=$true)][string]$UserName,
    [parameter(Mandatory=$true)][string]$Password,
    [parameter(Mandatory=$true)][string]$ShardMapManagerServerName,
    [parameter(Mandatory=$true)][string]$ShardMapManagerDatabaseName,
    [parameter(Mandatory=$true)][string]$ShardMapName
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

# Import modules
$ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path
Import-Module $ScriptDir\ShardManagement -Force

-- ここから下を全行削除します --
# Create new (or replace existing) shard map manager 
$ShardMapManager = Get-ShardMapManager -UserName $UserName -Password $Password -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardMapManagerDatabaseName

$ShardMap = $ShardMapManager.GetShardMap($ShardMapName);

# Get shard map
````
→ ここでインポートしているモジュールを使用してShardMapの操作を行います。
　　「param」内の「$ShardMapName」も削除してOKです。

### ５．コードの追加
モジュールインポート後にShardMapManager作成の処理を記載します。

````powershell:CreateShardMapManager.ps1
param (
    [parameter(Mandatory=$true)][string]$UserName,
    [parameter(Mandatory=$true)][string]$Password,
    [parameter(Mandatory=$true)][string]$ShardMapManagerServerName,
    [parameter(Mandatory=$true)][string]$ShardMapManagerDatabaseName
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

# Import modules
$ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path
Import-Module $ScriptDir\ShardManagement -Force

-- 以下追加した行です --
# Create new shard map manager
$ShardMapManager = New-ShardMapManager -UserName $UserName -Password $Password -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardMapManagerDatabaseName
````
→ 「SqlDatabaseName」で指定したDataBaseを「ShardMapManager」として作成します。

### ６．スクリプトの実行
修正したPowerShellのファイルを実行後すると「ShardMapManager」にしていしたDBにテーブルが作成されます。
テーブルは「__ShardManagement.xxxx」と言う名前で６個作成されます。


## ShardMapの作成
作成した「ShardMapManager」に「ShardMap」を作成します。
「ShardMap」はデータの管理方法（範囲指定「RangeShardMap」なのか値指定「ListShardMap」なのか）を管理しています。
また「ShardMap」は分割する値（KeyType）の型も管理しています。

「RangeShardMap」「ListShardMap」って何？と言うのはこちらに記載があります。
[シャード マップとシャードのマッピング](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-elastic-scale-shard-map-management#shard-maps-and-shard-mappings)

連番等のIDでデータのスケールアウトを行う場合は「RangeShardMap」を使用し
地域コードなど固定値でスケールアウトを行う場合は「ListShardMap」を使用した方が良いと思います。


### １．スクリプトの作成
先ほどダウンロードしたフォルダの中にある「GetMappings.ps1」をコピーして「CreateRangeShardMap.ps1」を作成します。


### ２．不要な行の削除
先ほどと同様にファイル内の「Create new (or replace existing) shard map manager （41行目）」までを残して以降を削除します。

```powershell:CreateRangeShardMap.ps1
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

# Import modules
$ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path
Import-Module $ScriptDir\ShardManagement -Force

# Create new (or replace existing) shard map manager 
$ShardMapManager = Get-ShardMapManager -UserName $UserName -Password $Password -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardMapManagerDatabaseName

-- ここから下の全行を削除します --
$ShardMap = $ShardMapManager.GetShardMap($ShardMapName);

# Get shard map
If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) {
    $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName
}
```
→ 「Get-ShardMapManager」で先ほど作成した「ShardMapManager」を使用できる状態にしています。


### ３．コードの追加
DBを管理する「ShardMap」を作成します。

- 範囲マッピングを作成する場合は以下コードを追加します。

```powershell:CreateRangeShardMap.ps1
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

# Import modules
$ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path
Import-Module $ScriptDir\ShardManagement -Force

# Create new (or replace existing) shard map manager 
$ShardMapManager = Get-ShardMapManager -UserName $UserName -Password $Password -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardMapManagerDatabaseName

-- 以下追加した行です --
# 'RangeShardMap' is the unique identifier for the range shard map.  
$ShardMap = New-RangeShardMap -KeyType $([int]) -RangeShardMapName $ShardMapName -ShardMapManager $ShardMapManager
```
　→ テーブル「ShardMapsGlobal」以下にシャードマップのデータが登録されます。

- リストマッピングを作成する場合は以下コードを追加します。

```powershell:CreateRangeShardMap.ps1
# $ShardMapManager is the shard map manager object.
$ShardMap = New-ListShardMap -KeyType $([int]) -ListShardMapName $ShardMapName -ShardMapManager $ShardMapManager
```
　→ テーブル「ShardMapsGlobal」以下にシャードマップのデータが登録されます。

- keyType:指定値  
　1:int  
　2:long  
　3:guid  
　4:byte[]  
　5:datetime  
　6:timespan  
　7:datetimeoffset  


### ４．スクリプトの実行
修正したスクリプトを実行するとテーブル「__ShardManagement.ShardMapsGlobal」にデータが追加されます。



## DB（Shard）の追加
作成した「ShardMap」にDBの追加を行います。
データの移動元、移動先両方のDBを登録する必要があります。

### １．スクリプトの作成
「ShardMapManager」を作成した際にダウンロードしたフォルダの中の「GetMappings.ps1」をコピーして「AddShardToSMM.ps1」を作成します。


### ２．引数の追加
追加するDB（Shard）を引数指定出来るように「ShardMapName」の下に「ShardDatabaseName」を追加します。

```powershell:AddShardToSMM.ps1
param (
    [parameter(Mandatory=$true)][string]$UserName,
    [parameter(Mandatory=$true)][string]$Password,
    [parameter(Mandatory=$true)][string]$ShardMapManagerServerName,
    [parameter(Mandatory=$true)][string]$ShardMapManagerDatabaseName,
    [parameter(Mandatory=$true)][string]$ShardMapName,
    [parameter(Mandatory=$true)][string]$ShardDatabaseName     # 追加行
)
```

### ３．シャードマップ取得処理の修正
シャードマップの取得が出来なかった際にメッセージを出力する記述になっていますが、処理は終了しないので以下コードを追加して処理を終了するようにします。

```powershell:AddShardToSMM.ps1
# Get shard map
If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) {
    $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName
} ElseIf ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::Range)) {
    $ShardMap = Get-RangeShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -RangeShardMapName $ShardMapName
} Else {
    Write-Error "Invalid Shard Map Type"
    exit 1    # 追加行
}
```

### ４．シャード（DB）をシャードマップに追加する処理を追記
シャードマップ取得の処理後に「Get mappings」の処理を削除して、シャード追加の処理を記載します。（62行目あたり）

```powershell:AddShardToSMM.ps1
# Get shard map
If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) {
    $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName
} ElseIf ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::Range)) {
    $ShardMap = Get-RangeShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -RangeShardMapName $ShardMapName
} Else {
    Write-Error "Invalid Shard Map Type"
    exit 1
}

-- 以下追加した行です --
# Add shard to ShardMap
Add-Shard -ShardMap $ShardMap -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardDatabaseName
```


### ５．スクリプトの実行
修正したスクリプトを実行するとシャードマップマネージャのテーブル「ShardsGlobal」にシャード（DB）情報が追加されます。
追加したDBにも「__ShardManagement.xxx」のテーブルが４つ追加されます。



## シャードにマッピング情報を追加
作成した「ShardMap」にKeyの範囲指定を行います。
「ShardMap」毎に設定が必要になります。

### １．スクリプトの作成
DB（Shard）の追加で作成した「AddShardToSMM.ps1」をコピーして「AddShardToMapping.ps1」を作成します。


### ２．不要な行の削除
ShardMap追加の処理を削除します。

```powershell:AddShardToMapping.ps1
# Get shard map
If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) {
    $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName
} ElseIf ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::Range)) {
    $ShardMap = Get-RangeShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -RangeShardMapName $ShardMapName
} Else {
    Write-Error "Invalid Shard Map Type"
    exit 1
}

-- ここから下の全行を削除します --
# Add shard to ShardMap
Add-Shard -ShardMap $ShardMap -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardDatabaseName
```


### ３．ShardにKeyの範囲指定を登録する処理を追加
作成したShardにKeyの範囲指定を行う処理を追加します。

```powershell:AddShardToMapping.ps1
# Get shard map
If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) {
    $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName
} ElseIf ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::Range)) {
    $ShardMap = Get-RangeShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -RangeShardMapName $ShardMapName
} Else {
    Write-Error "Invalid Shard Map Type"
    exit 1
}

-- 以下追加した行になります --
# Create the mappings and associate it with the new shards 
Add-RangeMapping -KeyType $([int]) -RangeHigh '200' -RangeLow '0' -RangeShardMap $ShardMap -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardDatabaseName
```


### ４．スクリプトの実行
修正したスクリプトを実行するとシャードマップマネージャのテーブル「ShardMappingsGlobal」にShardの情報とKeyの下限・上限の情報が登録されます。



## ShardMapにShardingKey（カラム）を登録
作成した「ShardMap」に「Shardkey」にするテーブルのカラムを登録します。


### １．スクリプトの作成
「AddShardToSMM.ps1」をコピーして「AddSchemaToShardMap.ps1」を作成します。


### ２．引数の設定の修正
「ShardDatabaseName」の記述を削除して以下パラメータを追加します。

```powershell:AddSchemaToShardMap.ps1
param (
    [parameter(Mandatory=$true)][string]$UserName,
    [parameter(Mandatory=$true)][string]$Password,
    [parameter(Mandatory=$true)][string]$ShardMapManagerServerName,
    [parameter(Mandatory=$true)][string]$ShardMapManagerDatabaseName,
    [parameter(Mandatory=$true)][string]$ShardMapName,
    [parameter(Mandatory=$true)][string]$ShardDatabaseName  # 削除
    [parameter(Mandatory=$true)][string]$TableName,         # 追加
    [parameter(Mandatory=$true)][string]$KeyName            # 追加
)
```


### ３．ShardingKeyに設定するカラムをセット
「Add shard to ShardMap」の処理を削除して以下コードに書き換えます。

```powershell:AddSchemaToShardMap.ps1
# Get shard map
If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) {
    $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName
} ElseIf ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::Range)) {
    $ShardMap = Get-RangeShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -RangeShardMapName $ShardMapName
} Else {
    Write-Error "Invalid Shard Map Type"
    exit 1
}

-- この行は削除します --
# Create the mappings and associate it with the new shards 
Add-RangeMapping -KeyType $([int]) -RangeHigh '200' -RangeLow '0' -RangeShardMap $ShardMap -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardDatabaseName

-- 以下行を追加します --
# Create SchemaInfo for our tables
$SchemaInfo = New-Object Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Schema.SchemaInfo
$SchemaInfo.Add($(New-Object Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Schema.ShardedTableInfo($TableName, $KeyName)))
$SchemaInfoCollection = $ShardMapManager.GetSchemaInfoCollection()
```


### ４．ShardingKeyの登録
「ShardMapManager」に「Shardkey」の情報を登録する処理を追加します。

```powershell:AddSchemaToShardMap.ps1
# Create SchemaInfo for our tables
$SchemaInfo = New-Object Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Schema.SchemaInfo
$SchemaInfo.Add($(New-Object Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Schema.ShardedTableInfo($TableName, $KeyName)))
$SchemaInfoCollection = $ShardMapManager.GetSchemaInfoCollection()

-- 以下行を追加します --
# Add the SchemaInfo for this Shard Map to the Schema Info Collection
if ($($SchemaInfoCollection | Where Key -eq $ShardMapName) -eq $null) {
    $SchemaInfoCollection.Add($ShardMapName, $SchemaInfo)
} else {
    $SchemaInfoCollection.Replace($ShardMapName, $SchemaInfo)
}
```



# スケールアウトの実行
## 実行の準備
ここまで読んでいただいてありがとうございます。
ここまで読んでやっと実行なのか、と思った方もいるかと思いますが、まだ少し設定が必要になります。（もう少しお付き合いください）

公式ドキュメントは
[split-merge サービスのデプロイ](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-elastic-scale-configure-deploy-split-and-merge)
になりますのでこちらを見ながらでも作業は行なえます。



## 分割統合パッケージのダウンロード
### １．NuGetから最新のNuGetバージョンをダウンロードします
コマンドプロンプトを開き、nuget.exe をダウンロードしたディレクトリに移動します。
例）C:\Users\hoge\Documents\WindowsPowerShell\nuget


### ２．パッケージのダウンロード
コマンドプロンプトで以下コマンドを実行して最新の Split-Merge パッケージを現在のディレクトリにダウンロードします。

```
nuget install Microsoft.Azure.SqlDatabase.ElasticScale.Service.SplitMerge
```

ファイルは、Microsoft.Azure.SqlDatabase.ElasticScale.Service.SplitMerge.x.x.xxx.x という名前のディレクトリに配置されます。x.x.xxx.x はバージョン番号です。
「content\splitmerge\service」サブディレクトリにSplit-Mergeサービスファイル、「content\splitmerge\powershell」サブディレクトリにSplit-MergePowerShellスクリプト (および必要なクライアント .dll) が格納されています。



## 分割統合パッケージを使用するための準備
### １．統合分割のステータスを管理するDBを作成
Azureポータルにアクセスしスケールアウトを行うリソースグループにアクセスします。
「追加」から新しいDBを作成します。
作成したDBのユーザ名、パスワードは控えておいてください。


### ２．SQLServerのFirewallsの設定を変更
Azureポータルから「SQLServer」にアクセスします。
（SQLデータベースではないので注意してください）
Firewalls設定画面で「Azureサービスへの接続許可」を「ON」にします。
アクセスを許可するIPアドレスの登録を行います。


### ３．AzureStorageを作成
診断の出力時に使用するAzureStorageアカウントを作成します。
Azureポータルより「新規」→「Storage」→「StorageAccount」を選択します。
「名前」「リソースグループ」を選択します。
「レプリケーション」は「Local」を選択します。
その他の項目についてはデフォルトでOKです。
「作成」をクリックするとAzureStorageアカウントが作成されます。


### ４．クラウドサービスの作成
WEBからスケールアウトを行う為のクラウドサーバを作成します。

「新規」→「Compute」→「クラウドサービス」を選択します。
「クラウドサービス」がない場合は検索窓から「cloud」で検索を行うと見つかります。
「名前」「リソースグループ」を選択します。
オプションは変更せずに「作成」をクリックするとクラウドサーバが作成されます。



## Split-Merge サービスの構成
### １．コンフィグファイルの作成
分割統合ツールをダウンロードしたディレクトリ以下に移動します。
例）C:\Users\hoge\Documents\WindowsPowerShell\nuget\Microsoft.Azure.SqlDatabase.ElasticScale.Service.SplitMerge.1.2.0\content\splitmerge\service

テンプレートファイルをコピーしてコンフィグファイルを作成します。
コピー元：ServiceConfiguration.Template.cscfg
コピー先：ServiceConfiguration.cscfg


### ２．コンフィグファイルの編集
「ServiceConfiguration.cscfg」ファイルをVisualStudioで開いて以下項目を編集します。

- ElasticScaleMetadata
「準備」で作成した統合分割のステータスを管理するDBの情報を記載します。
　→ 「.NET」用の接続用文字列をコピーしてそのまま貼り付ける

- WorkerRoleSynchronizationStorageAccountConnectionString
「準備」で作成したStrageServiceの情報を記載します
　→ 「AccessKey」から「ConnectionStrings」の値をコピーして貼り付けます。

```XML:ServiceConfiguration.cscfg
<Role name="SplitMergeWorker”>
    <ConfigurationSettings>
        ・・・
        <Setting name="WorkerRoleSynchronizationStorageAccountConnectionString" value="DefaultEndpointsProtocol=https;AccountName=;AccountKey=" />
        <Setting name="ElasticScaleMetadata" value="Server=;Database=;User ID=;Password=;" />
        ・・・
<Role name="SplitMergeWeb”>
    <ConfigurationSettings>
        ・・・
        <Setting name="ElasticScaleMetadata" value="Server=;Database=;User ID=;Password=;" />
        ・・・
```



## セキュリティの構成
### １．自己署名証明書の作成
スタートメニューから「VisualStadio 2017」内の「開発者コマンドプロンプト」を起動します。
証明書を保存するディレクトリに移動して以下コマンドを実行します。

```console
makecert ^
-n "CN=*.cloudapp.net" ^
-r -cy end -sky exchange -eku "1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2" ^
-a sha1 -len 2048 ^
-sr currentuser -ss root ^
-sv MyCert.pvk MyCert.cer
```

### ２．PFX ファイルの作成
証明書を作成したディレクトリでコマンドプロンプトから以下コマンドを実行します。
パスワードは証明書と同じパスワードを入力します。

```console
pvk2pfx -pvk MyCert.pvk -spc MyCert.cer -pfx MyCert.pfx -pi <password>
```


### ３．証明書のインポート
作成した証明書「MyCert.pfx」をダブルクリックしてインポートウィザードを起動します。
保存場所に「現在のユーザ」を選択して次へをクリックします。
以降デフォルトのまま完了まで進みます。


### ４．クラウド サービスへの PFX ファイルのアップロード
Azureにアクセスして作成したクラウドサーバを選択します。
メニューから設定内の「証明書」をクリックして、作成した証明書「MyCert.pfx」をアップロードします。


### ５．コンフィグファイルの修正
サービスの構成で修正したファイルに登録した証明書のサムプリントを記入します。
サムプリントはAzureポータルの署名書から確認できます。
![スクリーンショット 2018-01-09 15.25.47.png](https://qiita-image-store.s3.amazonaws.com/0/223359/cfaf5b8f-abe1-367a-ceaa-ae09e73d669f.png)

```XML:ServiceConfiguration.cscfg
<Role name="SplitMergeWorker”>
    <ConfigurationSettings>
        ・・・
　　<Setting name="DataEncryptionPrimaryCertificateThumbprint" value="｛ここにサムプリントの値を記載｝" />
　　<Certificate name="DataEncryptionPrimary" thumbprint="｛ここにサムプリントの値を記載｝" thumbprintAlgorithm="sha1" />
        ・・・
<Role name="SplitMergeWeb”>
    <ConfigurationSettings>
        ・・・
　　<Setting name="AdditionalTrustedRootCertificationAuthorities" value="｛ここにサムプリントの値を記載｝" />
　　<Setting name="AllowedClientCertificateThumbprints" value="｛ここにサムプリントの値を記載｝" />
　　<Setting name="DataEncryptionPrimaryCertificateThumbprint" value="｛ここにサムプリントの値を記載｝" />
        ・・・
　　<Certificate name="SSL" thumbprint="｛ここにサムプリントの値を記載｝" thumbprintAlgorithm="sha1" />
　　<Certificate name="CA" thumbprint="｛ここにサムプリントの値を記載｝" thumbprintAlgorithm="sha1" />
　　<Certificate name="DataEncryptionPrimary" thumbprint="｛ここにサムプリントの値を記載｝" thumbprintAlgorithm="sha1" />
```


### ６．サービスのデプロイ
Azureにアクセスして作成したクラウドサーバを選択します。
環境を「ステージング」に変更して「アップロード」をクリックします。
![スクリーンショット 2018-01-09 16.50.27.png](https://qiita-image-store.s3.amazonaws.com/0/223359/c4b91673-bdf6-7403-07b6-8a5b51fd9fd1.png)

以下内容を記入・アップロードして「OK」をクリックします。

- ラベル：initial upload of Split-Merge service
- ストレージ：作成したストレージ環境
- パッケージ：SplitMergeService.cspkg
- コンフィグ：ServiceConfiguration.cscfg
- チェックボックス：２つともチェック


### ７．WEBからサービスの確認
ストレージに表示されているURLをコピーして「HTTPS」でWEBアクセスします。
WEBからデータの分割統合が出来るようになります