Erstellen Sie einen Azure Red Hat OpenShift-Cluster mit gehosteten Steuerungsebenen (Vorschau)

In diesem Artikel wird beschrieben, wie Sie mithilfe des Azure CLI oder einer Bicep-Datei eine Azure Red Hat OpenShift mit gehosteten Steuerelementebenen (HCP)-Clustern erstellen.

Die Bicep Datei definiert alle Azure Ressourcen, die für den Cluster erforderlich sind, einschließlich der Netzwerkinfrastruktur, verwalteter Identitäten, Rollenzuweisungen, Clusterkonfiguration und Knotenpool.

Die CLI-Befehle erstellen alle Azure Ressourcen, die für den Cluster erforderlich sind, einschließlich der Netzwerkinfrastruktur, verwalteter Identitäten, Rollenzuweisungen, Clusterkonfiguration und Knotenpool.

Voraussetzungen

Vorbereiten der Umgebung

Stellen Sie vor dem Erstellen des Clusters sicher, dass Ihre Azure Umgebung die folgenden Anforderungen erfüllt.

Azure CLI

Stellen Sie sicher, dass Sie Azure CLI Version 2.67.0 oder höher verwenden. Verwenden Sie az --version, um Ihre installierte Version zu überprüfen. Informationen zum Installieren oder Aktualisieren finden Sie unter Install Azure CLI.

ARO HCP CLI-Erweiterung

  1. Laden Sie die Raddatei für die ARO HCP CLI-Erweiterung herunter.

  2. Installieren Sie die Erweiterung. Ersetzen Sie <path-to-downloaded-extension.whl> durch den Pfad der heruntergeladenen Datei.

    az extension add --source <path-to-downloaded-extension.whl>
    
  3. Überprüfe, ob die Erweiterung installiert ist:

    az aro hcp -h
    

Ressourcenkontingent

Azure Red Hat OpenShift mit gehosteten Steuerebenen erfordert mindestens 20 Kerne, um einen Cluster zu erstellen und auszuführen. Das standardmäßige Azure-Ressourcenkontingent für ein neues Azure-Abonnement erfüllt diese Anforderung nicht. Informationen zum Anfordern einer Erhöhung des Ressourcenlimits finden Sie unter "Standardkontingent: Erhöhen der Grenzwerte nach VM-Reihen". Stellen Sie sicher, dass Sie über ein ausreichendes Kontingent für die VM-Familie verfügen, die Sie aus den unterstützten VM-Größen für Workerknoten auswählen.

So überprüfen Sie das aktuelle Kontingent für die Standardfamilie virtueller Computer:

LOCATION=eastus
az vm list-usage -l $LOCATION \
  --query "[?contains(name.value, 'standardDSv5Family')]" -o table

Erlaubnisse

Sie benötigen Berechtigungen für mitwirkende und Benutzerzugriffsadministratoren oder Besitzerberechtigungen für die Ressourcengruppe oder das Abonnement, in der Sie den Cluster erstellen. Diese Berechtigungen sind erforderlich, um die Ressourcengruppe, das virtuelle Netzwerk, verwaltete Identitäten und Rollenzuweisungen zu erstellen.

Weitere Informationen finden Sie unter Überprüfen Ihrer Berechtigungen.

Registrieren von Ressourcenanbietern

Registrieren Sie die folgenden Ressourcenanbieter in Ihrem Azure-Abonnement:

  • Microsoft.RedHatOpenShift
  • Microsoft.Compute
  • Microsoft.Storage
  • Microsoft.Authorization

So überprüfen Sie, ob ein Ressourcenanbieter registriert ist:

az provider list --query "[?namespace=='Microsoft.RedHatOpenShift'].registrationState" \
  --output table

Wenn Sie Ressourcenanbieter finden, die nicht registriert sind, registrieren Sie sie.

az provider register --namespace Microsoft.RedHatOpenShift --wait
az provider register --namespace Microsoft.Compute --wait
az provider register --namespace Microsoft.Storage --wait
az provider register --namespace Microsoft.Authorization --wait

Weitere Informationen zum Registrieren von Ressourcenanbietern finden Sie unter Registrieren der Ressourcenanbieter.

Festlegen von Umgebungsvariablen

Legen Sie die folgenden Umgebungsvariablen fest, um die Namen der von Ihnen erstellten Ressourcen zu definieren. Ersetzen Sie die Platzhalterwerte durch Ihre eigenen Werte.

# Azure resource location and subscription
LOCATION="<region>"
SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
CUSTOMER_RG_NAME="<resource-group-name>"

# Network resources
CUSTOMER_NSG="<nsg-name>"
CUSTOMER_VNET_NAME="<vnet-name>"
CUSTOMER_VNET_SUBNET1="<worker-subnet-name>"
CUSTOMER_VNET_INTEGRATION_SUBNET_NAME="<vnet-integration-subnet-name>"

# Cluster and node pool
CLUSTER_NAME="<cluster-name>"
MANAGED_RESOURCE_GROUP="${CLUSTER_NAME}-managed-rg"
NP_NAME="<node-pool-name>"
CLUSTER_VERSION="<major.minor>"    # Example: 4.22
NP_VERSION="<major.minor.patch>"   # Example: 4.22.1

Note

Weitere Informationen zu cluster- und Knotenpoolversionsanforderungen finden Sie in den unterstützten Versionskombinationen.

Note

Eine Liste der unterstützten Regionen finden Sie unter Auswählen der Clusterregion.

Erstellen einer Ressourcengruppe

Erstellen Sie eine Ressourcengruppe, um die Clusterressource, das virtuelle Netzwerk und verwaltete Identitäten zu enthalten.

az group create \
  --name "${CUSTOMER_RG_NAME}" \
  --subscription "${SUBSCRIPTION_ID}" \
  --location "${LOCATION}"

Erstellen der Bicep-Datei

Erstellen Sie eine Datei namens azuredeploy.bicep mit folgendem Inhalt. Diese Bicep-Vorlage definiert alle Ressourcen, die zum Bereitstellen eines Azure Red Hat OpenShift-Clusters mit gehosteten Steuerungsebenen erforderlich sind, einschließlich der Netzwerksicherheitsgruppe, des virtuellen Netzwerks, der verwalteten Identitäten, der Rollenzuweisungen, des Schlüsseltresors, des KMS-Schlüssels für die Verschlüsselung, des Clusters und des Knotenpools.

Die Vorlage stellt einen Cluster mit OVN-Kubernetes-Netzwerk mit Standard-CIDR-Bereichen, kundenseitig verwalteter etcd-Verschlüsselung, ausgehender Konnektivität über den Lastenausgleich und einem einzelnen Knotenpool mit zwei Standard_D8s_v3 Workerknoten bereit.

Informationen zum Anpassen der Cluster- oder Knotenpoolkonfiguration finden Sie unter Bicep Dateireferenz.

Note

Wenn Sie der Netzwerksicherheitsgruppe (Network Security Group, NSG) benutzerdefinierte Regeln hinzufügen, stellen Sie sicher, dass die NSG den unter "Erforderlicher Netzwerksicherheitsgruppendatenverkehr" beschriebenen Datenverkehr zulässt.

@description('Network Security Group Name')
param customerNsgName string

@description('Virtual Network Name')
param customerVnetName string

@description('Subnet Name')
param customerVnetSubnetName string

@description('Virtual Network Integration Subnet Name')
param customerVirtualNetworkIntegrationSubnetName string

@description('Name of the cluster')
param clusterName string

@description('The cluster managed resource group name')
param managedResourceGroupName string

@description('The name of the node pool')
param nodePoolName string

@description('The OpenShift version for the cluster (X.Y format, e.g. 4.20)')
param clusterVersion string

@description('The OpenShift version for the node pool (X.Y.Z format, e.g. 4.20.8)')
param nodePoolVersion string

@description('Deploy ARO HCP with a private key vault')
param privateKeyVault bool

@description('API server visibility')
@allowed([
  'Public'
  'Private'
])
param apiVisibility string = 'Public'

@description('Default ingress type')
@allowed([
  'Public'
  'Private'
])
param ingressType string = 'Public'

@description('Cryptographic restrictions for kernel and userspace libraries (immutable after creation)')
@allowed(['None', 'FIPS'])
param cryptoRestrictions string = 'None'


var etcdEncryptionKeyName = 'etcd-data-kms-encryption-key'
var randomSuffix = toLower(uniqueString(clusterName))
var randomKeyVaultSuffix = toLower(uniqueString(resourceGroup().id))
var customerKeyVaultName string = 'cust-kv-${randomKeyVaultSuffix}'
var addressPrefix = '10.0.0.0/16'
var subnetPrefix = '10.0.0.0/24'
var virtualNetworkIntegrationSubnetPrefix = '10.0.1.0/24'


// Network Security Group
resource customerNsg 'Microsoft.Network/networkSecurityGroups@2023-05-01' = {
  name: customerNsgName
  location: resourceGroup().location
}

// Virtual network with worker subnet and VNet integration subnet
resource customerVnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
  name: customerVnetName
  location: resourceGroup().location
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
    subnets: [
      {
        name: customerVnetSubnetName
        properties: {
          addressPrefix: subnetPrefix
          networkSecurityGroup: {
            id: customerNsg.id
          }
        }
      }
      {
        name: customerVirtualNetworkIntegrationSubnetName
        properties: {
          addressPrefix: virtualNetworkIntegrationSubnetPrefix
          networkSecurityGroup: {
            id: customerNsg.id
          }
          delegations: [
            {
              name: 'aro-hcp-delegation'
              properties: {
                serviceName: 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters'
              }
            }
          ]
        }
      }
    ]
  }
}

resource subnet 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' existing = {
  name: customerVnetSubnetName
  parent: customerVnet
}

resource vnetIntegrationSubnet 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' existing = {
  name: customerVirtualNetworkIntegrationSubnetName
  parent: customerVnet
}

resource customerKeyVault 'Microsoft.KeyVault/vaults@2024-12-01-preview' = {
  name: customerKeyVaultName
  location: resourceGroup().location
  properties: {
    enableRbacAuthorization: true
    tenantId: subscription().tenantId
    publicNetworkAccess: privateKeyVault ? 'Disabled' : 'Enabled'
    sku: {
      family: 'A'
      name: 'standard'
    }
  }
}

resource etcdEncryptionKey 'Microsoft.KeyVault/vaults/keys@2024-12-01-preview' = {
  parent: customerKeyVault
  name: 'etcd-data-kms-encryption-key'
  properties: {
    kty: 'RSA'
    keySize: 2048
  }
}

resource privateEndpointDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = if (privateKeyVault) {
  name: 'privatelink.vaultcore.azure.net'
  location: 'global'
  properties: {}
  dependsOn: [
    privateEndpoint
  ]
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-09-01' = if (privateKeyVault) {
  name: 'kv-private-endpoint'
  properties: {
    privateLinkServiceConnections: [
      {
        name: 'kv-private-endpoint'
        properties: {
          privateLinkServiceId: customerKeyVault.id
          groupIds: ['vault']
        }
      }
    ]
    subnet: {
      id: customerVnet.properties.subnets[0].id
    }
  }
  location: resourceGroup().location
}

resource privateEndpointDnsGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2023-09-01' = if (privateKeyVault) {
  name: 'kv-private-ep-dns-group'
  parent: privateEndpoint
  properties: {
    privateDnsZoneConfigs: [
      {
        name: 'config1'
        properties: {
          privateDnsZoneId: privateEndpointDnsZone.id
        }
      }
    ]
  }
  dependsOn: [
    privateDnsZoneVnetLink
  ]
}

resource privateDnsZoneVnetLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = if (privateKeyVault) {
  name: uniqueString('kv-private-dns-zone-link')
  parent: privateEndpointDnsZone
  location: 'global'
  properties: {
    registrationEnabled: false
    virtualNetwork: {
      id: customerVnet.id
    }
  }
}

//
// Control plane identities
//

// Reader
var readerRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  'acdd72a7-3385-48ef-bd42-f606fba81ae7'
)

//
// Cluster API Azure managed identity
//

resource clusterApiAzureMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-cluster-api-azure-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift with hosted control planes Cluster API Provider
var hcpClusterApiProviderRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  '88366f10-ed47-4cc0-9fab-c8a06148393e'
)

resource hcpClusterApiProviderRoleSubnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, clusterApiAzureMi.id, hcpClusterApiProviderRoleId, subnet.id)
  scope: subnet
  properties: {
    principalId: clusterApiAzureMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: hcpClusterApiProviderRoleId
  }
}

resource hcpClusterApiProviderRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, clusterApiAzureMi.id, hcpClusterApiProviderRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: clusterApiAzureMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: hcpClusterApiProviderRoleId
  }
}

resource serviceManagedIdentityReaderOnClusterApiAzureMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, clusterApiAzureMi.id)
  scope: clusterApiAzureMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// KMS managed identity
//

resource kmsMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-kms-${randomSuffix}'
  location: resourceGroup().location
}

// Key Vault Crypto User
var keyVaultCryptoUserRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  '12338af0-0e69-4776-bea7-57ae8d297424'
)

resource keyVaultCryptoUserToKeyVaultRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, kmsMi.id, keyVaultCryptoUserRoleId, customerKeyVault.id)
  scope: customerKeyVault
  properties: {
    principalId: kmsMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: keyVaultCryptoUserRoleId
  }
}

resource serviceManagedIdentityReaderOnKmsMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, kmsMi.id)
  scope: kmsMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// Control plane operator managed identity
//

resource controlPlaneMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-control-plane-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift with hosted control planes Control Plane Operator
var hcpControlPlaneOperatorRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  'fc0c873f-45e9-4d0d-a7d1-585aab30c6ed'
)

resource hcpControlPlaneOperatorVnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, controlPlaneMi.id, hcpControlPlaneOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: controlPlaneMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: hcpControlPlaneOperatorRoleId
  }
}

resource hcpControlPlaneOperatorNsgRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, controlPlaneMi.id, hcpControlPlaneOperatorRoleId, customerNsg.id)
  scope: customerNsg
  properties: {
    principalId: controlPlaneMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: hcpControlPlaneOperatorRoleId
  }
}

resource serviceManagedIdentityReaderOnControlPlaneMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, controlPlaneMi.id)
  scope: controlPlaneMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// Cloud controller manager managed identity
//

resource cloudControllerManagerMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-cloud-controller-manager-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift Cloud Controller Manager
var cloudControllerManagerRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  'a1f96423-95ce-4224-ab27-4e3dc72facd4'
)

resource cloudControllerManagerRoleSubnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, cloudControllerManagerMi.id, cloudControllerManagerRoleId, subnet.id)
  scope: subnet
  properties: {
    principalId: cloudControllerManagerMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: cloudControllerManagerRoleId
  }
}

resource cloudControllerManagerRoleNsgAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, cloudControllerManagerMi.id, cloudControllerManagerRoleId, customerNsg.id)
  scope: customerNsg
  properties: {
    principalId: cloudControllerManagerMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: cloudControllerManagerRoleId
  }
}

resource cloudControllerManagerRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, cloudControllerManagerMi.id, cloudControllerManagerRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: cloudControllerManagerMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: cloudControllerManagerRoleId
  }
}

resource serviceManagedIdentityReaderOnCloudControllerManagerMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, cloudControllerManagerMi.id)
  scope: cloudControllerManagerMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// Ingress managed identity
//

resource ingressMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-ingress-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift Cluster Ingress Operator
var ingressOperatorRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  '0336e1d3-7a87-462b-b6db-342b63f7802c'
)

// Azure Red Hat OpenShift Image Registry Operator
var imageRegistryOperatorRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  '8b32b316-c2f5-4ddf-b05b-83dacd2d08b5'
)

resource ingressOperatorRoleSubnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, ingressMi.id, ingressOperatorRoleId, subnet.id)
  scope: subnet
  properties: {
    principalId: ingressMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: ingressOperatorRoleId
  }
}

resource ingressOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, ingressMi.id, ingressOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: ingressMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: ingressOperatorRoleId
  }
}

resource serviceManagedIdentityReaderOnIngressMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, ingressMi.id)
  scope: ingressMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// Disk CSI driver managed identity
//

resource diskCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-disk-csi-driver-${randomSuffix}'
  location: resourceGroup().location
}

resource serviceManagedIdentityReaderOnDiskCsiDriverMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, diskCsiDriverMi.id)
  scope: diskCsiDriverMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// File CSI driver managed identity
//

resource fileCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-file-csi-driver-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift File Storage Operator
var fileStorageOperatorRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  '0d7aedc0-15fd-4a67-a412-efad370c947e'
)

resource fileStorageOperatorRoleSubnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, fileCsiDriverMi.id, fileStorageOperatorRoleId, subnet.id)
  scope: subnet
  properties: {
    principalId: fileCsiDriverMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: fileStorageOperatorRoleId
  }
}

resource fileStorageOperatorRoleNsgAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, fileCsiDriverMi.id, fileStorageOperatorRoleId, customerNsg.id)
  scope: customerNsg
  properties: {
    principalId: fileCsiDriverMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: fileStorageOperatorRoleId
  }
}

resource fileStorageOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, fileCsiDriverMi.id, fileStorageOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: fileCsiDriverMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: fileStorageOperatorRoleId
  }
}

resource serviceManagedIdentityReaderOnFileCsiDriverMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, fileCsiDriverMi.id)
  scope: fileCsiDriverMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// Image registry managed identity
//

resource imageRegistryMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-image-registry-${randomSuffix}'
  location: resourceGroup().location
}

resource serviceManagedIdentityReaderOnImageRegistryMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, imageRegistryMi.id)
  scope: imageRegistryMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

resource imageRegistryOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, imageRegistryMi.id, imageRegistryOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: imageRegistryMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: imageRegistryOperatorRoleId
  }
}

//
// Cloud network config managed identity
//

resource cloudNetworkConfigMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-cp-cloud-network-config-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift Network Operator
var networkOperatorRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  'be7a6435-15ae-4171-8f30-4a343eff9e8f'
)

resource networkOperatorRoleSubnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, cloudNetworkConfigMi.id, networkOperatorRoleId, subnet.id)
  scope: subnet
  properties: {
    principalId: cloudNetworkConfigMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: networkOperatorRoleId
  }
}

resource networkOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, cloudNetworkConfigMi.id, networkOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: cloudNetworkConfigMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: networkOperatorRoleId
  }
}

resource serviceManagedIdentityReaderOnCloudNetworkMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, cloudNetworkConfigMi.id)
  scope: cloudNetworkConfigMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: readerRoleId
  }
}

//
// Data plane identities
//

// Azure Red Hat OpenShift Federated Credential
var federatedCredentialsRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  'ef318e2a-8334-4a05-9e4a-295a196c6a6e'
)

resource dpDiskCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-dp-disk-csi-driver-${randomSuffix}'
  location: resourceGroup().location
}

resource dpDiskCsiDriverMiFederatedCredentialsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpDiskCsiDriverMi.id, federatedCredentialsRoleId)
  scope: dpDiskCsiDriverMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: federatedCredentialsRoleId
  }
}

resource dpFileCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-dp-file-csi-driver-${randomSuffix}'
  location: resourceGroup().location
}

resource dpFileCsiDriverMiFederatedCredentialsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpFileCsiDriverMi.id, federatedCredentialsRoleId)
  scope: dpFileCsiDriverMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: federatedCredentialsRoleId
  }
}

resource dpFileCsiDriverFileStorageOperatorRoleSubnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpFileCsiDriverMi.id, fileStorageOperatorRoleId, subnet.id)
  scope: subnet
  properties: {
    principalId: dpFileCsiDriverMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: fileStorageOperatorRoleId
  }
}

resource dpFileCsiDriverFileStorageOperatorRoleNsgAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpFileCsiDriverMi.id, fileStorageOperatorRoleId, customerNsg.id)
  scope: customerNsg
  properties: {
    principalId: dpFileCsiDriverMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: fileStorageOperatorRoleId
  }
}

resource dpFileCsiDriverFileStorageOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpFileCsiDriverMi.id, fileStorageOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: dpFileCsiDriverMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: fileStorageOperatorRoleId
  }
}

resource dpImageRegistryMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-dp-image-registry-${randomSuffix}'
  location: resourceGroup().location
}

resource dpImageRegistryMiFederatedCredentialsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpImageRegistryMi.id, federatedCredentialsRoleId)
  scope: dpImageRegistryMi
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: federatedCredentialsRoleId
  }
}

resource dpImageRegistryOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, dpImageRegistryMi.id, imageRegistryOperatorRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: dpImageRegistryMi.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: imageRegistryOperatorRoleId
  }
}

//
// Service managed identity
//

resource serviceManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${clusterName}-service-managed-identity-${randomSuffix}'
  location: resourceGroup().location
}

// Azure Red Hat OpenShift with hosted control planes Service Managed Identity
var hcpServiceManagedIdentityRoleId = subscriptionResourceId(
  'Microsoft.Authorization/roleDefinitions',
  'c0ff367d-66d8-445e-917c-583feb0ef0d4'
)

resource serviceManagedIdentityRoleAssignmentVnet 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, hcpServiceManagedIdentityRoleId, customerVnet.id)
  scope: customerVnet
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: hcpServiceManagedIdentityRoleId
  }
}

resource serviceManagedIdentityRoleAssignmentNSG 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(resourceGroup().id, serviceManagedIdentity.id, hcpServiceManagedIdentityRoleId, customerNsg.id)
  scope: customerNsg
  properties: {
    principalId: serviceManagedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: hcpServiceManagedIdentityRoleId
  }
}


// Cluster resource
resource hcp 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters@2026-09-01-preview' = {
  name: clusterName
  location: resourceGroup().location
  properties: {
    version: {
      id: clusterVersion
      channelGroup: 'stable'
    }
    dns: {}
    network: {
      networkType: 'OVNKubernetes'
      podCidr: '10.128.0.0/14'
      serviceCidr: '172.30.0.0/16'
      machineCidr: '10.0.0.0/16'
      hostPrefix: 23
    }
    etcd: {
      dataEncryption: {
        keyManagementMode: 'CustomerManaged'
        customerManaged: {
          encryptionType: 'KMS'
          kms: {
            activeKey: {
              name: etcdEncryptionKeyName
              version: last(split(etcdEncryptionKey.properties.keyUriWithVersion, '/'))
            }
            vaultName: customerKeyVaultName
            visibility: privateKeyVault ? 'Private' : 'Public'
          }
        }
      }
    }
    api: {
      visibility: apiVisibility
    }
    ingress: {
      type: ingressType
    }
    cryptoRestrictions: cryptoRestrictions
    clusterImageRegistry: {
      state: 'Enabled'
    }
    platform: {
      managedResourceGroup: managedResourceGroupName
      subnetId: subnet.id
      vnetIntegrationSubnetId: vnetIntegrationSubnet.id
      outboundType: 'LoadBalancer'
      networkSecurityGroupId: customerNsg.id
      operatorsAuthentication: {
        userAssignedIdentities: {
          controlPlaneOperators: {
            'cluster-api-azure': clusterApiAzureMi.id
            'control-plane': controlPlaneMi.id
            'cloud-controller-manager': cloudControllerManagerMi.id
            ingress: ingressMi.id
            'disk-csi-driver': diskCsiDriverMi.id
            'file-csi-driver': fileCsiDriverMi.id
            'image-registry': imageRegistryMi.id
            'cloud-network-config': cloudNetworkConfigMi.id
            kms: kmsMi.id
          }
          dataPlaneOperators: {
            'disk-csi-driver': dpDiskCsiDriverMi.id
            'file-csi-driver': dpFileCsiDriverMi.id
            'image-registry': dpImageRegistryMi.id
          }
          serviceManagedIdentity: serviceManagedIdentity.id
        }
      }
    }
  }
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${serviceManagedIdentity.id}': {}
      '${clusterApiAzureMi.id}': {}
      '${controlPlaneMi.id}': {}
      '${cloudControllerManagerMi.id}': {}
      '${ingressMi.id}': {}
      '${diskCsiDriverMi.id}': {}
      '${fileCsiDriverMi.id}': {}
      '${imageRegistryMi.id}': {}
      '${cloudNetworkConfigMi.id}': {}
      '${kmsMi.id}': {}
    }
  }
  dependsOn: [
    hcpClusterApiProviderRoleSubnetAssignment
    hcpClusterApiProviderRoleVnetAssignment
    keyVaultCryptoUserToKeyVaultRoleAssignment
    hcpControlPlaneOperatorVnetRoleAssignment
    hcpControlPlaneOperatorNsgRoleAssignment
    cloudControllerManagerRoleSubnetAssignment
    cloudControllerManagerRoleNsgAssignment
    cloudControllerManagerRoleVnetAssignment
    ingressOperatorRoleSubnetAssignment
    ingressOperatorRoleVnetAssignment
    fileStorageOperatorRoleSubnetAssignment
    fileStorageOperatorRoleNsgAssignment
    fileStorageOperatorRoleVnetAssignment
    networkOperatorRoleSubnetAssignment
    networkOperatorRoleVnetAssignment
    dpDiskCsiDriverMiFederatedCredentialsRoleAssignment
    dpFileCsiDriverMiFederatedCredentialsRoleAssignment
    dpImageRegistryMiFederatedCredentialsRoleAssignment
    serviceManagedIdentityRoleAssignmentVnet
    serviceManagedIdentityRoleAssignmentNSG
    dpFileCsiDriverFileStorageOperatorRoleSubnetAssignment
    dpFileCsiDriverFileStorageOperatorRoleNsgAssignment
    dpFileCsiDriverFileStorageOperatorRoleVnetAssignment
    imageRegistryOperatorRoleVnetAssignment
    dpImageRegistryOperatorRoleVnetAssignment
    serviceManagedIdentityReaderOnControlPlaneMi
    serviceManagedIdentityReaderOnCloudControllerManagerMi
    serviceManagedIdentityReaderOnIngressMi
    serviceManagedIdentityReaderOnDiskCsiDriverMi
    serviceManagedIdentityReaderOnFileCsiDriverMi
    serviceManagedIdentityReaderOnImageRegistryMi
    serviceManagedIdentityReaderOnCloudNetworkMi
    serviceManagedIdentityReaderOnClusterApiAzureMi
    serviceManagedIdentityReaderOnKmsMi
  ]
}

// Node pool resource
resource nodepool 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters/nodePools@2026-09-01-preview' = {
  parent: hcp
  name: nodePoolName
  location: resourceGroup().location
  properties: {
    version: {
      id: nodePoolVersion
      channelGroup: 'stable'
    }
    platform: {
      subnetId: hcp.properties.platform.subnetId
      vmSize: 'Standard_D8s_v3'
      osDisk: {
        sizeGiB: 64
        diskStorageAccountType: 'StandardSSD_LRS'
      }
    }
    replicas: 2
  }
}

Bereitstellung der Bicep-Datei

Stellen Sie die Bicep-Vorlage bereit, um den Cluster und alle erforderlichen Ressourcen zu erstellen.

az deployment group create \
  --name 'aro-hcp' \
  --subscription "${SUBSCRIPTION_ID}" \
  --resource-group "${CUSTOMER_RG_NAME}" \
  --template-file azuredeploy.bicep \
  --parameters \
    customerNsgName="${CUSTOMER_NSG}" \
    customerVnetName="${CUSTOMER_VNET_NAME}" \
    customerVirtualNetworkIntegrationSubnetName="${CUSTOMER_VNET_INTEGRATION_SUBNET_NAME}" \
    customerVnetSubnetName="${CUSTOMER_VNET_SUBNET1}" \
    clusterName="${CLUSTER_NAME}" \
    managedResourceGroupName="${MANAGED_RESOURCE_GROUP}" \
    nodePoolName="${NP_NAME}" \
    clusterVersion="${CLUSTER_VERSION}" \
    nodePoolVersion="${NP_VERSION}" \
    apiVisibility="<Public-or-Private>" \
    ingressType="<Public-or-Private>" \
    privateKeyVault=<true-or-false> \
    cryptoRestrictions="<None-or-FIPS>"

Setzen Sie apiVisibility auf Public für einen über das Internet erreichbaren API-Server oder auf Private für einen API-Server, der nur über eine private Netzwerkverbindung erreichbar ist.

Setzen Sie ingressType auf Public für Anwendungsrouten mit Internetzugang oder auf Private für Anwendungsrouten, die nur über eine private Netzwerkverbindung erreichbar sind.

Setzen Sie privateKeyVault auf true, um den Zugriff auf den Schlüsseltresor auf einen privaten Endpunkt zu beschränken, oder auf false, um öffentlichen Zugriff zuzulassen. Wenn Sie privateKeyVault auf true setzen, deaktiviert die Bicep-Vorlage den öffentlichen Zugriff auf den Key Vault, stellt die Ressourcen für private Endpunkte bereit und setzt die Tresorsichtbarkeit in Ihrem Cluster auf Private.

Setzen Sie cryptoRestrictions auf FIPS, um den Cluster auf FIPS-validierte kryptografische Module zu beschränken, oder auf None (Standard), um ihn ohne FIPS-Einschränkungen bereitzustellen. Diese Einstellung ist nach der Clustererstellung unveränderlich.

Note

Die Steuerungsebene wird unabhängig von dieser Einstellung immer auf einem FIPS-fähigen Cluster gehostet. Der cryptoRestrictions Parameter steuert, ob die Arbeitsknotenpools FIPS-validierte kryptografische Module verwenden.

Die Bereitstellung dauert in der Regel 15 bis 20 Minuten.

Überprüfen Sie die Bereitstellung

Überprüfen Sie nach Abschluss der Bereitstellung, ob der Cluster und der Knotenpool erfolgreich erstellt wurden.

  1. Stellen Sie sicher, dass der Cluster erfolgreich erstellt wurde.

    az aro hcp cluster show \
      --name "${CLUSTER_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --query "properties.provisioningState" \
      --output tsv
    

    Wenn der Cluster bereit ist, ist die Ausgabe Succeeded.

  2. Stellen Sie sicher, dass der Knotenpool erfolgreich erstellt wurde.

    az aro hcp cluster nodepool show \
      --cluster-name "${CLUSTER_NAME}" \
      --name "${NP_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --query "properties.provisioningState" \
      --output tsv
    

    Wenn der Knotenpool bereit ist, ist die Ausgabe Succeeded.

Erstellen der Netzwerkinfrastruktur

Erstellen Sie eine Netzwerksicherheitsgruppe, ein virtuelles Netzwerk mit einem Arbeitssubnetz und ein VNet-Integrationssubnetz mit Delegierung.

  1. Erstellen Sie die Netzwerksicherheitsgruppe (NSG).

    Note

    Wenn Sie der NSG benutzerdefinierte Regeln hinzufügen, stellen Sie sicher, dass der datenverkehr zulässig ist, der in "Erforderlicher Netzwerksicherheitsgruppendatenverkehr" beschrieben ist.

    az network nsg create \
      --name "${CUSTOMER_NSG}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --location "${LOCATION}"
    
  2. Erstellen Sie das virtuelle Netzwerk mit dem Worker-Subnetz.

    az network vnet create \
      --name "${CUSTOMER_VNET_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --location "${LOCATION}" \
      --address-prefixes 10.0.0.0/16 \
      --subnet-name "${CUSTOMER_VNET_SUBNET1}" \
      --subnet-prefixes 10.0.0.0/24 \
      --nsg "${CUSTOMER_NSG}"
    
  3. Erstellen Sie das Subnetz für die VNet-Integration mit der erforderlichen Delegierung.

    az network vnet subnet create \
      --name "${CUSTOMER_VNET_INTEGRATION_SUBNET_NAME}" \
      --vnet-name "${CUSTOMER_VNET_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --address-prefixes 10.0.1.0/24 \
      --network-security-group "${CUSTOMER_NSG}" \
      --delegations Microsoft.RedHatOpenShift/hcpOpenShiftClusters
    
  4. Rufen Sie die Ressourcen-IDs für die Netzwerkressourcen ab.

    NSG_ID=$(az network nsg show \
      --name "${CUSTOMER_NSG}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --query id --output tsv)
    
    SUBNET_ID=$(az network vnet subnet show \
      --name "${CUSTOMER_VNET_SUBNET1}" \
      --vnet-name "${CUSTOMER_VNET_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --query id --output tsv)
    
    VNET_ID=$(az network vnet show \
      --name "${CUSTOMER_VNET_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --query id --output tsv)
    
    VNET_INTEGRATION_SUBNET_ID=$(az network vnet subnet show \
      --name "${CUSTOMER_VNET_INTEGRATION_SUBNET_NAME}" \
      --vnet-name "${CUSTOMER_VNET_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --query id --output tsv)
    

Erstellen der verwalteten Identitäten

Erstellen Sie die vom Benutzer zugewiesenen verwalteten Identitäten für die Clusteroperatoren und die vom Dienst verwaltete Identität. Eine Beschreibung der einzelnen Identitäten und ihres Zwecks finden Sie unter Erforderliche verwaltete Identitäten und Rollenzuweisungen.

# Control plane operator identities
az identity create --name "${CLUSTER_NAME}-cp-cluster-api-azure" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-control-plane" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-cloud-controller-manager" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-ingress" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-image-registry" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-cloud-network-config" --resource-group "${CUSTOMER_RG_NAME}"

# Data plane operator identities
az identity create --name "${CLUSTER_NAME}-dp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-dp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-dp-image-registry" --resource-group "${CUSTOMER_RG_NAME}"

# Service managed identity
az identity create --name "${CLUSTER_NAME}-service-managed-identity" --resource-group "${CUSTOMER_RG_NAME}"

Rufen Sie die Ressourcen-IDs und Prinzipal-IDs der verwalteten Identitäten ab.

# Control plane identity resource IDs and principal IDs
CLUSTER_API_AZURE_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-cluster-api-azure" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CLUSTER_API_AZURE_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-cluster-api-azure" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

CONTROL_PLANE_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-control-plane" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CONTROL_PLANE_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-control-plane" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

CLOUD_CONTROLLER_MANAGER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-controller-manager" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CLOUD_CONTROLLER_MANAGER_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-controller-manager" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

INGRESS_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-ingress" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
INGRESS_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-ingress" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

DISK_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)

FILE_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
FILE_CSI_DRIVER_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

IMAGE_REGISTRY_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
IMAGE_REGISTRY_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

CLOUD_NETWORK_CONFIG_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-network-config" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CLOUD_NETWORK_CONFIG_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-network-config" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

# Data plane identity resource IDs and principal IDs
DP_DISK_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-dp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)

DP_FILE_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-dp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
DP_FILE_CSI_DRIVER_MI_PID=$(az identity show --name "${CLUSTER_NAME}-dp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

DP_IMAGE_REGISTRY_MI_ID=$(az identity show --name "${CLUSTER_NAME}-dp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
DP_IMAGE_REGISTRY_MI_PID=$(az identity show --name "${CLUSTER_NAME}-dp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

# Service managed identity resource ID and principal ID
SERVICE_MI_ID=$(az identity show --name "${CLUSTER_NAME}-service-managed-identity" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
SERVICE_MI_PID=$(az identity show --name "${CLUSTER_NAME}-service-managed-identity" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)

Erstellen der Rollenzuweisungen

Weisen Sie jeder verwalteten Identität die erforderlichen Azure Rollen zu. Eine detaillierte Beschreibung der einzelnen Identitäten und der erforderlichen Rollenzuweisungen finden Sie unter Erforderliche verwaltete Identitäten und Rollenzuweisungen.

  1. Legen Sie die Rollendefinitions-GUIDs fest.

    READER_ROLE="acdd72a7-3385-48ef-bd42-f606fba81ae7"
    HCP_CLUSTER_API_PROVIDER_ROLE="88366f10-ed47-4cc0-9fab-c8a06148393e"
    HCP_CONTROL_PLANE_OPERATOR_ROLE="fc0c873f-45e9-4d0d-a7d1-585aab30c6ed"
    CLOUD_CONTROLLER_MANAGER_ROLE="a1f96423-95ce-4224-ab27-4e3dc72facd4"
    INGRESS_OPERATOR_ROLE="0336e1d3-7a87-462b-b6db-342b63f7802c"
    FILE_STORAGE_OPERATOR_ROLE="0d7aedc0-15fd-4a67-a412-efad370c947e"
    NETWORK_OPERATOR_ROLE="be7a6435-15ae-4171-8f30-4a343eff9e8f"
    FEDERATED_CREDENTIAL_ROLE="ef318e2a-8334-4a05-9e4a-295a196c6a6e"
    HCP_SERVICE_MI_ROLE="c0ff367d-66d8-445e-917c-583feb0ef0d4"
    IMAGE_REGISTRY_OPERATOR_ROLE="8b32b316-c2f5-4ddf-b05b-83dacd2d08b5"
    
  2. Weisen Sie Steuerungsebenenoperatorrollen zu.

    # Cluster API Azure → ARO HCP Cluster API Provider on worker subnet
    az role assignment create --assignee-object-id "${CLUSTER_API_AZURE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CLUSTER_API_PROVIDER_ROLE}" --scope "${SUBNET_ID}"
    az role assignment create --assignee-object-id "${CLUSTER_API_AZURE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CLUSTER_API_PROVIDER_ROLE}" --scope "${VNET_ID}"
    
    # Control Plane → ARO HCP Control Plane Operator on VNet and NSG
    az role assignment create --assignee-object-id "${CONTROL_PLANE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CONTROL_PLANE_OPERATOR_ROLE}" --scope "${VNET_ID}"
    az role assignment create --assignee-object-id "${CONTROL_PLANE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CONTROL_PLANE_OPERATOR_ROLE}" --scope "${NSG_ID}"
    
    # Cloud Controller Manager → ARO Cloud Controller Manager on worker subnet and NSG
    az role assignment create --assignee-object-id "${CLOUD_CONTROLLER_MANAGER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${CLOUD_CONTROLLER_MANAGER_ROLE}" --scope "${SUBNET_ID}"
    az role assignment create --assignee-object-id "${CLOUD_CONTROLLER_MANAGER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${CLOUD_CONTROLLER_MANAGER_ROLE}" --scope "${NSG_ID}"
    az role assignment create --assignee-object-id "${CLOUD_CONTROLLER_MANAGER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${CLOUD_CONTROLLER_MANAGER_ROLE}" --scope "${VNET_ID}"
    
    # Ingress → ARO Cluster Ingress Operator on worker subnet
    az role assignment create --assignee-object-id "${INGRESS_MI_PID}" --assignee-principal-type ServicePrincipal --role "${INGRESS_OPERATOR_ROLE}" --scope "${SUBNET_ID}"
    az role assignment create --assignee-object-id "${INGRESS_MI_PID}" --assignee-principal-type ServicePrincipal --role "${INGRESS_OPERATOR_ROLE}" --scope "${VNET_ID}"
    
    # File CSI Driver → ARO File Storage Operator on worker subnet and NSG
    az role assignment create --assignee-object-id "${FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${SUBNET_ID}"
    az role assignment create --assignee-object-id "${FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${NSG_ID}"
    az role assignment create --assignee-object-id "${FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${VNET_ID}"
    
    # Cloud Network Config → ARO Network Operator on worker subnet and VNet
    az role assignment create --assignee-object-id "${CLOUD_NETWORK_CONFIG_MI_PID}" --assignee-principal-type ServicePrincipal --role "${NETWORK_OPERATOR_ROLE}" --scope "${SUBNET_ID}"
    az role assignment create --assignee-object-id "${CLOUD_NETWORK_CONFIG_MI_PID}" --assignee-principal-type ServicePrincipal --role "${NETWORK_OPERATOR_ROLE}" --scope "${VNET_ID}"
    
    # Image Registry → ARO Image Registry Operator on VNet
    az role assignment create --assignee-object-id "${IMAGE_REGISTRY_MI_PID}" --assignee-principal-type ServicePrincipal --role "${IMAGE_REGISTRY_OPERATOR_ROLE}" --scope "${VNET_ID}"
    
  3. Weisen Sie Rollen für dienstverwaltete Identitäten zu.

    # Service MI → ARO HCP Service Managed Identity on VNet and NSG
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_SERVICE_MI_ROLE}" --scope "${VNET_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_SERVICE_MI_ROLE}" --scope "${NSG_ID}"
    
    # Service MI → Reader on each control plane identity
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CLUSTER_API_AZURE_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CONTROL_PLANE_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CLOUD_CONTROLLER_MANAGER_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${INGRESS_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${DISK_CSI_DRIVER_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${FILE_CSI_DRIVER_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${IMAGE_REGISTRY_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CLOUD_NETWORK_CONFIG_MI_ID}"
    
  4. Weisen Sie Datenebenenoperatorrollen zu.

    # Service MI → ARO Federated Credential on each data plane identity
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FEDERATED_CREDENTIAL_ROLE}" --scope "${DP_DISK_CSI_DRIVER_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FEDERATED_CREDENTIAL_ROLE}" --scope "${DP_FILE_CSI_DRIVER_MI_ID}"
    az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FEDERATED_CREDENTIAL_ROLE}" --scope "${DP_IMAGE_REGISTRY_MI_ID}"
    
    # Data Plane File CSI Driver → ARO File Storage Operator on worker subnet and NSG
    az role assignment create --assignee-object-id "${DP_FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${SUBNET_ID}"
    az role assignment create --assignee-object-id "${DP_FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${NSG_ID}"
    az role assignment create --assignee-object-id "${DP_FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${VNET_ID}"
    
    # Data Plane Image Registry → ARO Image Registry Operator on VNet
    az role assignment create --assignee-object-id "${DP_IMAGE_REGISTRY_MI_PID}" --assignee-principal-type ServicePrincipal --role "${IMAGE_REGISTRY_OPERATOR_ROLE}" --scope "${VNET_ID}"
    

Einrichten der kundenverwalteten etcd-Verschlüsselung

Azure Red Hat OpenShift mit gehosteten Steuerungsebenen verschlüsselt die etcd-Daten mithilfe von vom Kunden verwalteten Schlüsseln.

Erstellen der verwalteten KMS-Identität

  1. Legen Sie Umgebungsvariablen für den Key Vault- und KMS-Schlüssel fest.

    KEYVAULT_NAME="<key-vault-name>"
    KMS_KEY_NAME="etcd-kms-key"
    
  2. Erstellen Sie die verwaltete KMS-Identität.

    az identity create --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}"
    
  3. Rufen Sie die Ressourcen-ID und die Prinzipal-ID für die verwaltete Identität von KMS ab.

    KMS_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
    KMS_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
    

Erstellen der KMS-Rollenzuweisungen

Weisen Sie der dienstverwalteten Identität die Rolle „Leser“ für die KMS-verwaltete Identität zu.

az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${KMS_MI_ID}"

Erstellen des Key Vault- und KMS-Schlüssels

Erstellen Sie einen Azure Key Vault mit RBAC-Autorisierung und einen 2048-Bit-RSA-Verschlüsselungsschlüssel für die kundenseitig verwaltete etcd-Verschlüsselung.

  1. Erstellen Sie die Key Vault.

    az keyvault create \
      --name "${KEYVAULT_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --location "${LOCATION}" \
      --enable-rbac-authorization true
    
  2. Weisen Sie sich selbst die Key Vault Crypto Officer-Benutzerrolle zu. Diese Rolle gewährt Ihnen die Berechtigungen zum Erstellen des KMS-Verschlüsselungsschlüssels.

    az role assignment create \
      --role "Key Vault Crypto Officer" \
      --assignee "$(az account show --query user.name -o tsv)" \
      --scope "$(az keyvault show --name "${KEYVAULT_NAME}" --resource-group "${CUSTOMER_RG_NAME}" --query id -o tsv)"
    
    
  3. Erstellen Sie den KMS-Verschlüsselungsschlüssel.

    az keyvault key create \
      --vault-name "${KEYVAULT_NAME}" \
      --name "${KMS_KEY_NAME}" \
      --kty RSA \
      --size 2048
    
  4. Rufen Sie die Schlüsselversion ab.

    KMS_KEY_VERSION=$(az keyvault key show \
      --vault-name "${KEYVAULT_NAME}" \
      --name "${KMS_KEY_NAME}" \
      --query "key.kid" --output tsv | rev | cut -d'/' -f1 | rev)
    
  5. Weisen Sie der verwalteten KMS-Identität auf dem Key Vault die Rolle "Key Vault Crypto User" zu.

    KEY_VAULT_CRYPTO_USER_ROLE="12338af0-0e69-4776-bea7-57ae8d297424"
    KEYVAULT_ID=$(az keyvault show --name "${KEYVAULT_NAME}" --query id --output tsv)
    
    az role assignment create \
      --assignee-object-id "${KMS_MI_PID}" \
      --assignee-principal-type ServicePrincipal \
      --role "${KEY_VAULT_CRYPTO_USER_ROLE}" \
      --scope "${KEYVAULT_ID}"
    

(Optional) Einschränken des Key Vault Zugriffs auf einen privaten Endpunkt

Wenn Sie Key Vault Zugriff auf einen privaten Endpunkt einschränken möchten, erstellen Sie die folgenden Ressourcen. Wenn Sie keine private Key Vault benötigen, fahren Sie mit dem Erstellen des Clusters fort.

Von Bedeutung

Die Schritte in diesem Abschnitt konfigurieren nur den privaten Zugriff in Azure Key Vault. Wenn Sie Ihr Azure Red Hat OpenShift-Cluster mit gehosteten Steuerungsebenen erstellen, legen Sie auch --vault-visibility Private fest. Beide Einstellungen müssen übereinstimmen.

  1. Deaktivieren Sie den öffentlichen Netzwerkzugriff auf den Key Vault.

    az keyvault update \
      --name "${KEYVAULT_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --public-network-access Disabled
    
  2. Erstellen Sie einen privaten Endpunkt für die Key Vault.

    az network private-endpoint create \
      --name "kv-private-endpoint" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --vnet-name "${CUSTOMER_VNET_NAME}" \
      --subnet "${CUSTOMER_VNET_SUBNET1}" \
      --private-connection-resource-id "${KEYVAULT_ID}" \
      --group-ids vault \
      --connection-name "kv-private-endpoint"
    
  3. Erstellen Sie eine private DNS-Zone, und verknüpfen Sie sie mit dem virtuellen Netzwerk.

    az network private-dns zone create \
      --name "privatelink.vaultcore.azure.net" \
      --resource-group "${CUSTOMER_RG_NAME}"
    
    az network private-dns link vnet create \
      --name "kv-private-dns-zone-link" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --zone-name "privatelink.vaultcore.azure.net" \
      --virtual-network "${CUSTOMER_VNET_NAME}" \
      --registration-enabled false
    
  4. Erstellen Sie eine DNS-Zonengruppe für den privaten Endpunkt.

    az network private-endpoint dns-zone-group create \
      --name "kv-private-ep-dns-group" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --endpoint-name "kv-private-endpoint" \
      --private-dns-zone "privatelink.vaultcore.azure.net" \
      --zone-name "config1"
    

Erstellen Sie den Cluster.

Erstellen Sie den Azure Red Hat OpenShift-Cluster mit gehosteten Steuerungsebenen mithilfe der Netzwerkinfrastruktur, verwalteten Identitäten und Rollenzuweisungen, die Sie in den vorherigen Schritten konfiguriert haben.

Note

Informationen zu allen anpassbaren Clusterparametern finden Sie in der Befehlshilfe (az aro hcp cluster create -h).

Erstellen Sie den Cluster mit dem folgenden Befehl:

az aro hcp cluster create \
  --name "${CLUSTER_NAME}" \
  --resource-group "${CUSTOMER_RG_NAME}" \
  --location "${LOCATION}" \
  --version "${CLUSTER_VERSION}" \
  --channel-group stable \
  --subnet-id "${SUBNET_ID}" \
  --vnet-integration-subnet-id "${VNET_INTEGRATION_SUBNET_ID}" \
  --nsg "${NSG_ID}" \
  --managed-resource-group-name "${MANAGED_RESOURCE_GROUP}" \
  --key-management-mode CustomerManaged \
  --etcd-encryption-type KMS \
  --kms-vault-name "${KEYVAULT_NAME}" \
  --vault-visibility <Public-or-Private> \
  --kms-active-key "{name:${KMS_KEY_NAME},version:${KMS_KEY_VERSION}}" \
  --api-visibility <Public-or-Private> \
  --ingress-visibility <Public-or-Private> \
  --user-assigned-identities "{${SERVICE_MI_ID}:{},${CLUSTER_API_AZURE_MI_ID}:{},${CONTROL_PLANE_MI_ID}:{},${CLOUD_CONTROLLER_MANAGER_MI_ID}:{},${INGRESS_MI_ID}:{},${DISK_CSI_DRIVER_MI_ID}:{},${FILE_CSI_DRIVER_MI_ID}:{},${IMAGE_REGISTRY_MI_ID}:{},${CLOUD_NETWORK_CONFIG_MI_ID}:{},${KMS_MI_ID}:{}}" \
  --operators-authentication "{user-assigned-identities:{control-plane-operators:{cluster-api-azure:${CLUSTER_API_AZURE_MI_ID},control-plane:${CONTROL_PLANE_MI_ID},cloud-controller-manager:${CLOUD_CONTROLLER_MANAGER_MI_ID},ingress:${INGRESS_MI_ID},disk-csi-driver:${DISK_CSI_DRIVER_MI_ID},file-csi-driver:${FILE_CSI_DRIVER_MI_ID},image-registry:${IMAGE_REGISTRY_MI_ID},cloud-network-config:${CLOUD_NETWORK_CONFIG_MI_ID},kms:${KMS_MI_ID}},data-plane-operators:{disk-csi-driver:${DP_DISK_CSI_DRIVER_MI_ID},file-csi-driver:${DP_FILE_CSI_DRIVER_MI_ID},image-registry:${DP_IMAGE_REGISTRY_MI_ID}},service-managed-identity:${SERVICE_MI_ID}}}"

Wenn Sie den Key Vault auf einen privaten Endpunkt beschränkt haben, setzen Sie --vault-visibility auf Private statt auf Public, damit Ihre Clustereinstellung mit der Azure Key Vault-Netzwerkkonfiguration übereinstimmt.

Setzen Sie --api-visibility auf Public für einen über das Internet erreichbaren API-Server oder auf Private für einen API-Server, der nur über eine private Netzwerkverbindung erreichbar ist.

Setzen Sie --ingress-visibility auf Public für Anwendungsrouten mit Internetzugang oder auf Private für Anwendungsrouten, die nur über eine private Netzwerkverbindung erreichbar sind.


Die Bereitstellung dauert in der Regel 15 bis 20 Minuten.

Stellen Sie sicher, dass der Cluster erfolgreich erstellt wurde.

az aro hcp cluster show \
  --name "${CLUSTER_NAME}" \
  --resource-group "${CUSTOMER_RG_NAME}" \
  --query "properties.provisioningState" \
  --output tsv

Wenn der Cluster bereit ist, ist die Ausgabe Succeeded.

Erstellen des Knotenpools

Erstellen Sie einen Knotenpool, um Ihrem Cluster Arbeitskapazität hinzuzufügen. Mit dem folgenden Befehl wird ein Knotenpool mit zwei Standard_D8s_v3 Arbeitsknoten erstellt.

Von Bedeutung

Stellen Sie vor dem Erstellen des Knotenpools sicher, dass die NSG-Regeln den erforderlichen Datenverkehr zulassen, der in Plan your cluster network beschrieben ist. Eine passende Deny-Regel kann verhindern, dass der Knotenpool die Bereitstellung abschließt.

az aro hcp cluster nodepool create \
  --cluster-name "${CLUSTER_NAME}" \
  --name "${NP_NAME}" \
  --resource-group "${CUSTOMER_RG_NAME}" \
  --replicas 2 \
  --vm-size Standard_D8s_v3 \
  --version "${NP_VERSION}" \
  --channel-group stable

Stellen Sie sicher, dass der Knotenpool erfolgreich erstellt wurde.

az aro hcp cluster nodepool show \
  --cluster-name "${CLUSTER_NAME}" \
  --name "${NP_NAME}" \
  --resource-group "${CUSTOMER_RG_NAME}" \
  --query "properties.provisioningState" \
  --output tsv

Wenn der Knotenpool bereit ist, ist die Ausgabe Succeeded.

Bicep Dateireferenz

Im Beispiel Bicep Datei wird ein Cluster mit Standardkonfigurationswerten bereitgestellt. In diesem Abschnitt werden die einzelnen Ressourcen und Eigenschaften in der datei Bicep beschrieben, die Sie vor der Bereitstellung anpassen können.

Netzwerkressourcen

Die datei Bicep definiert eine Netzwerksicherheitsgruppe (Network Security Group, NSG), ein virtuelles Netzwerk mit einem Arbeitssubnetz und ein VNet-Integrationssubnetz und die Subnetzdelegierung für das VNet-Integrationssubnetz. Informationen zu den Anforderungen an die Subnetzgröße, die Platzierung und die NSG-Anforderungen finden Sie unter Planen Ihres Clusternetzwerks.

Verwaltete Identitäten und Rollenzuweisungen

Die datei Bicep definiert eine vom Benutzer zugewiesene verwaltete Identität für jeden OpenShift-Clusteroperator und Rollenzuweisungen, die jeder Identität die erforderlichen Berechtigungen erteilen. Eine detaillierte Beschreibung der einzelnen Identitäten und der erforderlichen Rollenzuweisungen finden Sie unter Erforderliche verwaltete Identitäten und Rollenzuweisungen.

Etcd-Verschlüsselungsressourcen

Die Bicep-Datei enthält die folgenden Ressourcen für die vom Kunden verwaltete etcd-Verschlüsselung:

  • KMS managed Identity – Eine vom Benutzer zugewiesene verwaltete Identität für den Zugriff auf den KMS-Schlüssel. Diese Identität erfordert Folgendes:
    • Eine Rollenzuweisung für die Rolle „Key Vault Crypto User“ mit Geltungsbereich auf den Azure Key Vault
    • Eine Zuweisung der Rolle „Leser“, die der dienstverwalteten Identität Lesezugriff auf die verwaltete KMS-Identität gewährt
  • Azure Key Vault – Ein Azure Key Vault mit aktivierter RBAC-Autorisierung
  • KMS-Verschlüsselungsschlüssel – In der Key Vault erstellter RSA 2048-Schlüssel

Wenn Sie den privateKeyVault Parameter auf truefestlegen, stellt die Bicep Datei auch die folgenden Ressourcen bereit, um den Zugriff auf die Key Vault auf einen privaten Endpunkt einzuschränken:

  • Ein privater Endpunkt für die Key Vault
  • Eine private DNS-Zone (privatelink.vaultcore.azure.net)
  • Eine private DNS-Zonengruppe, die den privaten Endpunkt der DNS-Zone zuordnet
  • Eine virtuelle Netzwerkverbindung, die die private DNS-Zone mit dem virtuellen Clusternetzwerk verbindet

Clusterressourceneigenschaften

Die Clusterressource (Microsoft.RedHatOpenShift/hcpOpenShiftClusters) definiert die Konfiguration für Ihren Cluster. Weitere Informationen zu den einzelnen Konfigurationsoptionen finden Sie unter "Auswählen ihrer dauerhaften Clustereinstellungen".

Property Erforderlich Beschreibung
version.id Ja Die zu installierende OpenShift-Nebenversion. Beispiel: 4.20 Informationen zum Auflisten der verfügbaren Versionen finden Sie unter Auflisten verfügbarer OpenShift-Versionen.
version.channelGroup Ja Der OpenShift-Updatekanal. Die einzige unterstützte Option ist stable.
dns.baseDomainPrefix No Ein benutzerdefiniertes Präfix für den Basisdomänennamen des Clusters. Maximale Länge von 15 Zeichen. Muss mit einem Kleinbuchstaben beginnen und darf nur Kleinbuchstaben, Zahlen und Bindestriche (-) enthalten.
network.networkType No Das Container Network Interface (CNI)-Plug-In. Gültige Werte sind OVNKubernetes (Standard) oder Other.
network.podCidr No Der IP-Adressbereich für Pods. Standardwert: 10.128.0.0/14.
network.serviceCidr No Der IP-Adressbereich für Dienste. Standardwert: 172.30.0.0/16.
network.machineCidr No Der IP-Adressbereich für Computeknoten. Standardwert: 10.0.0.0/16.
network.hostPrefix No Die Länge des Subnetzpräfixes, die jedem Knoten für seine Pods zugewiesen ist. Standardwert: 23.
api.visibility No Die Sichtbarkeit des API-Servers. Gültige Werte sind Public (Standard) oder Private. Diese Einstellung ist unveränderlich.
api.authorizedCidrs No Eine Liste der autorisierten CIDR-Blöcke (nur IPv4), die für den Zugriff auf den API-Server zulässig sind. Maximal 500 Einträge.
ingress.type No Der Typ des Standard-Cluster-Ingress. Gültige Werte sind Public (Standard) oder Private. Diese Einstellung ist unveränderlich.
cryptoRestrictions No Kryptografische Einschränkungen für Kernel- und Benutzerraumbibliotheken. Gültige Werte sind None (Standard) oder FIPS. Bei Festlegung auf FIPS" verwenden alle kryptografischen Vorgänge FIPS-validierte Module, und alle Knotenpools erben die FIPS-Konfiguration. Diese Einstellung ist nach der Clustererstellung unveränderlich.
etcd.dataEncryption.keyManagementMode Ja Der Verwaltungsmodus des Verschlüsselungsschlüssels. Der einzige unterstützte Wert lautet CustomerManaged.
etcd.dataEncryption.customerManaged.encryptionType Ja Der Verschlüsselungstyp. Der einzige unterstützte Wert lautet KMS.
etcd.dataEncryption.customerManaged.kms.vaultName Ja Der Name des Azure Key Vault.
etcd.dataEncryption.customerManaged.kms.visibility Ja Wie Ihr Azure Red Hat OpenShift-Cluster mit gehosteten Steuerungsebenen den Key Vault erreicht. Gültige Werte sind Public oder Private. Wenn Sie diese Einstellung Privatefestlegen, müssen Sie auch den öffentlichen Netzwerkzugriff auf die Key Vault deaktivieren und einen privaten Endpunkt im virtuellen Clusternetzwerk erstellen.
etcd.dataEncryption.customerManaged.kms.activeKey.name Ja Der Name des Verschlüsselungsschlüssels.
etcd.dataEncryption.customerManaged.kms.activeKey.version Ja Die Version des Verschlüsselungsschlüssels.
clusterImageRegistry.state No Der Status der internen Imageregistrierung. Gültige Werte sind Enabled (Standard) oder Disabled.
platform.managedResourceGroup No Der Name für die verwaltete Ressourcengruppe. Maximale Länge von 90 Zeichen.
platform.subnetId Ja Die Azure-Ressourcen-ID des Worker-Subnetzes.
platform.vnetIntegrationSubnetId Ja Die Azure-Ressourcen-ID des VNet-Integrationssubnetzes.
platform.outboundType No Das Modell für ausgehende Konnektivität. Der einzige unterstützte Wert lautet loadBalancer.
platform.networkSecurityGroupId Ja Die Azure Ressourcen-ID der Netzwerksicherheitsgruppe.
platform.operatorsAuthentication Ja Die verwalteten Identitätszuweisungen für die Clusteroperatoren.
autoscaling.maxNodesTotal No Die maximale Anzahl von Knoten, die vom Cluster autoscaler erstellt werden können. Standard: 0 (keine Begrenzung).
autoscaling.maxPodGracePeriodSeconds No Die maximale Anzahl an Sekunden für die ordnungsgemäße Beendigung von Pods vor dem Herunterskalieren.
autoscaling.maxNodeProvisionTimeSeconds No Die maximalen Sekunden für die Knotenbereitstellung. Standardwert: 900.
autoscaling.podPriorityThreshold No Der Prioritätsschwellenwert, unter dem Pods vom Autoscaler als „best-effort“ behandelt werden. Standardwert: -10.
imageDigestMirrors No Mirror-Einträge für Image-Digests, die Image-Abrufe von einer Quell-Registry zu Mirror-Registries umleiten. Maximal 240 Einträge.
nodeDrainTimeoutMinutes No Der Standardmäßige Knotenabfluss-Karenzzeitraum für alle Knotenpools in Minuten. Bereich: 0 bis 10080. Standard: 0 (kein Zeitlimit).
identity.type Ja Der Identitätstyp. Muss UserAssignedlauten.
identity.userAssignedIdentities Ja Eine Zuordnung der vom Benutzer zugewiesenen verwalteten Identitätsressourcen-IDs.

Ressourceneigenschaften des Knotenpools

Die Node-Pool-Ressource (Microsoft.RedHatOpenShift/hcpOpenShiftClusters/nodePools) definiert eine Gruppe von Worker-Knoten, die dieselbe Konfiguration gemeinsam nutzen.

Property Erforderlich Beschreibung
version.id Ja Die OpenShift-Patchversion für diesen Knotenpool. Beispiel: 4.20.8 Die Knotenpool-Version muss eine Patchversion innerhalb der Minor-Version des Clusters sein. Informationen zum Auflisten der verfügbaren Versionen finden Sie unter Auflisten verfügbarer OpenShift-Versionen.
version.channelGroup Ja Der OpenShift-Updatekanal. Die einzige unterstützte Option ist stable.
platform.vmSize Ja Die Größe der virtuellen Azure-Maschine für die Knoten. Informationen zum Auflisten verfügbarer VM-Größen finden Sie unter "Auflisten verfügbarer VM-Größen".
platform.subnetId Ja Die Azure Ressourcen-ID des Subnetzes. Wenn Sie diese Eigenschaft nicht angeben, verwendet der Knotenpool das Worker-Subnetz des Clusters.
platform.osDisk.diskSizeGiB No Die Größe der Betriebssystem-Festplatte in GiB. Minimum: 16.
platform.osDisk.diskStorageAccountType No Der Datenträgerspeicherkontotyp. Gültige Werte sind Premium_LRS, StandardSSD_LRSoder Standard_LRS.
platform.osDisk.encryptionSetId No Die Azure Ressourcen-ID eines DiskEncryptionSet zum Verschlüsseln von Betriebssystemdatenträgern.
platform.osDisk.diskType No Der Betriebssystemdatenträgertyp. Gültige Werte sind Managed oder Ephemeral.
platform.availabilityZone No Die Azure Verfügbarkeitszone für den Knotenpool.
platform.enableEncryptionAtHost No Aktiviert die Verschlüsselung auf Hostebene für VMs. Standardwert: false.
replicas Bedingt Die Anzahl der Knoten. Erforderlich, wenn autoScaling nicht konfiguriert ist.
autoScaling.min Bedingt Die minimale Knotenanzahl. Erforderlich, wenn replicas nicht konfiguriert ist.
autoScaling.max Bedingt Die maximale Knotenanzahl. Erforderlich, wenn replicas nicht konfiguriert ist.
autoRepair No Aktiviert Zustandsprüfungen für Knoten. Standardwert: true.
labels No Kubernetes-Bezeichnungen, die auf Knoten angewendet werden, als Array von Schlüsselwertpaaren.
taints No Kubernetes-Taints, die auf Knoten angewendet werden. Jeder Taint hat ein key, value und effect (NoSchedule, PreferNoSchedule oder NoExecute).
nodeDrainTimeoutMinutes No Die Schonfrist für das Drainen von Knoten für diesen Knotenpool in Minuten. Überschreibt den Standard des Clusters. Bereich: 0 bis 10080.

Auflisten verfügbarer OpenShift-Versionen

Der Cluster version.id verwendet eine Minor-Version (z. B. 4.20), während der Knotenpool version.id eine Patch-Version verwendet (z. B. 4.20.8). Führen Sie den folgenden Befehl aus, um die verfügbaren OpenShift-Versionen in Ihrer Region auflisten zu können:

az aro hcp version list --location "${LOCATION}" --output table

Auflisten der verfügbaren VM-Größen

Die Verfügbarkeit von VM-Größen hängt von der Azure Region Ihres Clusters ab. Führen Sie den folgenden Befehl aus, um die in Ihrer Region verfügbaren VM-Größen auflisten zu können:

az vm list-sizes --location "${LOCATION}" --output table

Eine Liste der unterstützten VM-Größen für den Arbeitsknoten für Azure Red Hat OpenShift mit gehosteten Steuerebenen finden Sie unter Unterstützte Größe virtueller Computer. Verwenden Sie die regionale Liste, um zu bestätigen, dass eine unterstützte Größe am Standort Ihres Clusters verfügbar ist.

Nächste Schritte