Dela via


Köra Bicep-distributionsskript privat via en privat slutpunkt

Med resurs-API-versionen Microsoft.Resources/deploymentScripts 2023-08-01kan du köra distributionsskript privat i en Azure Container Instance (ACI).

Konfigurera miljön

I den här konfigurationen körs den ACI som skapats av distributionsskriptet i ett virtuellt nätverk och hämtar en privat IP-adress. Sedan upprättas en anslutning till ett nytt eller befintligt lagringskonto via en privat slutpunkt. Egenskapen containerSettings/subnetIds anger den ACI som måste distribueras i ett undernät i det virtuella nätverket.

Skärmbild av arkitektur på hög nivå som visar hur infrastrukturen är ansluten för att köra distributionsskript privat.

Om du vill köra distributionsskript privat behöver du följande infrastruktur enligt arkitekturdiagrammet:

  • Skapa ett virtuellt nätverk med två undernät:
    • Ett undernät för den privata slutpunkten.
    • Ett undernät för ACI:t, det här undernätet behöver en Microsoft.ContainerInstance/containerGroups delegering.
  • Skapa ett lagringskonto utan åtkomst till det offentliga nätverket.
  • Skapa en privat slutpunkt i det virtuella nätverket som konfigurerats med underresursen file på lagringskontot.
  • Skapa en privat DNS-zon privatelink.file.core.windows.net och registrera ip-adressen för den privata slutpunkten som en A-post. Länka den privata DNS-zonen till det skapade virtuella nätverket.
  • Skapa en användartilldelad hanterad identitet med Storage File Data Privileged Contributor behörigheter för lagringskontot och ange den i identity egenskapen i distributionsskriptresursen. Information om hur du tilldelar identiteten finns i Identitet.
  • ACI-resursen skapas automatiskt av distributionsskriptresursen.

Följande Bicep-fil konfigurerar infrastrukturen som krävs för att köra ett distributionsskript privat:

@maxLength(10) // Required maximum length, because the storage account has a maximum of 26 characters
param namePrefix string
param location string = resourceGroup().location
param userAssignedIdentityName string = '${namePrefix}Identity'
param storageAccountName string = '${namePrefix}stg${uniqueString(resourceGroup().id)}'
param vnetName string = '${namePrefix}Vnet'
param deploymentScriptName string = '${namePrefix}ds'

var roleNameStorageFileDataPrivilegedContributor = '69566ab7-960f-475b-8e7c-b3118f30c6bd'
var vnetAddressPrefix = '192.168.4.0/23'
var subnetEndpointAddressPrefix = '192.168.4.0/24'
var subnetACIAddressPrefix = '192.168.5.0/24'

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: userAssignedIdentityName
  location: location
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: storageAccountName
  kind: 'StorageV2'
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  properties: {
    publicNetworkAccess: 'Disabled'
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
    }
  }
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = {
   name: storageAccount.name
   location: location
   properties: {
    privateLinkServiceConnections: [
      {
        name: storageAccount.name
        properties: {
          privateLinkServiceId: storageAccount.id
          groupIds: [
            'file'
          ]
        }
      }
    ]
    customNetworkInterfaceName: '${storageAccount.name}-nic'
    subnet: {
      id: virtualNetwork::privateEndpointSubnet.id
    }
   }
}

resource storageFileDataPrivilegedContributorReference 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
  name: roleNameStorageFileDataPrivilegedContributor
  scope: tenant()
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(storageFileDataPrivilegedContributorReference.id, managedIdentity.id, storageAccount.id)
  scope: storageAccount
  properties: {
    principalId: managedIdentity.properties.principalId
    roleDefinitionId: storageFileDataPrivilegedContributorReference.id
    principalType: 'ServicePrincipal'
  }
}

resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = {
  name: 'privatelink.file.core.windows.net'
  location: 'global'

  resource virtualNetworkLink 'virtualNetworkLinks' = {
    name: uniqueString(virtualNetwork.name)
    location: 'global'
    properties: {
      registrationEnabled: false
      virtualNetwork: {
        id: virtualNetwork.id
      }
    }
  }

  resource resRecord 'A' = {
    name: storageAccount.name
    properties: {
      ttl: 10
      aRecords: [
        {
          ipv4Address: first(first(privateEndpoint.properties.customDnsConfigs)!.ipAddresses)
        }
      ]
    }
  }
}

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' = {
  name: vnetName
  location: location
  properties:{
    addressSpace: {
      addressPrefixes: [
        vnetAddressPrefix
      ]
    }
  }

  resource privateEndpointSubnet 'subnets' = {
    name: 'PrivateEndpointSubnet'
    properties: {
      addressPrefixes: [
        subnetEndpointAddressPrefix
      ]
    }
  }

  resource containerInstanceSubnet 'subnets' = {
    name: 'ContainerInstanceSubnet'
    properties: {
      addressPrefix: subnetACIAddressPrefix
      delegations: [
        {
          name: 'containerDelegation'
          properties: {
            serviceName: 'Microsoft.ContainerInstance/containerGroups'
          }
        }
      ]
    }
  }
}

resource privateDeploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: deploymentScriptName
  dependsOn: [
    privateEndpoint
    privateDnsZone::virtualNetworkLink
  ]
  location: location
  kind: 'AzurePowerShell'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${managedIdentity.id}' : {}
    }
  }
  properties: {
    storageAccountSettings: {
      storageAccountName: storageAccount.name
    }
    containerSettings: {
      subnetIds: [
        {
          id: virtualNetwork::containerInstanceSubnet.id
        }
      ]
    }
    azPowerShellVersion: '9.0'
    retentionInterval: 'P1D'
    scriptContent: 'Write-Host "Hello World!"'
  }
}

ACI laddar ned containeravbildningar från Microsoft Container Registry. Om du använder en brandvägg tillåter du att URL:en mcr.microsoft.com ladda ned avbildningen. Om containeravbildningen inte laddas ned resulterar det i att ACI:en anger ett waiting tillstånd, vilket leder till ett timeout-fel.

Nästa steg

I den här artikeln har du lärt dig hur du kör distributionsskript via en privat slutpunkt. Mer information: