From eda28b30377df91ab5224e52808c10648af7c0b0 Mon Sep 17 00:00:00 2001 From: Laura Hinson Date: Wed, 10 Jun 2026 12:11:40 -0400 Subject: [PATCH] Private hosted clusters on Azure --- .../hcp-deploy/hcp-deploy-azure.adoc | 58 ++++++++- modules/hcp-azure-delete-private.adoc | 34 ++++++ modules/hcp-azure-oidc.adoc | 2 +- modules/hcp-azure-private-access.adoc | 86 +++++++++++++ modules/hcp-azure-private-hosted.adoc | 114 ++++++++++++++++++ modules/hcp-azure-private-iam.adoc | 89 ++++++++++++++ modules/hcp-azure-private-infra.adoc | 94 +++++++++++++++ modules/hcp-azure-private-operator.adoc | 83 +++++++++++++ modules/hcp-azure-private-subnet.adoc | 93 ++++++++++++++ modules/hcp-azure-private-ts.adoc | 41 +++++++ modules/hcp-azure-private.adoc | 11 ++ 11 files changed, 700 insertions(+), 5 deletions(-) create mode 100644 modules/hcp-azure-delete-private.adoc create mode 100644 modules/hcp-azure-private-access.adoc create mode 100644 modules/hcp-azure-private-hosted.adoc create mode 100644 modules/hcp-azure-private-iam.adoc create mode 100644 modules/hcp-azure-private-infra.adoc create mode 100644 modules/hcp-azure-private-operator.adoc create mode 100644 modules/hcp-azure-private-subnet.adoc create mode 100644 modules/hcp-azure-private-ts.adoc create mode 100644 modules/hcp-azure-private.adoc diff --git a/hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc b/hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc index 9783af319d6c..8bb54844f859 100644 --- a/hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc +++ b/hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc @@ -43,13 +43,61 @@ include::modules/hcp-azure-mgmt-cluster.adoc[leveloffset=+1] include::modules/hcp-azure-hosted.adoc[leveloffset=+1] -// include::modules/hcp-azure-private.adoc[leveloffset=+1] +include::modules/hcp-azure-private.adoc[leveloffset=+1] -// include::modules/hcp-azure-private-iam.adoc[leveloffset=+2] +include::modules/hcp-azure-private-subnet.adoc[leveloffset=+2] -// include::modules/hcp-azure-private-infra.adoc[leveloffset=+2] +[role="_additional-resources"] +.Additional resources + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-mgmt-cluster_hcp-deploy-azure[Configuring an {azure-short} management cluster for {hcp}] + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-oidc_hcp-deploy-azure[Setting up an OIDC issuer] + +include::modules/hcp-azure-private-operator.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-oidc_hcp-deploy-azure[Setting up an OIDC issuer] -// include::modules/hcp-azure-private-hosted.adoc[leveloffset=+2] +include::modules/hcp-azure-private-iam.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-oidc_hcp-deploy-azure[Setting up an OIDC issuer] + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-workload-id_hcp-deploy-azure[Creating {azure-short} Workload Identities] + +include::modules/hcp-azure-private-infra.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-oidc_hcp-deploy-azure[Setting up an OIDC issuer] + +include::modules/hcp-azure-private-hosted.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-private-subnet_hcp-deploy-azure[Preparing a subnet for a private hosted cluster on {azure-short}] + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-private-operator_hcp-deploy-azure[Installing the HyperShift Operator with private platform support] + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-private-iam_hcp-deploy-azure[Configuring IAM resources for a private hosted cluster] + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-private-infra_hcp-deploy-azure[Creating infrastructure for a private hosted cluster] + +include::modules/hcp-azure-private-access.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc#hcp-azure-private-hosted_hcp-deploy-azure[Creating a private {azure-short} hosted cluster] + +include::modules/hcp-azure-private-ts.adoc[leveloffset=+2] // include::modules/hcp-azure-autoscaling.adoc[leveloffset=+1] @@ -64,3 +112,5 @@ include::modules/hcp-azure-cluster-delete.adoc[leveloffset=+2] include::modules/hcp-azure-infra-delete.adoc[leveloffset=+2] include::modules/hcp-azure-workload-id-delete.adoc[leveloffset=+2] + +include::modules/hcp-azure-delete-private.adoc[leveloffset=+2] diff --git a/modules/hcp-azure-delete-private.adoc b/modules/hcp-azure-delete-private.adoc new file mode 100644 index 000000000000..5805fadaa372 --- /dev/null +++ b/modules/hcp-azure-delete-private.adoc @@ -0,0 +1,34 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-delete-private_{context}"] += Deleting a private hosted cluster on {azure-short} + +[role="_abstract"] +If you are no longer using a private hosted cluster on {azure-short}, you can delete it. + +The deletion process automatically cleans up Private Link resources in the following order: + +. The Control Plane Operator removes the private endpoint, private DNS zones, VNet links, and A records. +. The `hcp destroy` command removes role-based access control (RBAC) role assignments. +. The HyperShift Operator removes Private Link. + +.Procedure + +* To delete a private hosted cluster, enter the following command: ++ +[source,terminal] +---- +$ hcp destroy cluster azure \ + --name ${CLUSTER_NAME} \ + --azure-creds ${AZURE_CREDS} \ + --resource-group-name ${MANAGED_RG_NAME} \ + --dns-zone-rg-name ${DNS_ZONE_RG_NAME} +---- ++ +** `--name` specifies your hosted cluster name. +** `--azure-creds` specifies an {azure-short} credentials file that has permission to create infrastructure resources, such as virtual networks, subnets, and load balancers. This flag is required because the `hcp destroy cluster azure` command cleans up RBAC role assignments before it deletes infrastructure. +** `--resource-group-name` specifies the name of the resource group where you created identities. +** `--dns-zone-rg-name` specifies the name of the resource group that contains your DNS zone. + diff --git a/modules/hcp-azure-oidc.adoc b/modules/hcp-azure-oidc.adoc index ca3e8e644663..27df97171249 100644 --- a/modules/hcp-azure-oidc.adoc +++ b/modules/hcp-azure-oidc.adoc @@ -6,7 +6,7 @@ = Setting up an OIDC issuer [role="_abstract"] -To prepare to deploy {hcp} on {azure-short}, you need to set up {azure-short} Workload Identities and an OIDC issuer for hosted clusters. +To prepare to deploy {hcp} on {azure-short}, you need to set up an OIDC issuer for hosted clusters. .Prerequisites diff --git a/modules/hcp-azure-private-access.adoc b/modules/hcp-azure-private-access.adoc new file mode 100644 index 000000000000..1f268d6134e1 --- /dev/null +++ b/modules/hcp-azure-private-access.adoc @@ -0,0 +1,86 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-access_{context}"] += Accessing a private {azure-short} hosted cluster + +[role="_abstract"] +After you create a private hosted cluster, you need to take additional steps to access it. + +.Prerequisites + +* You completed the steps in "Creating a private {azure-short} hosted cluster". + +.Procedure + +* To access a private hosted cluster by generating a `kubeconfig` file, enter the following command: ++ +[source,terminal] +---- +$ hcp create kubeconfig \ + --name ${CLUSTER_NAME} \ + --port-forward > ${CLUSTER_NAME}-kubeconfig +---- + +* If you have access to the management cluster, you can port forward to the API server to access the private hosted cluster. ++ +.. Port forward to the `kube-apiserver` service by entering the following command: ++ +[source,terminal] +---- +$ kubectl port-forward svc/kube-apiserver \ + -n clusters-${CLUSTER_NAME} 6443:6443 & +---- ++ +.. Access the hosted cluster by using the `kubeconfig` file: ++ +[source,bash] +---- +$ KUBECONFIG=${CLUSTER_NAME}-kubeconfig oc get nodes +---- + +* If you have a virtual machine (VM) in an {azure-short} Virtual Network (VNet) that is peered with the hosted cluster's VNet, you can access the API server, but you must first link the private DNS zones to the peered VNet. ++ +[NOTE] +==== +The Control Plane Operator links private DNS zones only to the hosted cluster's VNet. If you want to resolve the API server hostname from a peered VNet, you must manually link the private DNS zones to that VNet as shown in the following steps. Otherwise, DNS resolution fails from the peered VNet. +==== ++ +.. Link the private DNS zone to your peered VNet as shown in the following example: ++ +[source,bash] +---- +$ PEERED_VNET_ID="/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/" +---- ++ +.. Enter the following command: ++ +[source,terminal] +---- +$ az network private-dns link vnet create \ + --resource-group "${MANAGED_RG_NAME}" \ + --zone-name "${CLUSTER_NAME}.hypershift.local" \ + --name "peered-vnet-link" \ + --virtual-network "${PEERED_VNET_ID}" \ + --registration-enabled false +---- ++ +.. If you also need base-domain resolution, enter the following command: ++ +[source,terminal] +---- +$ az network private-dns link vnet create \ + --resource-group "${MANAGED_RG_NAME}" \ + --zone-name "${PARENT_DNS_ZONE}" \ + --name "peered-vnet-basedomain-link" \ + --virtual-network "${PEERED_VNET_ID}" \ + --registration-enabled false +---- ++ +.. Access the cluster as shown in the following example: ++ +[source,bash] +---- +$ KUBECONFIG=${CLUSTER_NAME}-kubeconfig oc get nodes +---- \ No newline at end of file diff --git a/modules/hcp-azure-private-hosted.adoc b/modules/hcp-azure-private-hosted.adoc new file mode 100644 index 000000000000..b739c9f87428 --- /dev/null +++ b/modules/hcp-azure-private-hosted.adoc @@ -0,0 +1,114 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-hosted_{context}"] += Creating a private {azure-short} hosted cluster + +[role="_abstract"] +Create a private hosted cluster to ensure that the communication between compute nodes and the hosted control plane occurs over {azure-short} Private Link. + +.Prerequisites + +* You configured a subnet, as described in "Preparing a subnet for a private hosted cluster on {azure-short}". + +* You installed the HyperShift Operator on an {product-title} management cluster on {azure-short}, as described in "Installing the HyperShift Operator with private platform support". + +* You created Identity and Access Management (IAM) resources, as described in "Configuring IAM resources for a private hosted cluster". + +* You created infrastructure, as described in "Creating infrastructure for a private hosted cluster". + +* This procedure relies on environment variables that you created in the prerequisite procedures. Be sure to complete this procedure in the same terminal where you already defined the environment variables. + +.Procedure + +. Create the private hosted cluster by entering the following command: ++ +[source,terminal] +---- +$ hcp create cluster azure \ + --name "$CLUSTER_NAME" \ + --namespace "clusters" \ + --azure-creds ${AZURE_CREDS} \ + --location ${LOCATION} \ + --node-pool-replicas 2 \ + --base-domain ${PARENT_DNS_ZONE} \ + --pull-secret ${PULL_SECRET} \ + --generate-ssh \ + --release-image ${RELEASE_IMAGE} \ + --resource-group-name "${MANAGED_RG_NAME}" \ + --vnet-id "${VNET_ID}" \ + --subnet-id "${SUBNET_ID}" \ + --network-security-group-id "${NSG_ID}" \ + --sa-token-issuer-private-key-path "${SA_TOKEN_ISSUER_PRIVATE_KEY_PATH}" \ + --oidc-issuer-url "${OIDC_ISSUER_URL}" \ + --dns-zone-rg-name ${DNS_ZONE_RG_NAME} \ + --assign-service-principal-roles \ + --workload-identities-file ${WORKLOAD_IDENTITIES_FILE} \ + --external-dns-domain ${DNS_ZONE_NAME} \ + --endpoint-access Private \ + --endpoint-access-private-nat-subnet-id "${NAT_SUBNET_ID}" +---- ++ +* When you choose a value for the `--external-dns-domain` flag, ensure that the value does not match `{cluster-name}.{base-domain}`. If you use `{cluster-name}.{base-domain}` for the value, the Control Plane Operator creates a private DNS zone that can shadow the `*.apps` domain, which causes the console and ingress to become unreachable. +* `--endpoint-access` accepts 3 values: ++ +** `Public`, which is the default value. When you specify `Public`, the API server is accessible through public endpoint only. +** `PublicAndPrivate`, where the API server is accessible through both public and private endpoints. +** `Private`, where the API server is accessible only through Private Link. ++ +After you create a cluster, you cannot change it between `Public` endpoint and non-public (`PublicAndPrivate` or `Private`) endpoint access. ++ +If you need to allow `Private` endpoint connections from {azure-short} subscriptions other than the hosted cluster's subscription, use the following flag: `--endpoint-access-private-additional-allowed-subscriptions "sub-id-1, sub-id-2"`. + +.Verification + +. Check the Private Link resources by entering the following command: ++ +[source,terminal] +---- +$ oc get azureprivatelinkservices -n clusters-${CLUSTER_NAME} +---- + +. Check the status and connections by entering the following command: ++ +[source,terminal] +---- +$ oc get azureprivatelinkservices -n clusters-${CLUSTER_NAME} -o yaml +---- ++ +.Setup progress conditions +[cols="2",options="header"] +|=== +|Condition |Description + +|`AzureInternalLoadBalancerAvailable` +|The internal load balancer has a front-end IP address. + +|`AzurePLSCreated` +|Private Link is created in the management cluster. + +|`AzurePrivateEndpointAvailable` +|Private endpoint is created in the hosted cluster VNet. + +|`AzurePrivateDNSAvailable` +|Private DNS zones and A records are created. + +|`AzurePrivateLinkServiceAvailable` +|All components are ready and private connectivity is available. + +|=== + +. Check the overall cluster status by entering the following command: ++ +[source,terminal] +---- +$ oc get hostedcluster ${CLUSTER_NAME} -n clusters +---- + +. Wait for the status by entering the following command: ++ +[source,terminal] +---- +$ oc wait --for=condition=Available hostedcluster/${CLUSTER_NAME} -n clusters --timeout=30m +---- diff --git a/modules/hcp-azure-private-iam.adoc b/modules/hcp-azure-private-iam.adoc new file mode 100644 index 000000000000..8e3fd1e3894e --- /dev/null +++ b/modules/hcp-azure-private-iam.adoc @@ -0,0 +1,89 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-iam_{context}"] += Configuring IAM resources for a private hosted cluster + +[role="_abstract"] +Create Workload Identities so that your private clusters can manage private endpoints and private DNS zones. + +.Prerequisites + +* You have an {product-title} management cluster on {azure-short} that has the HyperShift Operator installed. + +* The {azure-short} command-line interface (CLI) is installed and configured. + +* The {oc-first} is installed. + +* If you are using external DNS, the `jq` command-line JSON processor is installed. + +* You configured an OIDC issuer. For more information, see "Setting up an OIDC issuer". + +.Procedure + +. Set your environment variables: ++ +.. Set your prefix by entering the following command: ++ +[source,bash] +---- +$ PREFIX="" +---- ++ +.. Set the cluster name by entering the following command: ++ +[source,bash] +---- +$ CLUSTER_NAME="${PREFIX}-hc" +---- ++ +.. Set the resource group name by entering the following command: ++ +[source,bash] +---- +$ RESOURCE_GROUP_NAME="${CLUSTER_NAME}-${PREFIX}" +---- ++ +.. Set the location by entering the following command: ++ +[source,bash] +---- +$ LOCATION="" +---- ++ +.. Set the variable for the path to the {azure-short} credentials file by entering the following command: ++ +[source,bash] +---- +$ AZURE_CREDS="" +---- ++ +.. Set the variable for the OIDC issuer URL by entering the following command: ++ +[source,bash] +---- +$ OIDC_ISSUER_URL="" +---- +.. Set the path to the Workload Identities file by entering the following command: ++ +[source,bash] +---- +$ WORKLOAD_IDENTITIES_FILE="" +---- + +. Create Workload Identities by entering the following command: ++ +[source,terminal] +---- +$ hcp create iam azure \ + --name "${CLUSTER_NAME}" \ + --infra-id "${PREFIX}" \ + --azure-creds "${AZURE_CREDS}" \ + --location "${LOCATION}" \ + --resource-group-name "${RESOURCE_GROUP_NAME}" \ + --oidc-issuer-url "${OIDC_ISSUER_URL}" \ + --output-file "${WORKLOAD_IDENTITIES_FILE}" +---- ++ +The command creates 8 Workload Identities. For `Private` and `PublicAndPrivate` clusters, the Control Plane Operator identity is used to create and manage private endpoints, private DNS zones, {azure-short} Virtual Network (VNet) links, and DNS A records. The Control Plane Identity is assigned the `Contributor` role by default. To use a more restrictive role, use the `--assign-custom-hcp-roles` flag. \ No newline at end of file diff --git a/modules/hcp-azure-private-infra.adoc b/modules/hcp-azure-private-infra.adoc new file mode 100644 index 000000000000..f4f218af9819 --- /dev/null +++ b/modules/hcp-azure-private-infra.adoc @@ -0,0 +1,94 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-infra_{context}"] += Creating infrastructure for a private hosted cluster + +[role="_abstract"] +Set up infrastructure so that you can create private hosted clusters. + +.Prerequisites + +* You have an {product-title} management cluster on {azure-short} that has the HyperShift Operator installed. + +* The {azure-short} command-line interface (CLI) is installed and configured. + +* The {oc-first} is installed. + +* If you are using external DNS, the `yq` command-line YAML processor is installed. + +* You configured an OIDC issuer. For more information, see "Setting up an OIDC issuer". + +.Procedure + +. Set your environment variables: ++ +.. Set the variable for the DNS zone resource group by entering the following command: ++ +[source,bash] +---- +$ DNS_ZONE_RG_NAME="os4-common" +---- ++ +.. Set the variable for the base domain of your DNS zone by entering the following command: ++ +[source,bash] +---- +$ PARENT_DNS_ZONE="" +---- ++ +.. Set the variable that points to the infrastructure output file by entering the following command: ++ +[source,bash] +---- +$ INFRA_OUTPUT_FILE="${PREFIX}-infra-output.json" +---- + +. Create infrastructure by entering the following command: ++ +[source,terminal] +---- +$ hcp create infra azure \ + --azure-creds "${AZURE_CREDS}" \ + --infra-id "${PREFIX}" \ + --name "${CLUSTER_NAME}" \ + --location "${LOCATION}" \ + --base-domain "${PARENT_DNS_ZONE}" \ + --dns-zone-rg-name "${DNS_ZONE_RG_NAME}" \ + --workload-identities-file "${WORKLOAD_IDENTITIES_FILE}" \ + --assign-identity-roles \ + --output-file "${INFRA_OUTPUT_FILE}" +---- + +. Read the infrastructure output to get the resource IDs that you created, as shown in the following example: ++ +.. Read the resource group name by entering the following command: ++ +[source,bash] +---- +$ MANAGED_RG_NAME=$(yq -r -p yaml '.resourceGroupName' "${INFRA_OUTPUT_FILE}") +---- ++ +.. Read the VNet ID by entering the following command: ++ +[source,bash] +---- +$ VNET_ID=$(yq -r -p yaml '.vnetID' "${INFRA_OUTPUT_FILE}") +---- ++ +.. Read the subnet ID by entering the following command: ++ +[source,bash] +---- +$ SUBNET_ID=$(yq -r -p yaml '.subnetID' "${INFRA_OUTPUT_FILE}") +---- ++ +.. Read the network security group ID by entering the following command: ++ +[source,bash] +---- +$ NSG_ID=$(yq -r -p yaml '.securityGroupID' "${INFRA_OUTPUT_FILE}") +---- ++ +Note the resource IDs because you need them to create the private hosted cluster. \ No newline at end of file diff --git a/modules/hcp-azure-private-operator.adoc b/modules/hcp-azure-private-operator.adoc new file mode 100644 index 000000000000..770b1aa46662 --- /dev/null +++ b/modules/hcp-azure-private-operator.adoc @@ -0,0 +1,83 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-operator_{context}"] += Installing the HyperShift Operator with private platform support + +[role="_abstract"] +To set up an environment that supports private clusters, you must install the HyperShift Operator with flags that configure {azure-short} Private Link management. + +[NOTE] +==== +If you already installed the HyperShift Operator but you did not include the `--private-platform Azure` setting, you must run the `hcp install` command again with the private platform flags before you can create private clusters. +==== + +.Prerequisites + +* You have an {product-title} management cluster on {azure-short}. + +* The {azure-short} command-line interface (CLI) is installed and configured. + +* The {oc-first} is installed. + +* If you are using external DNS, the `jq` command-line JSON processor is installed. + +* You configured an OIDC issuer. For more information, see "Setting up an OIDC issuer". + +.Procedure + +. Obtain credentials so that the Operator can manage Private Link resources. ++ +.. Obtain the credentials file for Private Link management as shown in the following example: ++ +[source,bash] +---- +$ AZURE_PRIVATE_CREDS="" +---- ++ +.. Obtain the infrastructure resource group of the management cluster as shown in the following example: ++ +[source,bash] +---- +$ MGMT_INFRA_RG=$(oc get infrastructure cluster -o jsonpath='{.status.platformStatus.azure.resourceGroupName}') +---- + +. Set the external DNS configuration variables as shown in the following examples: ++ +[source,bash] +---- +$ SERVICE_PRINCIPAL_FILEPATH="" +---- ++ +[source,bash] +---- +$ DNS_ZONE_NAME="" +---- + +. Install the HyperShift Operator with private platform support as shown in the following example: ++ +[source,terminal] +---- +$ hcp install \ + --pull-secret ${PULL_SECRET} \ + --private-platform Azure \ + --azure-private-creds ${AZURE_PRIVATE_CREDS} \ + --azure-pls-resource-group ${MGMT_INFRA_RG} \ + --external-dns-provider=azure \ + --external-dns-credentials ${SERVICE_PRINCIPAL_FILEPATH} \ + --external-dns-domain-filter ${DNS_ZONE_NAME} +---- ++ +* `--private-platform Azure` specifies that {azure-short} Private Link management is to be enabled in the Operator. +* `--azure-private-creds` specifies the path to the {azure-short} credentials file that is used for Private Link operations. ++ +[NOTE] +==== +Besides using the `--azure-private-creds` flag, you can use one of the following authentication methods. Be sure to use only one authentication method. + +** `--azure-private-secret` specifies an existing Kubernetes secret that has {azure-short} credentials. This flag has a companion flag, `--azure-private-secret-key`. Its default value is `credentials`, but you can customize it for secrets that have non-standard key names. +** `--azure-pls-managed-identity-client-id` specifies the client ID of a managed identity for Private Link operations through Workload Identity federation. If you specify this flag, you must also include the `--azure-pls-subscription-id` flag, which specifies the {azure-short} subscription ID for Private Link operations. +==== +* `--azure-pls-resource-group` specifies the resource group where the Private Link resources are to be created. This resource group is the same as the resource group of the infrastructure for the management cluster. +* `--external-dns-credentials` specifies the path to a file that contains DNS credentials. If preferred, you can use the `--external-dns-secret` flag instead to specify a Kubernetes secret that has DNS credentials. diff --git a/modules/hcp-azure-private-subnet.adoc b/modules/hcp-azure-private-subnet.adoc new file mode 100644 index 000000000000..3a9c40eaee61 --- /dev/null +++ b/modules/hcp-azure-private-subnet.adoc @@ -0,0 +1,93 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-subnet_{context}"] += Preparing a subnet for a private hosted cluster on {azure-short} + +[role="_abstract"] +{azure-short} Private Link requires a dedicated subnet for network address translator (NAT) IP address allocation. You can manually create the subnet, or it can be automatically created during cluster creation. + +By manually creating the subnet, you have control over classless inter-domain routing (CIDR) allocation and naming. The following steps apply to manually creating the subnet. If you want the subnet to be automatically created, skip this procedure. + +[NOTE] +==== +{azure-short} Private Link, the NAT subnet, and the internal load balancer of the management cluster must all be in the same {azure-short} region. Private Link is automatically created in the location where the hosted cluster is created. {azure-short} rejects the creation of Private Link if the NAT subnet is in a different region. +==== + +.Prerequisites + +* You have an {product-title} management cluster on {azure-short}. For more information, see "Configuring an {azure-short} management cluster for {hcp}". + +* The {azure-short} command-line interface (CLI) is installed and configured. + +* The {oc-first} is installed. + +* If you are using external DNS, the `jq` command-line JSON processor is installed. + +* You configured an OIDC issuer. For more information, see "Setting up an OIDC issuer". + +.Procedure + +. Identify the {azure-short} Virtual Network (VNet) of the management cluster. ++ +.. Obtain the infrastructure resource group of the management cluster as shown in the following example: ++ +[source,bash] +---- +$ MGMT_INFRA_RG=$(oc get infrastructure cluster -o jsonpath='{.status.platformStatus.azure.resourceGroupName}') +---- ++ +.. Find the VNet in the infrastructure resource group as shown in the following example: ++ +[source,bash] +---- +$ MGMT_VNET_NAME=$(az network vnet list --resource-group "${MGMT_INFRA_RG}" --query "[0].name" -o tsv) +---- ++ +.. Set the environment variable for the VNet by entering the following command: ++ +[source,bash] +---- +$ MGMT_VNET_RG="${MGMT_INFRA_RG}" +---- + +. Create the NAT subnet. ++ +.. Check the existing address space and subnets to ensure that you do not choose an overlapping classless inter-domain routing (CIDR) range. Enter the following command: ++ +[source,terminal] +---- +$ az network vnet show \ + --resource-group "${MGMT_VNET_RG}" \ + --name "${MGMT_VNET_NAME}" \ + --query '{addressSpace: addressSpace.addressPrefixes, subnets: subnets[].{name: name, prefix: addressPrefix}}' \ + -o json +---- ++ +.. Create the subnet as shown in the following example: ++ +[source,terminal] +---- +$ az network vnet subnet create \ + --resource-group "${MGMT_VNET_RG}" \ + --vnet-name "${MGMT_VNET_NAME}" \ + --name "${NAT_SUBNET_NAME}" \ + --address-prefixes 10.1.64.0/24 \ + --disable-private-link-service-network-policies true +---- ++ +* The NAT subnet must be in the VNet of the management cluster because Private Link is created alongside the internal load balancer of the management cluster. +* The `10.1.64.0/24` address prefix is an example only. Replace it with a CIDR range that does not overlap with any other subnet in the VNet of the management cluster. If the VNet uses `10.0.0.0/16`, the NAT subnet must fall within that range, or you must expand the address space of the VNet. +* The `--disable-private-link-service-network-policies` flag is required and must be set to `true`. Otherwise, {azure-short} rejects the creation of Private Link on the subnet. + +. Obtain the NAT subnet resource ID for later use as shown in the following example: ++ +[source,bash] +---- +$ NAT_SUBNET_ID=$(az network vnet subnet show \ + --resource-group "${MGMT_VNET_RG}" \ + --vnet-name "${MGMT_VNET_NAME}" \ + --name "${NAT_SUBNET_NAME}" \ + --query id -o tsv) +---- diff --git a/modules/hcp-azure-private-ts.adoc b/modules/hcp-azure-private-ts.adoc new file mode 100644 index 000000000000..e77906c706a2 --- /dev/null +++ b/modules/hcp-azure-private-ts.adoc @@ -0,0 +1,41 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: PROCEDURE +[id="hcp-azure-private-ts_{context}"] += Troubleshooting private hosted clusters on {azure-short} + +[role="_abstract"] +If your private hosted cluster gets stuck, check the `AzurePrivateLinkService` custom resource conditions. + +.Procedure + +. Enter the following command to check the Private Link conditions: ++ +[source,terminal] +---- +$ oc get azureprivatelinkservices \ + -n clusters-${CLUSTER_NAME} \ + -o jsonpath='{.items[0].status.conditions}' | jq . +---- + +. Review the output and compare it to the following condition table: ++ +.Private cluster stuck conditions +[cols="2",options="header"] +|=== +|Condition |Possible cause + +|`AzureInternalLoadBalancerAvailable` = `False` +|The `private-router` service has not received an internal load balancer IP address yet. Check the service status and {azure-short} networking. + +|`AzurePLSCreated` = `False` +|Private Link creation failed. Check the NAT subnet policies, credentials, and the HyperShift Operator logs. + +|`AzurePrivateEndpointAvailable` = `False` +|Private endpoint creation failed or the connection was not approved. Check the Private Link auto-approval list and the Control Plane Operator logs. + +|`AzurePrivateDNSAvailable` = `False` +|The DNS zone or record creation failed. In the {azure-short} subscription that stores the infrastructure resources for the hosted cluster, check the Control Plane Operator identity permissions. + +|=== diff --git a/modules/hcp-azure-private.adoc b/modules/hcp-azure-private.adoc new file mode 100644 index 000000000000..ae449f8eade7 --- /dev/null +++ b/modules/hcp-azure-private.adoc @@ -0,0 +1,11 @@ +//Module included in the following assemblies: +// hosted_control_planes/hcp-deploy/hcp-deploy-azure.adoc + +:_mod-docs-content-type: CONCEPT +[id="hcp-azure-private_{context}"] += Private hosted clusters on {azure-short} + +[role="_abstract"] +By default, hosted clusters are accessible through public DNS and the default router of the management cluster. If you want communication between your compute nodes and the hosted control plane to be private, you can create hosted clusters that use {azure-short} Private Link for communication. + +Private endpoint access uses {azure-short} Private Link to expose the internal load balancer of the hosted control plane to the {azure-short} Virtual Network (VNet) of the hosted cluster. Compute nodes resolve the API server hostname by using private DNS zones that point to the private endpoint IP address.