通过 Azure 资源管理器 (ARM) 模板创建 SQL Server

Posted

技术标签:

【中文标题】通过 Azure 资源管理器 (ARM) 模板创建 SQL Server【英文标题】:Create SQL Server via Azure Resource Manager (ARM) template 【发布时间】:2019-01-26 11:50:04 【问题描述】:

我正在尝试创建一个新的 SQL Server Azure 实例,然后我想在其中创建一些新数据库。

我从 Azure 门户了解到,某些管理员用户可能是:

一个 SA 用户(我认为这意味着“服务器管理员”,它看起来像是管理 SQL Server 实例的某种旧方式,但同时非常“基本”并证明工作) 一个 Active Directory 用户(不确定这里的 Azure 术语,但看起来这可能是整个 Azure 平台的一些“广泛用户”,例如我自己的 Azure 门户登录用户,这不是特定于数据库世界)。

我想创建一个带有 SA 用户的 SQL Server 来管理服务器。 在 Azure 门户中,我找不到为 SQL Server 实例的 SA 用户生成 ARM 模板的方法

我正在从一个 10000 行的 ARM 模板复制粘贴一个很长的 SQL 服务器和数据库列表,但我无法隔离基本步骤来获得一个希望干净且简短的 ARM 模板。

这是我尝试在 Azure 上部署的 ARM 模板:


    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": 
      "location": 
          "type": "string",
          "defaultValue": "westeurope"
        ,
      "foo_sql_server_name": 
          "defaultValue": "foo-sql-server",
          "type": "String"
      
    ,
    "resources": [
      
          "type": "Microsoft.Sql/servers",
          "kind": "v12.0",
          "name": "[parameters('foo_sql_server_name')]",
          "apiVersion": "2015-05-01-preview",
          "location": "[parameters('location')]",
          "scale": null,
          "properties": 
              "administratorLogin": "<MY_SA_USER_THAT_I_CAN_NOT_CREATE>",
              "version": "12.0"
          ,
          "dependsOn": []
      
    ]

当运行上述内容时:

az group deployment create \
  --name "deployDBs" \
  --resource-group "MyCustomResourceGroup" \
  --template-file ./templates/db.json # --verbose --debug

然后我收到以下错误消息:

Deployment failed. Correlation ID: <A_CUSTOM_GUID>. 
  "status": "Failed",
  "error": 
    "code": "ResourceDeploymentFailure",
    "message": "The resource operation completed with terminal provisioning state 'Failed'.",
    "details": [
      
        "code": "InvalidParameterValue",
        "message": "Invalid value given for parameter Password. Specify a valid parameter value."
      
    ]
  

当删除 JSON 字段 administratorLogin 时(因为希望我能以某种方式在其他地方创建 SA 用户,我还需要弄清楚),然后我收到以下错误消息:

Deployment failed. Correlation ID: <ANOTHER_CUSTOM_GUID>. 
  "status": "Failed",
  "error": 
    "code": "ResourceDeploymentFailure",
    "message": "The resource operation completed with terminal provisioning state 'Failed'.",
    "details": [
      
        "code": "InvalidParameterValue",
        "message": "Invalid value given for parameter Login. Specify a valid parameter value."
      
    ]
  

我无法从 10000 行自动生成的 ARM 模板中找到 SA 用户(服务器管理员)的“用户名密码”对的定义。

如何在部署新的 SQL Server 实例时为 SQL Server 创建/注入 SA 用户?

【问题讨论】:

【参考方案1】:

您在本地 SQL Server 实例上使用的 sa 登录名在 Azure SQL 上称为管理员登录名。您可以提供管理员登录名及其密码作为参数,如下示例模板所示:


  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": 
    "yourservernameName": 
      "type": "string",
      "defaultValue": "yourservername2"
    ,
    "yourservernameAdminLogin": 
      "type": "string",
      "defaultValue": "VeryWiseAdmin",
      "minLength": 1
    ,
    "yourservernameAdminLoginPassword": 
      "type": "securestring",
      "defaultValue": "ReplaceWithTheMostSecurePasswordThatEverExisted&NeverShareLikeThisWithAnyone!"
    ,
    "dbnameName": 
      "type": "string",
      "defaultValue": "dbname",
      "minLength": 1
    ,
    "dbnameCollation": 
      "type": "string",
      "minLength": 1,
      "defaultValue": "SQL_Latin1_General_CP1_CI_AS"
    ,
    "dbnameEdition": 
      "type": "string",
      "defaultValue": "Basic"
    ,
    "dbnameRequestedServiceObjectiveName": 
      "type": "string",
      "defaultValue": "Basic"
    
  ,
  "variables": 
  ,
  "resources": [
    
      "name": "[parameters('yourservernameName')]",
      "type": "Microsoft.Sql/servers",
      "location": "West Europe",
      "apiVersion": "2014-04-01-preview",
      "dependsOn": [],
      "tags": 
        "displayName": "yourservername"
      ,
      "properties": 
        "administratorLogin": "[parameters('yourservernameAdminLogin')]",
        "administratorLoginPassword": "[parameters('yourservernameAdminLoginPassword')]",
        "version": "12.0"
      ,
      "resources": [
        
          "name": "[concat(parameters('yourservernameName'),'/AllowAllWindowsAzureIps')]",
          "type": "Microsoft.Sql/servers/firewallRules",
          "location": "[resourceGroup().location]",
          "apiVersion": "2014-04-01-preview",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', parameters('yourservernameName'))]"
          ],
          "properties": 
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          
        ,
        
          "name": "[concat(parameters('yourservernameName'),'/',parameters('dbnameName'))]",
          "type": "Microsoft.Sql/servers/databases",
          "location": "West Europe",
          "apiVersion": "2014-04-01-preview",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', parameters('yourservernameName'))]"
          ],
          "tags": 
            "displayName": "dbname"
          ,
          "properties": 
            "collation": "[parameters('dbnameCollation')]",
            "edition": "[parameters('dbnameEdition')]",
            "maxSizeBytes": "1073741824",
            "requestedServiceObjectiveName": "[parameters('dbnameRequestedServiceObjectiveName')]"
          
        
      ]
    
  ],
  "outputs": 
    "SomeString": 
      "type": "string",
      "value": "What ever you want to put here"
    ,
    "ServerNameParam": 
      "type": "string",
      "value": "[parameters('yourservernameName')]"
    ,
    "ServerResourceID": 
      "type": "string",
      "value": "[resourceId('Microsoft.Sql/servers', parameters('yourservernameName'))]"
    ,
    "ServerObject": 
      "type": "object",
      "value": "[reference(parameters('yourservernameName'))]"
    ,
    "SqlServerURL": 
      "type": "string",
      "value": "[reference(parameters('yourservernameName')).fullyQualifiedDomainName]"
    ,
    "DbResourceID": 
      "type": "string",
      "value": "[resourceId('Microsoft.Sql/servers/databases', parameters('yourservernameName'), parameters('dbnameName'))]"
    ,
    "DbObject": 
      "type": "object",
      "value": "[reference(parameters('dbnameName'))]"
    ,
    "DbAdoConnString": 
      "type": "string",
      "value": "[concat('Server=tcp:',reference(parameters('yourservernameName')).fullyQualifiedDomainName,',1433;Initial Catalog=',parameters('dbnameName'),';Persist Security Info=False;User ID=',reference(parameters('yourservernameName')).administratorLogin,';Password=',reference(parameters('yourservernameName')).administratorLoginPassword,';MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;')]"
    
  


【讨论】:

【参考方案2】:

工作样本:

"name": "name",
"type": "Microsoft.Sql/servers",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"properties": 
    "administratorLogin": "somelogin",
    "administratorLoginPassword": "somepasswordD1!"

请注意,SA 可能不允许,因为用户名和密码具有复杂性要求

【讨论】:

谢谢,有没有办法在运行时注入该密码值?将密码值放入 JSON 模板中似乎非常危险。我从 Azure 门户获得的 10000 行 ARM 模板不包含 administratorLoginPassword,我想知道这里推荐的最佳实践是什么。关于密码结构要求,这里有规则:docs.microsoft.com/en-us/sql/relational-databases/security/… 好吧,您可以为此使用一个参数(例如用于名称的参数),或者使用密钥保管库参考 将 KeyVault 机密与 Azure 资源管理器模板一起使用:docs.microsoft.com/en-us/azure/azure-resource-manager/… Azure 资源管理器模板中的参数(具体来说,搜索secureString):docs.microsoft.com/en-us/azure/azure-resource-manager/… @JohanStenberg-MSFT @4c74356b41 感谢 Key Vault。我正在考虑在我的 PC/笔记本电脑上使用更本地的 unix/bash 解决方案,例如用环境变量结合sedawk 等命令动态替换 JSON 模板中的占位符,也许来自 Azure 的更现代的东西命令行界面。但是查看文档似乎很容易通过 JSON ARM 模板设置 Key Vault。再次感谢!【参考方案3】:

我们希望为每个资源组创建一个临时的唯一密码,并且不必担心模板或参数文件中的密码,因为这些已检入 git。像这样解决它:

template.json:


  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": 
    "vulnerabilityAssessments_Default_storageContainerPath": 
      "type": "SecureString"
    ,
    "servers_dev_name": 
      "defaultValue": "dev-app",
      "type": "String"
    
  ,
  "variables": 
    "servers_dev_password": "[concat('P', uniqueString(resourceGroup().id, '224F5A8B-51DB-46A3-A7C8-59B0DD584A41'), 'x', '!')]",
  ,
  "resources": [
    
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2019-06-01-preview",
      "name": "[parameters('servers_dev_name')]",
      "location": "northeurope",
      "kind": "v12.0",
      "properties": 
        "administratorLogin": "OurSaName",
        "administratorLoginPassword": "[variables('servers_dev_password')]",
        "version": "12.0",
        "publicNetworkAccess": "Enabled"
      
    ,

“确保我们符合 Azure SQL 数据库策略”您的密码必须包含以下三个类别中的字符 - 英文大写字母、英文小写字母、数字 (0-9) 和非字母数字字符(!, $, #, %, etc.)”,我们为每个类别在唯一字符串前后插入一个字符。”

来源:

https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-string#uniquestring

https://vivien-chevallier.com/Articles/automatically-generate-a-password-for-an-azure-sql-database-with-arm-template

警告:

如果您添加到您的parameters.json

"servers_dev_password": 
  "value": "[uniqueString(resourceGroup().id)]"

并将参数添加到template.json实际密码将为:[uniqueString(resourceGroup().id)]

"servers_dev_password": 
  "type": "SecureString"

需要注意的是,uniqueString 的定义是:

根据提供的值创建确定性哈希字符串 参数。

这意味着,如果您想为每个部署创建一个唯一密码,则必须如下所示:

"parameters": 
  "newGuid": 
    "type": "string",
    "defaultValue": "[newGuid()]"
  


"variables": 
  "sqlserverAdminPassword": "[concat(uniqueString(guid(resourceGroup().id, deployment().name)), parameters('newGuid'), 'Tg2%')]"

您的密码将在每次部署时更新。

https://***.com/a/70325944/3850405

【讨论】:

以上是关于通过 Azure 资源管理器 (ARM) 模板创建 SQL Server的主要内容,如果未能解决你的问题,请参考以下文章

自定义配置脚本 Azure 资源管理器模板

使用 azure ARM 模板配置逻辑应用失败警报

Java调用ARM模板执行Azure Rest建立VM过程

ARM - 如何从存储帐户获取访问密钥,以便稍后在模板中的 AppSettings 中使用?

Azure函数的ARM模板文档

无法通过 ARM 模板将 CMK 加密应用于 Azure 存储帐户