练习 - 通过使用模块将资源部署到多个范围

已完成

注释

本练习需要 Azure 订阅。 如果还没有订阅,可以获取 免费订阅

R&D 团队已请求帮助在 Project Teddybear 订阅中创建虚拟网络。 你知道将来将帮助团队提供更多订阅,因此你决定扩展可重用的 Bicep 模板,以便为团队成员部署虚拟网络。

在本练习中,你将更新在上一个练习中开始生成的模板。

在此过程中,你将:

  • 更新订阅范围的模板以创建新的资源组。
  • 使用虚拟网络创建单独的 Bicep 模块,并使用参数来控制虚拟网络的配置方式。
  • 更新模板以将模块部署到资源组。
  • 部署模板。

此练习要求你有权部署订阅范围的资源。 如果无法使用当前 Azure 帐户满足此要求,可以获取 免费试用版 并创建新的 Azure 订阅和租户。 或者,你也可以跳过此练习中的部署步骤。

创建资源组

  1. 在 Visual Studio Code 中,打开在前面的练习中创建的 main.bicep 文件。

  2. 在当前变量定义下,添加以下变量定义:

    var resourceGroupName = 'ToyNetworking'
    
  3. 在文件的底部,添加以下资源定义:

    resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-07-01' = {
      name: resourceGroupName
      location: deployment().location
    }
    

    请注意,你正在定义资源组,就像定义另一个资源一样。 资源组是一个订阅范围内的资源,可以在 Bicep 文件中部署和管理该资源, targetScope 并将其设置为 subscription

  4. 保存对文件所做的更改。

添加模块以创建虚拟网络

接下来,你将为 R&D 团队的虚拟网络创建 Bicep 模块。 本练习稍后会将模块中的资源部署到资源组。

  1. 在 Visual Studio Code 中,在你创建了 main.bicep 文件的同一文件夹中,创建一个名为“模块”的新文件夹。

  2. modules 文件夹中,创建并保存名为 virtualNetwork.bicep 的文件。

  3. virtualNetwork.bicep 文件中,添加以下内容:

    param virtualNetworkName string
    param virtualNetworkAddressPrefix string
    
    resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
      name: virtualNetworkName
      location: resourceGroup().location
      properties: {
        addressSpace: {
          addressPrefixes: [
            virtualNetworkAddressPrefix
          ]
        }
      }
    }
    

    请注意,你尚未为此模块指定一个 targetScope 。 当 Bicep 文件面向资源组时,无需指定目标范围。

  4. 保存对文件所做的更改。

在订阅部署中使用模块

现在,你已准备好告诉 Bicep 将模块部署到资源组。

  1. 在 Visual Studio Code 中的 main.bicep 文件中的行下 targetScope ,添加以下参数定义:

    param virtualNetworkName string
    param virtualNetworkAddressPrefix string
    

    这些参数使模板可重用。 每当 R&D 团队需要新订阅时,都可以创建具有唯一名称和 IP 地址范围的虚拟网络。

  2. 在文件的底部,添加以下模块定义:

    module virtualNetwork 'modules/virtualNetwork.bicep' = {
      scope: resourceGroup
      name: 'virtualNetwork'
      params: {
        virtualNetworkName: virtualNetworkName
        virtualNetworkAddressPrefix: virtualNetworkAddressPrefix
      }
    }
    

    请注意,你正在显式指定 scope 模块。 Bicep 了解模块中的资源应部署到之前在文件中创建的资源组。

验证模板

main.bicep 文件应如下所示:

targetScope = 'subscription'

param virtualNetworkName string
param virtualNetworkAddressPrefix string

var policyDefinitionName = 'DenyFandGSeriesVMs'
var policyAssignmentName = 'DenyFandGSeriesVMs'
var resourceGroupName = 'ToyNetworking'

resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2024-05-01' = {
  name: policyDefinitionName
  properties: {
    policyType: 'Custom'
    mode: 'All'
    parameters: {}
    policyRule: {
      if: {
        allOf: [
          {
            field: 'type'
            equals: 'Microsoft.Compute/virtualMachines'
          }
          {
            anyOf: [
              {
                field: 'Microsoft.Compute/virtualMachines/sku.name'
                like: 'Standard_F*'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/sku.name'
                like: 'Standard_G*'
              }
            ]
          }
        ]
      }
      then: {
        effect: 'deny'
      }
    }
  }
}

resource policyAssignment 'Microsoft.Authorization/policyAssignments@2024-05-01' = {
  name: policyAssignmentName
  properties: {
    policyDefinitionId: policyDefinition.id
  }
}

resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-07-01' = {
  name: resourceGroupName
  location: deployment().location
}

module virtualNetwork 'modules/virtualNetwork.bicep' = {
  scope: resourceGroup
  name: 'virtualNetwork'
  params: {
    virtualNetworkName: virtualNetworkName
    virtualNetworkAddressPrefix: virtualNetworkAddressPrefix
  }
}

模块/virtualNetwork.bicep 文件应如下所示:

param virtualNetworkName string
param virtualNetworkAddressPrefix string

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
  name: virtualNetworkName
  location: resourceGroup().location
  properties: {
    addressSpace: {
      addressPrefixes: [
        virtualNetworkAddressPrefix
      ]
    }
  }
}

如果任一文件与示例不匹配,请复制示例或调整模板。

将模板部署到 Azure

在 Visual Studio Code 终端中,使用以下 Azure CLI 命令部署模板:

templateFile="main.bicep"
today=$(date +"%d-%b-%Y")
deploymentName="sub-scope-"$today
virtualNetworkName="rnd-vnet-001"
virtualNetworkAddressPrefix="10.0.0.0/24"

az deployment sub create \
    --name $deploymentName \
    --location westus \
    --template-file $templateFile \
    --parameters virtualNetworkName=$virtualNetworkName \
                 virtualNetworkAddressPrefix=$virtualNetworkAddressPrefix

在 Visual Studio Code 终端中,使用以下 Azure PowerShell 命令部署模板:

$templateFile = 'main.bicep'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "sub-scope-$today"
$virtualNetworkName = 'rnd-vnet-001'
$virtualNetworkAddressPrefix = '10.0.0.0/24'

New-AzSubscriptionDeployment `
  -Name $deploymentName `
  -Location westus `
  -TemplateFile $templateFile `
  -virtualNetworkName $virtualNetworkName `
  -virtualNetworkAddressPrefix $virtualNetworkAddressPrefix

请注意,你要传入参数 virtualNetworkName 的值 virtualNetworkAddressPrefix 。 当另一个 R&D 团队要求你为其准备订阅时,你将能够更改这些值,为该团队提供自己的虚拟网络。

此部署可能需要一两分钟才能完成,然后你会看到部署成功。

验证部署

现在,你将检查该模块创建的资源组和部署。

  1. 转到 Azure 门户

  2. 在左窗格中,选择“资源组”。 请注意,已创建 ToyNetworking 资源组。

  3. 选择 ToyNetworking 资源组。 请注意,模块已成功部署到资源组,并且已创建虚拟网络:

    Azure 门户的屏幕截图,其中显示了 ToyNetworking 资源组。

清理资源

已成功部署订阅范围的资源,包括资源组,并且已使用模块将资源部署到创建的资源组。 可以删除已创建的策略资源和资源组。

谨慎

此命令将永久删除名为 ToyNetworking 及其所有资源的资源组。 如果已将任何其他内容部署到此资源组,则应跳过此步骤。

subscriptionId=$(az account show --query 'id' --output tsv)

az policy assignment delete --name 'DenyFandGSeriesVMs' --scope "/subscriptions/$subscriptionId"
az policy definition delete --name 'DenyFandGSeriesVMs' --subscription $subscriptionId
az group delete --name ToyNetworking
$subscriptionId = (Get-AzContext).Subscription.Id

Remove-AzPolicyAssignment -Name 'DenyFandGSeriesVMs' -Scope "/subscriptions/$subscriptionId"
Remove-AzPolicyDefinition -Name 'DenyFandGSeriesVMs' -SubscriptionId $subscriptionId
Remove-AzResourceGroup -Name ToyNetworking