【问题标题】:Create SQL Server via Azure Resource Manager (ARM) template通过 Azure 资源管理器 (ARM) 模板创建 SQL Server
【发布时间】: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 用户?

【问题讨论】:

    标签: sql-server azure azure-sql-database azure-resource-manager azure-cli


    【解决方案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://stackoverflow.com/a/70325944/3850405

      【讨论】:

        猜你喜欢
        • 2017-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-08
        • 2021-08-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多