Skip to content

Commit f23bfd1

Browse files
authored
Merge pull request #5489 from nawazkh/enable_local_testing
Add documentation and scripts on running e2e test locally
2 parents eb42392 + 687912b commit f23bfd1

File tree

7 files changed

+715
-70
lines changed

7 files changed

+715
-70
lines changed

Makefile

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ E2E_CONF_FILE_ENVSUBST := $(ROOT_DIR)/test/e2e/config/azure-dev-envsubst.yaml
186186
SKIP_CLEANUP ?= false
187187
AZWI_SKIP_CLEANUP ?= false
188188
SKIP_LOG_COLLECTION ?= false
189+
MGMT_CLUSTER_TYPE ?= kind
189190
# @sonasingh46: Skip creating mgmt cluster for ci as workload identity needs kind cluster
190191
# to be created with extra mounts for key pairs which is not yet supported
191192
# by existing e2e framework. A mgmt cluster(kind) is created as part of e2e suite
@@ -317,8 +318,12 @@ install-tools: $(ENVSUBST) $(KUSTOMIZE) $(KUBECTL) $(HELM) $(GINKGO) $(KIND) $(A
317318

318319
.PHONY: create-management-cluster
319320
create-management-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) $(KIND) ## Create a management cluster.
320-
# Create kind management cluster.
321-
$(MAKE) kind-create
321+
# Create management cluster based on type
322+
@if [ "$(MGMT_CLUSTER_TYPE)" = "aks" ]; then \
323+
$(MAKE) aks-create; \
324+
else \
325+
$(MAKE) kind-create; \
326+
fi
322327

323328
# Install cert manager and wait for availability
324329
./hack/install-cert-manager.sh
@@ -334,7 +339,9 @@ create-management-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) $(KIND) ## Create
334339
timeout --foreground 300 bash -c "until curl --retry $(CURL_RETRIES) -sSL https://github.com/kubernetes-sigs/cluster-api-addon-provider-helm/releases/download/v0.2.5/addon-components.yaml | $(ENVSUBST) | $(KUBECTL) apply -f -; do sleep 5; done"
335340

336341
# Deploy CAPZ
337-
$(KIND) load docker-image $(CONTROLLER_IMG)-$(ARCH):$(TAG) --name=$(KIND_CLUSTER_NAME)
342+
if [ "$(MGMT_CLUSTER_TYPE)" != "aks" ]; then \
343+
$(KIND) load docker-image $(CONTROLLER_IMG)-$(ARCH):$(TAG) --name=$(KIND_CLUSTER_NAME); \
344+
fi
338345
timeout --foreground 300 bash -c "until $(KUSTOMIZE) build config/default | $(ENVSUBST) | $(KUBECTL) apply -f - --server-side=true; do sleep 5; done"
339346

340347
# Wait for CAPI deployments
@@ -360,7 +367,10 @@ create-management-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) $(KIND) ## Create
360367
timeout --foreground 300 bash -c "until $(KUBECTL) get clusters -A; do sleep 3; done"
361368
timeout --foreground 300 bash -c "until $(KUBECTL) get azureclusters -A; do sleep 3; done"
362369
timeout --foreground 300 bash -c "until $(KUBECTL) get kubeadmcontrolplanes -A; do sleep 3; done"
363-
@echo 'Set kubectl context to the kind management cluster by running "$(KUBECTL) config set-context kind-$(KIND_CLUSTER_NAME)"'
370+
371+
@if [ "$(MGMT_CLUSTER_TYPE)" != "aks" ]; then \
372+
echo 'Set kubectl context to the kind management cluster by running "$(KUBECTL) config set-context kind-$(KIND_CLUSTER_NAME)"'; \
373+
fi
364374

365375
.PHONY: create-workload-cluster
366376
create-workload-cluster: $(ENVSUBST) $(KUBECTL) ## Create a workload cluster.
@@ -726,6 +736,17 @@ test-cover: test ## Run tests with code coverage and generate reports.
726736
kind-create-bootstrap: $(KUBECTL) ## Create capz kind bootstrap cluster.
727737
KIND_CLUSTER_NAME=capz-e2e ./scripts/kind-with-registry.sh
728738

739+
.PHONY: create-bootstrap
740+
create-bootstrap: $(KUBECTL) ## Create bootstrap cluster (AKS or KIND) for CAPZ testing. Default is KIND.
741+
@echo "Creating bootstrap cluster with type: $(MGMT_CLUSTER_TYPE)"
742+
@if [ "$(MGMT_CLUSTER_TYPE)" == "aks" ]; then \
743+
MGMT_CLUSTER_NAME="$${MGMT_CLUSTER_NAME:-capz-e2e-$(shell date +%s)}" \
744+
./scripts/aks-as-mgmt.sh || { echo "Failed to create AKS bootstrap cluster" >&2; exit 1; }; \
745+
else \
746+
KIND_CLUSTER_NAME=capz-e2e ./scripts/kind-with-registry.sh || { echo "Failed to create KIND bootstrap cluster" >&2; exit 1; }; \
747+
fi
748+
@echo "Bootstrap cluster created successfully"
749+
729750
.PHONY: cleanup-workload-identity
730751
cleanup-workload-identity: ## Cleanup CI workload-identity infra
731752
@if ! [ "$(AZWI_SKIP_CLEANUP)" == "true" ]; then \

docs/book/src/developers/development.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,8 @@ To run E2E locally, set `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRI
507507
./scripts/ci-e2e.sh
508508
```
509509

510+
Note: Users that have a restrictive environment and want to leverage API Server ILB in their flavors and to run e2e tests locally should refer to the detailed explanation in [running e2e tests locally leveraging apiserver ilb solution](./tilt-with-aks-as-mgmt-ilb.md#running-e2e-tests-locally-using-api-server-ilbs-networking-solution)
511+
510512
You can optionally set the following variables:
511513

512514
| Variable | Description | Default |

docs/book/src/developers/tilt-with-aks-as-mgmt-ilb.md

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ While the default Tilt setup recommends using a KIND cluster as the management c
3838
export AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY="<user-assigned-managed-identity-client-id>"
3939
export AZURE_CLIENT_ID="${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY}"
4040
export AZURE_OBJECT_ID_USER_ASSIGNED_IDENTITY="<user-assigned-managed-identity--object-id>"
41+
export AZURE_USER_ASSIGNED_IDENTITY_RESOURCE_ID="<resource-id-of-user-assigned-managed-id-from-json-view>"
4142
export AZURE_LOCATION="<azure-location-having-quota-for-B2s-and-D4s_v3-SKU>"
4243
export REGISTRY=<your-container-registry>
4344
```
@@ -76,6 +77,158 @@ While the default Tilt setup recommends using a KIND cluster as the management c
7677
- [apiserver-ilb](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/templates/cluster-template-apiserver-ilb.yaml): VM-based default flavor that brings up native K8s clusters with Linux nodes.
7778
- [apiserver-ilb-windows](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/templates/cluster-template-windows-apiserver-ilb.yaml): VM-based flavor that brings up native K8s clusters with Linux and Windows nodes.
7879

80+
## Running e2e tests locally using API Server ILB's networking solution
81+
82+
Running an e2e test locally in a restricted environment calls for some workarounds in the prow templates and the e2e test itself.
83+
84+
1. We need to add the apiserver ILB with private endpoints and predeterimined CIDRs to the workload cluster's VNet & Subnets, and pre-kubeadm commands updating the `/etc/hosts` file of the nodes of the workload cluster.
85+
86+
2. Once the template has been modified to be run in local environment using AKS as management cluster, we need to be able to peer the vnets, create private DNS zone for the FQDN of the workload cluster and re-enable blocked NSG ports.
87+
88+
**Note:**
89+
90+
- The following guidance is only for debugging, and is not a recommendation for any production environment.
91+
92+
- The below steps are for self-managed templates only and do not apply to AKS workload clusters.
93+
94+
- If you are going to run the local tests from a dev machine in Azure, you will have to use user-assigned managed identity and assign it to the management cluster. Follow the below steps before proceeding.
95+
1. Create a user-assigned managed identity
96+
2. Assign that managed identity a contributor role to your subscription
97+
3. Set `AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY`, `AZURE_OBJECT_ID_USER_ASSIGNED_IDENTITY`, and `AZURE_USER_ASSIGNED_IDENTITY_RESOURCE_ID` to the user-assigned managed identity.
98+
99+
#### Update prow template with apiserver ILB networking solution
100+
101+
There are three sections of a prow template that need an update.
102+
103+
1. AzureCluster
104+
- `/spec/networkSpec/apiServerLB`
105+
- Add FrontendIP
106+
- Add an associated private IP to be leveraged by an internal ILB
107+
- `/spec/networkSpec/vnet/cidrBlocks`
108+
- Add VNet CIDR
109+
- `/spec/networkSpec/subnets/0/cidrBlocks`
110+
- Add Subnet CIDR for the control plane
111+
- `/spec/networkSpec/subnets/1/cidrBlocks`
112+
- Add Subnet CIDR for the worker node
113+
2. `KubeadmConfigTemplate` - linux node; Identifiable by `name: .*-md-0`
114+
- `/spec/template/spec/preKubeadmCommands/0`
115+
- Add a prekubeadm command updating the `/etc/hosts` of worker nodes of type "linux".
116+
3. `KubeadmConfigTemplate` - windows node; Identifiable by `name: .*-md-win`
117+
- `/spec/template/spec/preKubeadmCommands/0`
118+
- Add a prekubeadm command updating the `/etc/hosts` of worker nodes of type "windows".
119+
120+
A sample kustomize command for updating a prow template via its kustomization.yaml is pasted below.
121+
122+
```yaml
123+
- target:
124+
kind: AzureCluster
125+
patch: |-
126+
- op: add
127+
path: /spec/networkSpec/apiServerLB
128+
value:
129+
frontendIPs:
130+
- name: ${CLUSTER_NAME}-api-lb
131+
publicIP:
132+
dnsName: ${CLUSTER_NAME}-${APISERVER_LB_DNS_SUFFIX}.${AZURE_LOCATION}.cloudapp.azure.com
133+
name: ${CLUSTER_NAME}-api-lb
134+
- name: ${CLUSTER_NAME}-internal-lb-private-ip
135+
privateIP: ${AZURE_INTERNAL_LB_PRIVATE_IP}
136+
- target:
137+
kind: AzureCluster
138+
patch: |-
139+
- op: add
140+
path: /spec/networkSpec/vnet/cidrBlocks
141+
value: []
142+
- op: add
143+
path: /spec/networkSpec/vnet/cidrBlocks/-
144+
value: ${AZURE_VNET_CIDR}
145+
- target:
146+
kind: AzureCluster
147+
patch: |-
148+
- op: add
149+
path: /spec/networkSpec/subnets/0/cidrBlocks
150+
value: []
151+
- op: add
152+
path: /spec/networkSpec/subnets/0/cidrBlocks/-
153+
value: ${AZURE_CP_SUBNET_CIDR}
154+
- target:
155+
kind: AzureCluster
156+
patch: |-
157+
- op: add
158+
path: /spec/networkSpec/subnets/1/cidrBlocks
159+
value: []
160+
- op: add
161+
path: /spec/networkSpec/subnets/1/cidrBlocks/-
162+
value: ${AZURE_NODE_SUBNET_CIDR}
163+
- target:
164+
kind: KubeadmConfigTemplate
165+
name: .*-md-0
166+
patch: |-
167+
- op: add
168+
path: /spec/template/spec/preKubeadmCommands
169+
value: []
170+
- op: add
171+
path: /spec/template/spec/preKubeadmCommands/-
172+
value: echo '${AZURE_INTERNAL_LB_PRIVATE_IP} ${CLUSTER_NAME}-${APISERVER_LB_DNS_SUFFIX}.${AZURE_LOCATION}.cloudapp.azure.com' >> /etc/hosts
173+
- target:
174+
kind: KubeadmConfigTemplate
175+
name: .*-md-win
176+
patch: |-
177+
- op: add
178+
path: /spec/template/spec/preKubeadmCommands/-
179+
value:
180+
powershell -Command "Add-Content -Path 'C:\\Windows\\System32\\drivers\\etc\\hosts' -Value '${AZURE_INTERNAL_LB_PRIVATE_IP} ${CLUSTER_NAME}-${APISERVER_LB_DNS_SUFFIX}.${AZURE_LOCATION}.cloudapp.azure.com'"
181+
```
182+
183+
#### Peer Vnets of the management cluster and the workload cluster
184+
185+
Peering VNets, creating a private DNS zone with the FQDN of the workload cluster, and updating NSGs of the management and workload clusters can be achieved by running `scripts/peer-vnets.sh`.
186+
187+
This script, `scripts/peer-vnets.sh`, should be run after triggering the test run locally and from a separate terminal.
188+
189+
#### Running the test locally
190+
191+
We recommend running each test individually while debugging the test failure. This implies that `GINKGO_FOCUS` is as unique as possible. So for instance if you want to run `periodic-cluster-api-provider-azure-e2e-main`'s "With 3 control-plane nodes and 2 Linux and 2 Windows worker nodes" test,
192+
193+
1. We first need to add the following environment variables to the test itself. For example:
194+
195+
```go
196+
Expect(os.Setenv("EXP_APISERVER_ILB", "true")).To(Succeed())
197+
Expect(os.Setenv("AZURE_INTERNAL_LB_PRIVATE_IP", "10.0.0.101")).To(Succeed())
198+
Expect(os.Setenv("AZURE_VNET_CIDR", "10.0.0.0/8")).To(Succeed())
199+
Expect(os.Setenv("AZURE_CP_SUBNET_CIDR", "10.0.0.0/16")).To(Succeed())
200+
Expect(os.Setenv("AZURE_NODE_SUBNET_CIDR", "10.1.0.0/16")).To(Succeed())
201+
```
202+
203+
The above lines should be added before the `clusterctl.ApplyClusterTemplateAndWait()` is invoked.
204+
205+
206+
2. Open the terminal and run the below command:
207+
208+
```bash
209+
GINKGO_FOCUS="With 3 control-plane nodes and 2 Linux and 2 Windows worker nodes" USE_LOCAL_KIND_REGISTRY=false SKIP_CLEANUP="true" SKIP_LOG_COLLECTION="true" REGISTRY="<>" MGMT_CLUSTER_TYPE="aks" EXP_APISERVER_ILB=true AZURE_LOCATION="<>" ARCH="amd64" scripts/ci-e2e.sh
210+
```
211+
212+
**Note:**
213+
214+
- Set `MGMT_CLUSTER_TYPE` to `"aks"` to leverage `AKS` as the management cluster.
215+
- Set `EXP_APISERVER_ILB` to `true` to enable the API Server ILB feature gate.
216+
- Set `AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY`, `AZURE_OBJECT_ID_USER_ASSIGNED_IDENTITY` and `AZURE_USER_ASSIGNED_IDENTITY_RESOURCE_ID` to use the user-assigned managed identity instead of the AKS-created managed identity.
217+
218+
3. In a new terminal, wait for AzureClusters to be created by the above command. Check it using `kubectl get AzureClusters -A`. Note that this command will fail or will not output anything unless the above command, `GINKGO_FOCUS...`, has deployed the worker template and initiated workload cluster creation.
219+
220+
Once the worker cluster has been created, `export` the `CLUSTER_NAME` and `CLUSTER_NAMESPACE`.
221+
It is recommended that `AZURE_INTERNAL_LB_PRIVATE_IP` is set an IP of `10.0.0.x`, say `10.0.0.101`, to avoid any test updates.
222+
223+
Then open a new terminal at the root of the cluster api provider azure repo and run the below command.
224+
225+
```bash
226+
AZURE_INTERNAL_LB_PRIVATE_IP="<Internal-IP-from-the-e2e-test>" CLUSTER_NAME="<e2e workload-cluster-name>" CLUSTER_NAMESPACE="<e2e-cluster-namespace>" ./scripts/peer-vnets.sh ./tilt-settings.yaml
227+
```
228+
229+
You will see that the test progresses in the first terminal window that invoked `GINKGO_FOCUS=....`
230+
231+
79232
## Leveraging internal load balancer
80233

81234
By default using Tilt with Cluster API Provider Azure (CAPZ), the management cluster is exposed via a public endpoint. This works well for many development scenarios but presents challenges in environments with strict network security requirements.
@@ -127,4 +280,3 @@ By default using Tilt with Cluster API Provider Azure (CAPZ), the management clu
127280
**Solution:**
128281
- Use 3 control plane nodes in a stacked etcd setup.
129282
- Using aks as management cluster sets `CONTROL_PLANE_MACHINE_COUNT` to 3 by default.
130-

e2e.mk

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66
##@ E2E Testing:
77
.PHONY: test-e2e-run
8-
test-e2e-run: generate-e2e-templates install-tools kind-create-bootstrap ## Run e2e tests.
9-
@$(ENVSUBST) < $(E2E_CONF_FILE) > $(E2E_CONF_FILE_ENVSUBST) && \
8+
test-e2e-run: generate-e2e-templates install-tools create-bootstrap ## Run e2e tests.
9+
if [ "$(MGMT_CLUSTER_TYPE)" == "aks" ]; then \
10+
source ./scripts/peer-vnets.sh && source_tilt_settings tilt-settings.yaml; \
11+
fi; \
12+
$(ENVSUBST) < $(E2E_CONF_FILE) > $(E2E_CONF_FILE_ENVSUBST) && \
1013
if [ -z "${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY}" ]; then \
1114
export AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY=$(shell cat $(AZURE_IDENTITY_ID_FILEPATH)); \
1215
fi; \

0 commit comments

Comments
 (0)