Criar um cluster do Azure Red Hat OpenShift com planos de controlo alojados (pré-visualização)

Este artigo descreve como criar um cluster Azure Red Hat OpenShift com planos de controlo alojados (HCP) usando o CLI do Azure ou um ficheiro Bicep.

O ficheiro Bicep define todos os recursos Azure necessários para o cluster, incluindo a infraestrutura de rede, identidades geridas, atribuições de funções, configuração do cluster e pool de nós.

Os comandos CLI criam todos os recursos Azure necessários para o cluster, incluindo a infraestrutura de rede, identidades geridas, atribuições de papéis, configuração do cluster e pool de nós.

Pré-requisitos

Prepare seu ambiente

Antes de criar o cluster, verifique se o seu ambiente Azure cumpre os seguintes requisitos.

CLI do Azure (Interface de Linha de Comando da Azure)

Verifique se você está usando a CLI do Azure versão 2.67.0 ou superior. Usa az --version para verificar a versão instalada. Para instalar ou atualizar, consulte Install CLI do Azure.

Extensão do CLI ARO HCP

  1. Instale a extensão.

    az extension add --name aro
    
  2. Verifique se a extensão está instalada:

    az aro hcp -h
    

Quota de recursos

O Azure Red Hat OpenShift com planos de controlo alojados requer pelo menos 20 núcleos para criar e executar um cluster. A quota de recursos predefinida de uma nova subscrição do Azure não cumpre este requisito. Para solicitar um aumento do seu limite de recursos, consulte a quota Padrão: Aumentar os limites por série de VMs. Verifica se tens quota suficiente para a família de VMs que escolheres entre os tamanhos de VM dos nós de trabalho suportados.

Para verificar a quota atual da família de máquinas virtuais predefinida:

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

Permissões

Precisa de permissões de Colaborador e de Administrador de Acesso de Utilizador, ou permissões de Proprietário, no grupo de recursos ou na subscrição onde cria o cluster. Estas permissões são necessárias para criar o grupo de recursos, a rede virtual, as identidades geridas e as atribuições de funções.

Para mais informações, consulte Verificar as suas permissões.

Registrar provedores de recursos

Registe os seguintes fornecedores de recursos na sua subscrição do Azure:

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

Para verificar se um fornecedor de recursos está registado:

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

Se encontrar algum prestador de recursos que não esteja registado, inscreva-os.

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

Para mais informações sobre como registar fornecedores de recursos, consulte Registar os fornecedores de recursos.

Definir variáveis de ambiente

Defina as seguintes variáveis de ambiente para definir os nomes dos recursos que cria. Substitui os valores provisórios pelos teus próprios.

# 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

Para mais informações sobre os requisitos de versão do cluster e do conjunto de nós, consulte as combinações de versões suportadas.

Note

Para uma lista das regiões suportadas, veja Escolher a região do cluster.

Criar um grupo de recursos

Crie um grupo de recursos para armazenar o recurso do cluster, a rede virtual e as identidades geridas.

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

Criar o arquivo Bicep

Crie um arquivo nomeado azuredeploy.bicep com o seguinte conteúdo. Este modelo Bicep define todos os recursos necessários para implementar um cluster do Azure Red Hat OpenShift com planos de controlo alojados, incluindo o grupo de segurança de rede, a rede virtual, as identidades geridas, as atribuições de funções, o Key Vault, a chave de encriptação do KMS, o cluster e o conjunto de nós.

O modelo implementa um cluster com rede OVN-Kubernetes com intervalos CIDR predefinidos, encriptação etcd gerida pelo cliente, conectividade de saída do balanceador de carga e um único pool de nós com dois Standard_D8s_v6 nós trabalhadores.

Para personalizar a configuração do cluster ou do pool de nós, consulte a referência do ficheiro Bicep.

Note

Se adicionar regras personalizadas ao grupo de segurança de rede (NSG), certifique-se de que o NSG permite o tráfego descrito em Tráfego obrigatório do grupo de segurança de rede.

@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 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 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 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 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 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 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: [
    hcpClusterApiProviderRoleVnetAssignment
    keyVaultCryptoUserToKeyVaultRoleAssignment
    hcpControlPlaneOperatorVnetRoleAssignment
    hcpControlPlaneOperatorNsgRoleAssignment
    cloudControllerManagerRoleNsgAssignment
    cloudControllerManagerRoleVnetAssignment
    ingressOperatorRoleVnetAssignment
    fileStorageOperatorRoleNsgAssignment
    fileStorageOperatorRoleVnetAssignment
    networkOperatorRoleVnetAssignment
    dpDiskCsiDriverMiFederatedCredentialsRoleAssignment
    dpFileCsiDriverMiFederatedCredentialsRoleAssignment
    dpImageRegistryMiFederatedCredentialsRoleAssignment
    serviceManagedIdentityRoleAssignmentVnet
    serviceManagedIdentityRoleAssignmentNSG
    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_v6'
      osDisk: {
        sizeGiB: 64
        diskStorageAccountType: 'StandardSSD_LRS'
      }
    }
    replicas: 2
  }
}

Desdobrar o arquivo Bicep

Implemente o modelo Bicep para criar o cluster e todos os recursos necessários.

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>"

Defina apiVisibility como Public para um servidor de API acessível através da Internet, ou como Private para um servidor de API acessível apenas através de uma ligação de rede privada.

Defina ingressType como Public para rotas da aplicação acessíveis a partir da Internet, ou como Private para rotas da aplicação acessíveis apenas através de uma ligação de rede privada.

Defina privateKeyVault como true para restringir o acesso ao Key Vault a um ponto final privado, ou como false para permitir o acesso público. Se definires privateKeyVault como true, o modelo Bicep desativa o acesso público ao Key Vault, implementa os recursos do ponto final privado e define a visibilidade do cofre como Private no cluster.

Defina cryptoRestrictions como FIPS para restringir o cluster a módulos criptográficos validados pelo FIPS, ou None (por defeito) para instalar sem restrições FIPS. Esta configuração é imutável após a criação do cluster.

Note

O plano de controlo está sempre alojado num cluster habilitado por FIPS, independentemente desta configuração. O cryptoRestrictions parâmetro controla se os pools de nós trabalhadores utilizam módulos criptográficos validados por FIPS.

A implementação normalmente demora entre 15 a 20 minutos a ser concluída.

Verificar a implantação

Após o término da implementação, verifique se o cluster e o pool de nós foram criados com sucesso.

  1. Verifique se o cluster foi criado com sucesso.

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

    Quando o cluster está pronto, a saída é Succeeded.

  2. Verifique se o pool de nós foi criado com sucesso.

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

    Quando o pool de nós está pronto, a saída é Succeeded.

Criar a infraestrutura de rede

Crie um grupo de segurança de rede, uma rede virtual com uma sub-rede de trabalho e uma sub-rede de integração da VNet com delegação.

  1. Crie o grupo de segurança de rede (NSG).

    Note

    Se adicionar regras personalizadas ao NSG, certifique-se de que permite o tráfego descrito em Tráfego de grupo de segurança de rede obrigatório.

    az network nsg create \
      --name "${CUSTOMER_NSG}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --location "${LOCATION}"
    
  2. Crie a rede virtual com a sub-rede de trabalhadores.

    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. Crie a sub-rede de integração do VNet com a delegação necessária.

    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 \
      --delegations Microsoft.RedHatOpenShift/hcpOpenShiftClusters
    
  4. Obtenha os IDs dos recursos de rede.

    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)
    

Criar as identidades geridas

Crie as identidades geridas atribuídas pelo utilizador para os operadores do cluster e a identidade gerida do serviço. Para uma descrição de cada identidade e do seu propósito, veja Identidades geridas obrigatórias e atribuições de funções.

# 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}"

Obtenha os IDs de recursos e IDs principais para as identidades geridas.

# 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)

Criar as atribuições de funções

Atribuir os papéis Azure necessários a cada identidade gerida. Para uma descrição detalhada de cada identidade e das suas atribuições obrigatórias de funções, veja Identidades geridas e atribuições de funções obrigatórias.

  1. Defina os GUIDs de definição de funções.

    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. Atribuir funções de operador do plano de controlo.

    # Cluster API Azure → ARO HCP Cluster API Provider on the VNet
    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 VNet and NSG
    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 VNet
    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 VNet and NSG
    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 VNet
    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. Atribuir funções de identidade gerida por serviço.

    # 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. Atribuir funções de operador de plano de dados.

    # 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 VNet 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 "${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}"
    

Configurar encriptação etcd gerida pelo cliente

O Azure Red Hat OpenShift com planos de controlo alojados encripta os dados etcd usando chaves geridas pelo cliente.

Criar a identidade gerida do KMS

  1. Defina variáveis de ambiente para o Key Vault e a chave KMS.

    KEYVAULT_NAME="<key-vault-name>"
    KMS_KEY_NAME="etcd-kms-key"
    
  2. Crie a identidade gerida por KMS.

    az identity create --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}"
    
  3. Obtenha o ID do recurso e o ID principal para a identidade gerida do KMS.

    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)
    

Criar as atribuições de função do KMS

Atribuir à identidade gerida do serviço o papel de Leitor na identidade gerida do KMS.

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

Criar o Key Vault e a chave KMS

Crie um Azure Key Vault com autorização RBAC e uma chave de encriptação RSA de 2048 bits para encriptação etcd gerida pelo cliente.

  1. Cria o Key Vault.

    az keyvault create \
      --name "${KEYVAULT_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --location "${LOCATION}" \
      --enable-rbac-authorization true
    
  2. Atribui-te o papel de utilizador do Key Vault Crypto Officer. Esta função concede-lhe permissões para criar a chave de encriptação KMS.

    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. Crie a chave de encriptação KMS.

    az keyvault key create \
      --vault-name "${KEYVAULT_NAME}" \
      --name "${KMS_KEY_NAME}" \
      --kty RSA \
      --size 2048
    
  4. Compra a versão chave.

    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. Atribua a função Utilizador de Criptografia do Key Vault à identidade gerida pelo KMS no Key Vault.

    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}"
    

(Opcional) Restringir o acesso do Key Vault a um endpoint privado

Se quiser restringir o acesso ao Key Vault a um endpoint privado, crie os seguintes recursos. Se não precisares de um Key Vault privado, salta para Criar o cluster.

Importante

Os passos desta secção configuram o acesso privado apenas no Azure Key Vault. Ao criar o cluster do Azure Red Hat OpenShift com planos de controlo alojados, define também --vault-visibility Private. Ambas as definições têm de corresponder.

  1. Desative o acesso à rede pública no Key Vault.

    az keyvault update \
      --name "${KEYVAULT_NAME}" \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --public-network-access Disabled
    
  2. Crie um endpoint privado para o 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. Crie uma zona DNS privada e ligue-a à rede virtual.

    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. Crie um grupo de zonas DNS para o endpoint privado.

    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"
    

Criar o cluster

Crie o cluster Azure Red Hat OpenShift com planos de controlo alojados usando a infraestrutura de rede, identidades geridas e atribuições de funções que configurou nos passos anteriores.

Note

Para informações sobre todos os parâmetros personalizáveis do cluster, consulte a ajuda de comandos (az aro hcp cluster create -h).

Crie o cluster com o seguinte comando:

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}" \
  --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> \
  --assign-service-managed-identity "${SERVICE_MI_ID}" \
  --assign-control-plane-operator-identity cluster-api-azure "${CLUSTER_API_AZURE_MI_ID}" \
  --assign-control-plane-operator-identity control-plane "${CONTROL_PLANE_MI_ID}" \
  --assign-control-plane-operator-identity cloud-controller-manager "${CLOUD_CONTROLLER_MANAGER_MI_ID}" \
  --assign-control-plane-operator-identity ingress "${INGRESS_MI_ID}" \
  --assign-control-plane-operator-identity disk-csi-driver "${DISK_CSI_DRIVER_MI_ID}" \
  --assign-control-plane-operator-identity file-csi-driver "${FILE_CSI_DRIVER_MI_ID}" \
  --assign-control-plane-operator-identity image-registry "${IMAGE_REGISTRY_MI_ID}" \
  --assign-control-plane-operator-identity cloud-network-config "${CLOUD_NETWORK_CONFIG_MI_ID}" \
  --assign-control-plane-operator-identity kms "${KMS_MI_ID}" \
  --assign-data-plane-operator-identity disk-csi-driver "${DP_DISK_CSI_DRIVER_MI_ID}" \
  --assign-data-plane-operator-identity file-csi-driver "${DP_FILE_CSI_DRIVER_MI_ID}" \
  --assign-data-plane-operator-identity image-registry "${DP_IMAGE_REGISTRY_MI_ID}"

Se restringiste o Key Vault a um endpoint privado, define --vault-visibility em Private vez dePublic, para que a configuração do teu cluster corresponda à configuração da rede do Azure Key Vault.

Defina --api-visibility como Public para um servidor de API acessível através da Internet, ou como Private para um servidor de API acessível apenas através de uma ligação de rede privada.

Defina --ingress-visibility como Public para rotas da aplicação acessíveis a partir da Internet, ou como Private para rotas da aplicação acessíveis apenas através de uma ligação de rede privada.


A implementação normalmente demora entre 15 a 20 minutos a ser concluída.

Verifique se o cluster foi criado com sucesso.

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

Quando o cluster está pronto, a saída é Succeeded.

Criar o pool de nós

Crie um pool de nós para adicionar capacidade de computação worker ao seu cluster. O comando seguinte cria um pool de nós com dois Standard_D8s_v6 nós de trabalho.

Importante

Antes de criar o pool de nós, verifique se as regras NSG permitem o tráfego necessário descrito em Planeie a sua rede de cluster. Uma regra Deny correspondente pode impedir que o pool de nós conclua o provisionamento.

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

Verifique se o pool de nós foi criado com sucesso.

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

Quando o pool de nós está pronto, a saída é Succeeded.

Referência do ficheiro Bicep

O ficheiro Bicep de exemplo implementa um cluster com valores de configuração predefinidos. Esta secção descreve cada recurso e propriedade no ficheiro Bicep que pode personalizar antes de implementar.

Recursos de rede

O ficheiro Bicep define um grupo de segurança de rede (NSG), uma rede virtual com uma sub-rede de trabalho e uma sub-rede de integração VNet, e a delegação de sub-rede para a sub-rede de integração VNet. Para dimensionamento das sub-redes, colocação e requisitos NSG, consulte Planear a sua rede de clusters.

Identidades geridas e atribuições de funções

O ficheiro Bicep define uma identidade gerida atribuída pelo utilizador para cada Operador de cluster OpenShift, e atribuições de funções que concedem a cada identidade as permissões de que necessita. Para uma descrição detalhada de cada identidade e das suas atribuições obrigatórias de funções, veja Identidades geridas e atribuições de funções obrigatórias.

Recursos de encriptação Etcd

O ficheiro Bicep inclui os seguintes recursos para encriptação etcd gerida pelo cliente:

  • Identidade gerida KMS - Uma identidade gerida atribuída pelo utilizador para aceder à chave KMS. Esta identidade exige:
    • Uma atribuição de papel de utilizador do Key Vault Crypto com âmbito para o Azure Key Vault
    • Uma atribuição de papel de Leitor que concede ao serviço acesso à leitura da identidade gerida do serviço em vez da identidade gerida do KMS
  • Azure Key Vault - Um Azure Key Vault com autorização RBAC ativada
  • Chave de encriptação KMS - Uma chave RSA 2048 criada no Key Vault

Se definir o privateKeyVault parâmetro para true, o ficheiro Bicep também implementa os seguintes recursos para restringir o acesso ao Key Vault a um endpoint privado:

  • Um endpoint privado para o Key Vault
  • Uma zona DNS privada (privatelink.vaultcore.azure.net)
  • Um grupo privado de zona DNS que associa o endpoint privado à zona DNS
  • Um link de rede virtual que liga a zona DNS privada à rede virtual do cluster

Propriedades dos recursos do cluster

O recurso do cluster (Microsoft.RedHatOpenShift/hcpOpenShiftClusters) define a configuração do seu cluster. Para mais informações sobre cada opção de configuração, consulte Escolher as definições do seu cluster permanente.

Property Obrigatório Description
version.id Sim A versão menor do OpenShift para instalar. Por exemplo, 4.20. Para listar as versões disponíveis, consulte Listar versões OpenShift disponíveis.
version.channelGroup Sim O canal de atualização do OpenShift. A única opção suportada é stable.
dns.baseDomainPrefix No Um prefixo personalizado para o domínio base do cluster. Comprimento máximo de 15 caracteres. Deve começar com uma letra minúscula, podendo conter apenas letras minúsculas, números e hífens (-).
network.networkType No O plugin de interface de rede de contentores (CNI). Os valores válidos são OVNKubernetes (por defeito) ou Other.
network.podCidr No O intervalo de endereços IP para pods. Padrão: 10.128.0.0/14.
network.serviceCidr No O intervalo de endereços IP para serviços. Padrão: 172.30.0.0/16.
network.machineCidr No Intervalo de endereços IP dos nós de computação. Padrão: 10.0.0.0/16.
network.hostPrefix No O comprimento do prefixo de sub-rede atribuído a cada nó para os respetivos pods. Padrão: 23.
api.visibility No A visibilidade do servidor API. Os valores válidos são Public (por defeito) ou Private. Essa configuração é imutável.
api.authorizedCidrs No Uma lista de blocos CIDR autorizados (apenas IPv4) autorizados para aceder ao servidor API. Máximo de 500 inscrições.
ingress.type No O tipo de entrada padrão do cluster. Os valores válidos são Public (por defeito) ou Private. Essa configuração é imutável.
cryptoRestrictions No Restrições criptográficas para bibliotecas do kernel e do espaço de utilizador. Os valores válidos são None (por defeito) ou FIPS. Quando definido para FIPS, todas as operações criptográficas utilizam módulos validados por FIPS e todos os pools de nós herdam a configuração FIPS. Esta configuração é imutável após a criação do cluster.
etcd.dataEncryption.keyManagementMode Sim O modo de gestão de chaves de encriptação. O único valor suportado é CustomerManaged.
etcd.dataEncryption.customerManaged.encryptionType Sim O tipo de encriptação. O único valor suportado é KMS.
etcd.dataEncryption.customerManaged.kms.vaultName Sim O nome do Azure Key Vault.
etcd.dataEncryption.customerManaged.kms.visibility Sim Como o seu cluster Azure Red Hat OpenShift com planos de controlo alojados acede ao Key Vault. Os valores válidos são Public ou Private. Se definires isto para Private, também tens de desativar o acesso à rede pública no Key Vault e criar um endpoint privado na rede virtual do cluster.
etcd.dataEncryption.customerManaged.kms.activeKey.name Sim O nome da chave de encriptação.
etcd.dataEncryption.customerManaged.kms.activeKey.version Sim A versão da chave de encriptação.
clusterImageRegistry.state No O estado do registo interno de imagens. Os valores válidos são Enabled (por defeito) ou Disabled.
platform.managedResourceGroup No O nome do grupo de recursos gerenciados. Comprimento máximo de 90 caracteres.
platform.subnetId Sim O ID do recurso Azure da sub-rede de trabalho.
platform.vnetIntegrationSubnetId Sim O ID de recurso Azure da sub-rede de integração VNet.
platform.outboundType No O modelo de conectividade de saída. O único valor suportado é loadBalancer.
platform.networkSecurityGroupId Sim O ID de recurso Azure do grupo de segurança de rede.
platform.operatorsAuthentication Sim As atribuições de identidade gerida dos operadores do cluster.
autoscaling.maxNodesTotal No O número máximo de nós que o autoescalador de cluster pode criar. Padrão: 0 (sem limite).
autoscaling.maxPodGracePeriodSeconds No Número máximo de segundos para o encerramento ordeiro do pod antes da redução.
autoscaling.maxNodeProvisionTimeSeconds No Número máximo de segundos para o provisionamento de nós. Padrão: 900.
autoscaling.podPriorityThreshold No O limiar de prioridade abaixo do qual os pods são tratados como melhor esforço pelo autoescalador. Padrão: -10.
imageDigestMirrors No Entradas espelhadas do digest de imagens que redirecionam imagens de um registo de origem para registos espelhados. Máximo de 240 inscrições.
nodeDrainTimeoutMinutes No O período de carência padrão para drenagem de nós para todos os pools de nós, em minutos. Alcance: 0 até 10080. Padrão: 0 (sem limite de tempo).
identity.type Sim O tipo de identidade. Deve ser UserAssigned.
identity.userAssignedIdentities Sim Um mapa dos IDs de recursos de identidade gerida atribuídos pelo utilizador.

Propriedades dos recursos do pool de nós

O recurso do pool de nós (Microsoft.RedHatOpenShift/hcpOpenShiftClusters/nodePools) define um grupo de nós de trabalho que partilham a mesma configuração.

Property Obrigatório Description
version.id Sim A versão do patch OpenShift para este pool de nós. Por exemplo, 4.20.8. A versão do node pool deve ser uma versão patch dentro da versão menor do cluster. Para listar as versões disponíveis, consulte Listar versões OpenShift disponíveis.
version.channelGroup Sim O canal de atualização do OpenShift. A única opção suportada é stable.
platform.vmSize Sim O tamanho da máquina virtual do Azure para os nós. Para listar os tamanhos de VM disponíveis, consulte Listar tamanhos de VM disponíveis.
platform.subnetId Sim O ID de recurso Azure da subrede. Se não especificares esta propriedade, o conjunto de nós utiliza a sub-rede dos nós de trabalho do cluster.
platform.osDisk.diskSizeGiB No O tamanho do disco do sistema operativo em GiB. Mínimo: 16.
platform.osDisk.diskStorageAccountType No O tipo de conta de armazenamento em disco. Os valores válidos são Premium_LRS, StandardSSD_LRS, ou Standard_LRS.
platform.osDisk.encryptionSetId No O ID de recurso Azure de um DiskEncryptionSet para encriptar discos do sistema operativo.
platform.osDisk.diskType No O tipo de disco do sistema operativo. Os valores válidos são Managed ou Ephemeral.
platform.availabilityZone No A zona de disponibilidade do Azure para o pool de nós.
platform.enableEncryptionAtHost No Permite encriptação ao nível do host para VMs. Padrão: false.
replicas Conditional O número de nós. É obrigatório se autoScaling não estiver configurado.
autoScaling.min Conditional O número mínimo de nós. É obrigatório se replicas não estiver configurado.
autoScaling.max Conditional O número máximo de nós. É obrigatório se replicas não estiver configurado.
autoRepair No Permite verificações do estado dos nós. Padrão: true.
labels No Etiquetas do Kubernetes aplicadas aos nós, sob a forma de um array de pares chave-valor.
taints No Contaminações de Kubernetes aplicadas a nós. Cada mancha tem um key, value, e effect (NoSchedule, PreferNoSchedule, ou NoExecute).
nodeDrainTimeoutMinutes No O período de carência para o esvaziamento dos nós deste conjunto de nós, em minutos. Sobrepõe-se ao padrão do cluster. Alcance: 0 até 10080.

Lista disponível de versões OpenShift

O cluster version.id usa uma versão secundária (por exemplo, 4.20), enquanto o conjunto de nós version.id usa uma versão de correção (por exemplo, 4.20.8). Para listar as versões OpenShift disponíveis na sua região, execute o seguinte comando:

az aro hcp get-versions --location "${LOCATION}" --output table

Lista de tamanhos de VM disponíveis

A disponibilidade dos tamanhos das VMs depende da região Azure do seu cluster. Para listar os tamanhos das VMs disponíveis na sua região, execute o seguinte comando:

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

Para consultar a lista de tamanhos de máquinas virtuais suportados para os nós de trabalho do Azure Red Hat OpenShift com planos de controlo alojados, consulte Tamanhos de máquinas virtuais suportados. Utilize a lista regional para confirmar que um tamanho suportado está disponível na localização do seu cluster.

Passos seguintes