【问题标题】:ARM templates - web.config transform not workingARM 模板 - web.config 转换不起作用
【发布时间】:2017-02-08 11:08:11
【问题描述】:

我正在尝试使用 Arm 模板部署网站和 sql azure,并且我正在尝试使用已部署的数据库名称将 sql 连接字符串与已部署的网站进行转换。创建了网站,部署了源代码并创建了 sql azure 数据库,但连接字符串并没有改变。 我已经按照这里的方法: https://github.com/Azure/azure-quickstart-templates/tree/master/201-web-app-sql-database

我的 website.json 看起来像这样:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "hostingPlanName": {
      "type": "string",
      "minLength": 1
    },
    "environmentName": {
      "type": "string",
      "allowedValues": [
        "integration",
        "qa"
      ]
    },
    "skuName": {
      "type": "string",
      "defaultValue": "F1",
      "allowedValues": [
        "F1",
        "D1",
        "B1",
        "B2",
        "B3",
        "S1",
        "S2",
        "S3",
        "P1",
        "P2",
        "P3",
        "P4"
      ],
      "metadata": {
        "description": "Describes plan's pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
      }
    },
    "skuCapacity": {
      "type": "int",
      "defaultValue": 1,
      "minValue": 1,
      "metadata": {
        "description": "Describes plan's instance count"
      }
    },
    "sqlserverAdminLogin": {
      "type": "string",
      "minLength": 1
    },
    "sqlserverAdminLoginPassword": {
      "type": "securestring"
    },
    "databaseName": {
      "type": "string",
      "minLength": 1
    },
    "databaseCollation": {
      "type": "string",
      "minLength": 1,
      "defaultValue": "SQL_Latin1_General_CP1_CI_AS"
    },
    "databaseEdition": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "Standard",
        "Premium"
      ]
    },
    "databaseRequestedServiceObjectiveName": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "S0",
        "S1",
        "S2",
        "P1",
        "P2",
        "P3"
      ],
      "metadata": {
        "description": "Describes the performance level for Edition"
      }
    }
  },
  "variables": {
    "webSiteName": "[concat('webSite-MyApp-', uniqueString(resourceGroup().id))]",
    "sqlserverName": "[concat('sqlserver-', parameters('environmentName'), '-',  uniqueString(resourceGroup().id))]"
  },
  "resources": [
    {
      "apiVersion": "2015-08-01",
      "name": "[parameters('hostingPlanName')]",
      "type": "Microsoft.Web/serverfarms",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "HostingPlan"
      },
      "sku": {
        "name": "[parameters('skuName')]",
        "capacity": "[parameters('skuCapacity')]"
      },
      "properties": {
        "name": "[parameters('hostingPlanName')]"
      }
    },
    {
      "apiVersion": "2015-08-01",
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
      ],
      "location": "[resourceGroup().location]",
      "name": "[variables('webSiteName')]",
      "properties": {
        "name": "[variables('webSiteName')]",
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
      },
      "resources": [
        {
          "apiVersion": "2016-03-01",
          "type": "config",
          "name": "connectionstrings",
          "dependsOn": [
            "[variables('webSiteName')]"
          ],
          "properties": {
            "DefaultConnection": {
              "value": "[concat('Data Source=tcp:', reference(concat('Microsoft.Sql/servers/', variables('sqlserverName'))).fullyQualifiedDomainName, ',1433;Initial Catalog=', parameters('databaseName'), ';User Id=', parameters('sqlserverAdminLogin'), '@', reference(concat('Microsoft.Sql/servers/', variables('sqlserverName'))).fullyQualifiedDomainName, ';Password=', parameters('sqlserverAdminLoginPassword'), ';')]",
              "type": "SQLAzure"
            }
          }
        }
      ],
      "tags": {
        "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
        "displayName": "Website"
      },
      "type": "Microsoft.Web/sites"
    },
    {
      "name": "[variables('sqlserverName')]",
      "type": "Microsoft.Sql/servers",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "SqlServer"
      },
      "apiVersion": "2014-04-01",
      "properties": {
        "administratorLogin": "[parameters('sqlserverAdminLogin')]",
        "administratorLoginPassword": "[parameters('sqlserverAdminLoginPassword')]",
        "version": "12.0"
      },
      "resources": [
        {
          "name": "[parameters('databaseName')]",
          "type": "databases",
          "location": "[resourceGroup().location]",
          "tags": {
            "displayName": "Database"
          },
          "apiVersion": "2015-01-01",
          "dependsOn": [
            "[variables('sqlserverName')]"
          ],
          "properties": {
            "edition": "Basic",
            "collation": "SQL_Latin1_General_CP1_CI_AS",
            "maxSizeBytes": "1073741824",
            "requestedServiceObjectiveName": "Basic"
          }
        },
        {
          "type": "firewallrules",
          "apiVersion": "2014-04-01",
          "dependsOn": [
            "[variables('sqlserverName')]"
          ],
          "location": "[resourceGroup().location]",
          "name": "AllowAllWindowsAzureIps",
          "properties": {
            "endIpAddress": "0.0.0.0",
            "startIpAddress": "0.0.0.0"
          }
        }
      ]
    }
  ],
  "outputs": {
    "siteUri": {
      "type": "string",
      "value": "[reference(concat('Microsoft.Web/sites/', variables('webSiteName'))).hostnames[0]]"
    },
    "sqlServerFullyQualifiedDomain": {
      "type": "string",
      "value": "[reference(concat('Microsoft.Sql/servers/', variables('sqlserverName'))).fullyQualifiedDomainName]"
    }
  }
}

我的参数文件如下:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "hostingPlanName": {
      "value": "MyAppIntegration"
    },
    "environmentName": {
      "value": "integration"
    },
    "sqlserverAdminLogin": {
      "value": "azureuser"
    },
    "sqlserverAdminLoginPassword": {
      "reference": {
        "keyVault": {
          "id": "/subscriptions/XXXXXXXX/resourceGroups/resourceGroupName/providers/Microsoft.KeyVault/vaults/MyAppVault"
        },
        "secretName": "SqlAzurePassword"
      }
    },
    "databaseName": {
      "value": "myapp-integration" 
    }
  }
}

我的 web.config 看起来像这样:

ml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-MyApp-20170201054732.mdf;Initial Catalog=aspnet-MyApp-20170201054732;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

谁能告诉我为什么 DefaultConnection 永远不会改变?

【问题讨论】:

    标签: asp.net-mvc azure azure-web-app-service azure-pipelines-release-pipeline arm-template


    【解决方案1】:

    我刚刚部署了它,并且可以确认应用程序设置已正确填充。 Web.config 不应被此模板覆盖,该模板创建应用程序设置,应用程序读取:

    如果应用程序设置碰巧已经存在于您的 web.config 文件中,Windows Azure 网站将在运行时使用与您的网站关联的值自动覆盖它们。连接字符串以类似的方式工作,但有一点额外要求。请记住,之前有一个名为“example-config_db”的连接字符串与网站相关联。如果网站的 web.config 文件在配置部分引用了相同的连接字符串,则 Windows Azure 网站将在运行时使用门户中显示的值自动更新连接字符串。

    参考:https://azure.microsoft.com/en-us/blog/windows-azure-web-sites-how-application-strings-and-connection-strings-work/

    【讨论】:

    • 我对一些 appSettings 做了同样的事情,模板用部署设置覆盖了它们。我仍然不明白为什么它在这里不起作用。我遵循了微软使用的模板。你是什​​么意思'记得早先',你从哪里得到example-config_db?我不想使用门户,我想使用部署模板并根据 azure 创建的数据库动态填写连接字符串。
    • Azure 做到这一点的方式确实令人困惑。我可以使用 ARM 模板覆盖 AppSettings 中的变量,但连接字符串不会覆盖,但会在幕后以不可见的方式使用,正如您在上面所指出的那样。 web.config 保持不变。
    • 是的,看来是这样
    【解决方案2】:

    web.config 中的 DefaultConnection 连接字符串不会通过 ARM 部署更新,因为您实际上需要将 web.config 文件部署为 MSDeploy 包的一部分,并带有用于更新 DefaultConnection 连接的参数字符串,使用 ARM 模板中的 MSDeploy 扩展资源。

    例如在您的 MSDeploy Package parameters.xml 中,您需要定义一个参数以允许更新名称为 DefaultConnection 的连接字符串的值。

      <parameter name="Default Connection String" description="Connection string to enter into config" tags="SQL, Hidden,NoStore">
        <parameterEntry kind="XmlFile" scope="Web\.config$" match="//connectionStrings/add[@name='DefaultConnection']/@connectionString" />
      </parameter>
    

    除了上述之外,您还需要添加 MSDeploy extension 资源,这是您网站资源下的子资源,并设置 默认连接字符串 参数在 ARM 模板中使用 Azure SQL 连接字符串。

    {
      "apiVersion": "2015-08-01",
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
      ],
      "location": "[resourceGroup().location]",
      "name": "[variables('webSiteName')]",
      "properties": {
        "name": "[variables('webSiteName')]",
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
      },
    "resources": [
        {
            "name": "MSDeploy",
            "type": "extensions",
            "location": "[resourceGroup().location]",
            "apiVersion": "2016-08-01",
            "dependsOn": [
                "[concat('Microsoft.Web/sites/', variables('webSiteName'))]"
            ],
            "tags": {
                "displayName": "webDeploy"
            },
            "properties": {
                "packageUri": "[parameters('MSDeployPackageUri')]", 
                "dbType": "None",
                "connectionString": "",
                "setParameters": {
                    "Application Path": "[variables('webSiteName')]",
                    "Default Connection String": "[concat('Data Source=tcp:', reference(concat('Microsoft.Sql/servers/', variables('sqlserverName'))).fullyQualifiedDomainName, ',1433;Initial Catalog=', parameters('databaseName'), ';User Id=', parameters('sqlserverAdminLogin'), '@', reference(concat('Microsoft.Sql/servers/', variables('sqlserverName'))).fullyQualifiedDomainName, ';Password=', parameters('sqlserverAdminLoginPassword'), ';')]"
                }
            }
        }
    ],
      "tags": {
        "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
        "displayName": "Website"
      },
      "type": "Microsoft.Web/sites"
    },...
    

    参考:Deploy a web app with MSDeploy, custom hostname and SSL certificate

    【讨论】:

    • 感谢您的回复。我不必做任何这些来覆盖 appSetting 变量。为什么连接字符串如此不同?
    • 这是因为 Azure 应用服务的连接字符串设置优先于 web.config 中定义的连接字符串设置,因此它们不需要更新 web.config 中的连接字符串
    • 我没有在 azure 应用服务中使用连接字符串
    • 没有。在您的 Arm 模板中,您将在您的网站下定义连接字符串配置类型资源
    • 感谢您的帮助。我想要做的是以与 appSettings 相同的方式覆盖 web.config 中的连接字符串。你上面描述的能做到这一点吗?
    猜你喜欢
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 2019-04-24
    相关资源
    最近更新 更多