我们有一个业务需求,我们必须在AzureDevOps内部的CD步骤中创建数据库和集合。据我的研究表明,这不可能通过ARM来完成。
MS的支持票证确认这在ARM中是不可能的,必须在您的应用程序内完成。如前所述,业务需求阻止我们这样做。
基本选项是通过编程方式或Cosmos Db的REST API。
答案 0 :(得分:1)
我最终使用PowerShell脚本完成了这项工作! 在this和this帖子的帮助下,我得以上手-他们特别为身份验证令牌提供了帮助。
然后,我在Cosmos Db SQL REST API上引用了MS文档:Create Database和Create Collection
这是我的PS脚本(在发布时在AzureDevOps / VSTS中工作):
param($endpoint, $masterKey, $databaseName, $collectionName, $collectionRUs)
Add-Type -AssemblyName System.Web
Add-Type -TypeDefinition @"
public enum CosmosResourceType
{
Database,
Collection
}
"@
Function Create-Resource
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$endPoint,
[Parameter(Mandatory=$true)][String]$masterKey,
[Parameter(Mandatory=$true)][String]$dataBaseName,
[Parameter(Mandatory=$true)][String]$collectionName,
[Parameter(Mandatory=$true)][CosmosResourceType]$cosmosResourceType
)
$verb = "POST";
$resourceType = "dbs";
$resourceLink = "dbs";
$header = "";
$idValue = "";
$contentType = "application/json";
$queryUri = "$endPoint$resourceLink"
if($cosmosResourceType -eq "Database")
{
$header = Generate-Headers -verb $verb -resourceType $resourceType -key $masterKey
$idValue = $dataBaseName
}
elseif($cosmosResourceType -eq "Collection")
{
$resourceType = "colls";
$resourceLink = "dbs/$dataBaseName"
$header = Generate-Headers -verb $verb -resourceType $resourceType -resourceLink $resourceLink -key $masterKey
# Not sure why but at this moment Cosmos Db ignores this setting
$header | Add-Member -Name 'x-ms-offer-throughput' -Type NoteProperty -Value $collectionRUs
$idValue = $collectionName
$queryUri = "$endPoint$resourceLink/colls"
}
else
{
Write-Host "Invalid Cosmos Resource Type:"$cosmosResourceType -ForeGroundColor Red
}
$jsonDoc = [pscustomobject]@{ id = $idValue }
$jsonDoc = $jsonDoc | ConvertTo-Json
$response = InvokeRest -verb $Verb -ContentType $contentType -uri $queryUri -headers $header -body $jsonDoc
if($response.code.ToLowerInvariant() -eq "Conflict".ToLowerInvariant())
{
Write-Host "Warning: $cosmosResourceType already existing" -ForeGroundColor Yellow
}
elseif($response.code.ToLowerInvariant() -eq "Ok".ToLowerInvariant())
{
Write-Host "$cosmosResourceType Created" -ForeGroundColor Green
}
else
{
Write-Host "response:"$response -ForeGroundColor Red
}
}
Function InvokeRest
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]$verb,
[Parameter(Mandatory=$true)]$contentType,
[Parameter(Mandatory=$true)]$uri,
[Parameter(Mandatory=$true)]$headers,
[Parameter(Mandatory=$false)]$body
)
Try {
$result = Invoke-RestMethod -Method $Verb -ContentType $contentType -Uri $uri -Headers $headers -Body $body
Write-Host "InvokeRest: "$result -ForeGroundColor Green
$response = [pscustomobject]@{
code = "OK"
body = $result
}
return $response
}
Catch {
# Check if there is a response.
if ($_.Exception.Response -eq $null) {
$expMessage = $_.Exception.Message
$failedItem = $_.Exception.Source
$line = $_.InvocationInfo.ScriptLineNumber
Write-Host "At $($line):`r`n$expMessage `r`n$failedItem" -ForeGroundColor Red
throw $_.Exception
}
else {
# Get the response body with more error detail.
$respStream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($respStream)
$response = $reader.ReadToEnd() | ConvertFrom-Json
return $response
}
}
}
Function Generate-Headers
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$verb,
[Parameter(Mandatory=$false)][String]$resourceLink,
[Parameter(Mandatory=$true)][String]$resourceType,
[Parameter(Mandatory=$true)][String]$key
)
$dateTime = [DateTime]::UtcNow.ToString("r")
$authHeader = Generate-MasterKeyAuthorizationSignature -verb $verb -resourceLink $resourceLink -resourceType $resourceType -key $masterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
Write-Host $authHeader
$header = @{authorization=$authHeader;"x-ms-version"="2017-02-22";"x-ms-date"=$dateTime}
return $header
}
Function Generate-MasterKeyAuthorizationSignature
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$verb,
[Parameter(Mandatory=$false)][String]$resourceLink,
[Parameter(Mandatory=$true)][String]$resourceType,
[Parameter(Mandatory=$true)][String]$key,
[Parameter(Mandatory=$true)][String]$keyType,
[Parameter(Mandatory=$true)][String]$tokenVersion,
[Parameter(Mandatory=$true)][String]$dateTime
)
$hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
$hmacSha256.Key = [System.Convert]::FromBase64String($key)
$payLoad = Generate-Payload -verb $verb -resourceLink $resourceLink -resourceType $resourceType -dateTime $dateTime
$hashPayLoad = $hmacSha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($payLoad))
$signature = [System.Convert]::ToBase64String($hashPayLoad);
[System.Web.HttpUtility]::UrlEncode("type=$keyType&ver=$tokenVersion&sig=$signature")
}
Function Generate-Payload
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$verb,
[Parameter(Mandatory=$false)][String]$resourceLink,
[Parameter(Mandatory=$true)][String]$resourceType,
[Parameter(Mandatory=$true)][String]$dateTime
)
$payLoad = ""
if ( [string]::IsNullOrEmpty($resourceLink) )
{
$payLoad = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n`n$($dateTime.ToLowerInvariant())`n`n"
}
else
{
$payLoad = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n$resourceLink`n$($dateTime.ToLowerInvariant())`n`n"
}
return $payLoad
}
# Create Database
$cosmosResourceType = [CosmosResourceType]::Database
Create-Resource -endPoint $endpoint -masterKey $masterKey -dataBaseName $databaseName -collectionName $collectionName -cosmosResourceType $cosmosResourceType
# Create Collection
$cosmosResourceType = [CosmosResourceType]::Collection
Create-Resource -endPoint $endpoint -masterKey $masterKey -dataBaseName $databaseName -collectionName $collectionName -cosmosResourceType $cosmosResourceType
希望这对其他人有帮助。