Skip to content

Commit de31bcc

Browse files
authored
Merge pull request #4765 from jackfrancis/capz-e2e-workload-identity
CI: workload-identity native
2 parents e9cc97f + 5e6ede0 commit de31bcc

File tree

75 files changed

+504
-696
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+504
-696
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,11 @@ release-*/manifests/calico-*.yaml
8686
# mentioned in the capz book
8787
/sp.json
8888
/cluster.yaml
89+
90+
# CI workload-identity
91+
jwks.json
92+
*.pub
93+
*.key
94+
azure_identity_id
95+
azure_wi_back_compat
96+
openid-configuration.json

Makefile

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ KUSTOMIZE_VER := v5.4.1
8989
KUSTOMIZE_BIN := kustomize
9090
KUSTOMIZE := $(TOOLS_BIN_DIR)/$(KUSTOMIZE_BIN)-$(KUSTOMIZE_VER)
9191

92+
AZWI_VER := v1.2.2
93+
AZWI_BIN := azwi
94+
AZWI := $(TOOLS_BIN_DIR)/$(AZWI_BIN)-$(AZWI_VER)
95+
9296
MOCKGEN_VER := v0.4.0
9397
MOCKGEN_BIN := mockgen
9498
MOCKGEN := $(TOOLS_BIN_DIR)/$(MOCKGEN_BIN)-$(MOCKGEN_VER)
@@ -177,6 +181,7 @@ ARTIFACTS ?= $(ROOT_DIR)/_artifacts
177181
E2E_CONF_FILE ?= $(ROOT_DIR)/test/e2e/config/azure-dev.yaml
178182
E2E_CONF_FILE_ENVSUBST := $(ROOT_DIR)/test/e2e/config/azure-dev-envsubst.yaml
179183
SKIP_CLEANUP ?= false
184+
AZWI_SKIP_CLEANUP ?= false
180185
SKIP_LOG_COLLECTION ?= false
181186
# @sonasingh46: Skip creating mgmt cluster for ci as workload identity needs kind cluster
182187
# to be created with extra mounts for key pairs which is not yet supported
@@ -191,6 +196,11 @@ LDFLAGS := $(shell hack/version.sh)
191196
CLUSTER_TEMPLATE ?= cluster-template.yaml
192197

193198
export KIND_CLUSTER_NAME ?= capz
199+
export RANDOM_SUFFIX := $(shell /bin/bash -c "echo $$RANDOM")
200+
export AZWI_RESOURCE_GROUP ?= capz-wi-$(RANDOM_SUFFIX)
201+
export CI_RG ?= $(AZWI_RESOURCE_GROUP)
202+
export USER_IDENTITY ?= $(addsuffix $(RANDOM_SUFFIX),$(CI_RG))
203+
export AZURE_IDENTITY_ID_FILEPATH ?= $(ROOT_DIR)/azure_identity_id
194204

195205
## --------------------------------------
196206
## Binaries
@@ -287,7 +297,7 @@ verify-codespell: codespell ## Verify codespell.
287297
##@ Development:
288298

289299
.PHONY: install-tools # populate hack/tools/bin
290-
install-tools: $(ENVSUBST) $(KUSTOMIZE) $(KUBECTL) $(HELM) $(GINKGO) $(KIND)
300+
install-tools: $(ENVSUBST) $(KUSTOMIZE) $(KUBECTL) $(HELM) $(GINKGO) $(KIND) $(AZWI)
291301

292302
.PHONY: create-management-cluster
293303
create-management-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) $(KIND) ## Create a management cluster.
@@ -341,7 +351,10 @@ create-management-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) $(KIND) ## Create
341351
.PHONY: create-workload-cluster
342352
create-workload-cluster: $(ENVSUBST) $(KUBECTL) ## Create a workload cluster.
343353
# Create workload Cluster.
344-
@if [ -f "$(TEMPLATES_DIR)/$(CLUSTER_TEMPLATE)" ]; then \
354+
@if [ -z "${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY}" ]; then \
355+
export AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY=$(shell cat $(AZURE_IDENTITY_ID_FILEPATH)); \
356+
fi; \
357+
if [ -f "$(TEMPLATES_DIR)/$(CLUSTER_TEMPLATE)" ]; then \
345358
timeout --foreground 300 bash -c "until $(ENVSUBST) < $(TEMPLATES_DIR)/$(CLUSTER_TEMPLATE) | $(KUBECTL) apply -f -; do sleep 5; done"; \
346359
elif [ -f "$(CLUSTER_TEMPLATE)" ]; then \
347360
timeout --foreground 300 bash -c "until $(ENVSUBST) < "$(CLUSTER_TEMPLATE)" | $(KUBECTL) apply -f -; do sleep 5; done"; \
@@ -686,7 +699,13 @@ test-cover: test ## Run tests with code coverage and generate reports.
686699

687700
.PHONY: kind-create-bootstrap
688701
kind-create-bootstrap: $(KUBECTL) ## Create capz kind bootstrap cluster.
689-
export AZWI=$${AZWI:-true} KIND_CLUSTER_NAME=capz-e2e && ./scripts/kind-with-registry.sh
702+
KIND_CLUSTER_NAME=capz-e2e ./scripts/kind-with-registry.sh
703+
704+
.PHONY: cleanup-workload-identity
705+
cleanup-workload-identity: ## Cleanup CI workload-identity infra
706+
@if ! [ "$(AZWI_SKIP_CLEANUP)" == "true" ]; then \
707+
./scripts/cleanup-workload-identity.sh \
708+
fi
690709

691710
## --------------------------------------
692711
## Security Scanning
@@ -708,6 +727,9 @@ kind-create: $(KUBECTL) ## Create capz kind cluster if needed.
708727

709728
.PHONY: tilt-up
710729
tilt-up: install-tools kind-create ## Start tilt and build kind cluster if needed.
730+
@if [ -z "${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY}" ]; then \
731+
export AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY=$(shell cat $(AZURE_IDENTITY_ID_FILEPATH)); \
732+
fi; \
711733
CLUSTER_TOPOLOGY=true EXP_CLUSTER_RESOURCE_SET=true EXP_MACHINE_POOL=true EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true EXP_EDGEZONE=true tilt up
712734

713735
.PHONY: delete-cluster
@@ -792,6 +814,16 @@ $(HELM): ## Put helm into tools folder.
792814
ln -sf $(HELM) $(TOOLS_BIN_DIR)/$(HELM_BIN)
793815
rm -f $(TOOLS_BIN_DIR)/get_helm.sh
794816

817+
$(AZWI): ## Put azwi into tools folder.
818+
mkdir -p $(TOOLS_BIN_DIR)
819+
rm -f "$(TOOLS_BIN_DIR)/$(AZWI_BIN)*"
820+
curl --retry $(CURL_RETRIES) -fsSL -o $(TOOLS_BIN_DIR)/azwi.tar.gz https://github.com/Azure/azure-workload-identity/releases/download/$(AZWI_VER)/azwi-$(AZWI_VER)-$(GOOS)-$(GOARCH).tar.gz
821+
tar -xf "$(TOOLS_BIN_DIR)/azwi.tar.gz" -C $(TOOLS_BIN_DIR) $(AZWI_BIN)
822+
mv "$(TOOLS_BIN_DIR)/$(AZWI_BIN)" $(AZWI)
823+
ln -sf $(AZWI) $(TOOLS_BIN_DIR)/$(AZWI_BIN)
824+
chmod +x $(AZWI) $(TOOLS_BIN_DIR)/$(AZWI_BIN)
825+
rm -f $(TOOLS_BIN_DIR)/azwi.tar.gz
826+
795827
$(KIND): ## Build kind into tools folder.
796828
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) sigs.k8s.io/kind $(KIND_BIN) $(KIND_VER)
797829

Tiltfile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ settings = {
3535
}
3636

3737
# Auth keys that need to be loaded from the environment
38-
keys = ["AZURE_SUBSCRIPTION_ID", "AZURE_TENANT_ID", "AZURE_CLIENT_SECRET", "AZURE_CLIENT_ID"]
38+
keys = ["AZURE_SUBSCRIPTION_ID", "AZURE_TENANT_ID", "AZURE_CLIENT_ID"]
3939

4040
# Get global settings from tilt-settings.yaml or tilt-settings.json
4141
tilt_file = "./tilt-settings.yaml" if os.path.exists("./tilt-settings.yaml") else "./tilt-settings.json"
@@ -266,13 +266,10 @@ def create_identity_secret():
266266

267267
os.putenv("AZURE_CLUSTER_IDENTITY_SECRET_NAME", "cluster-identity-secret")
268268
os.putenv("AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE", "default")
269-
os.putenv("CLUSTER_IDENTITY_NAME", "cluster-identity")
269+
os.putenv("CLUSTER_IDENTITY_NAME", "cluster-identity-ci")
270270
os.putenv("ASO_CREDENTIAL_SECRET_NAME", "aso-credentials")
271271

272-
os.putenv("AZURE_CLIENT_SECRET_B64", base64_encode(os.environ.get("AZURE_CLIENT_SECRET")))
273-
local("cat templates/azure-cluster-identity/secret.yaml | " + envsubst_cmd + " | " + kubectl_cmd + " apply -f -", quiet = True, echo_off = True)
274272
local("cat templates/flavors/aks-aso/credentials.yaml | " + envsubst_cmd + " | " + kubectl_cmd + " apply -f -", quiet = True, echo_off = True)
275-
os.unsetenv("AZURE_CLIENT_SECRET_B64")
276273

277274
def create_crs():
278275
# create config maps

docs/book/src/topics/workload-identity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ to give the identity Contributor access to the Azure subscription where the work
169169
- At this stage, you can apply this yaml to create a workload cluster.
170170
171171
Notes:
172-
- Please follow this [link](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/templates/test/ci/cluster-template-prow-workload-identity.yaml)
172+
- Please follow this [link](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/templates/test/ci/cluster-template-prow.yaml)
173173
to see a workload cluster yaml configuration that uses workload identity.
174174
- Creating a workload cluster via workload identity will be
175175
simplified after [this](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues/3589) issue is resolved.

e2e.mk

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44
# long-running E2E jobs every time that file changes
55

66
##@ E2E Testing:
7-
87
.PHONY: test-e2e-run
98
test-e2e-run: generate-e2e-templates install-tools kind-create-bootstrap ## Run e2e tests.
10-
$(ENVSUBST) < $(E2E_CONF_FILE) > $(E2E_CONF_FILE_ENVSUBST) && \
11-
$(GINKGO) -v --trace --timeout=4h --tags=e2e --focus="$(GINKGO_FOCUS)" --skip="$(GINKGO_SKIP)" --nodes=$(GINKGO_NODES) --no-color=$(GINKGO_NOCOLOR) --output-dir="$(ARTIFACTS)" --junit-report="junit.e2e_suite.1.xml" $(GINKGO_ARGS) ./test/e2e -- \
12-
-e2e.artifacts-folder="$(ARTIFACTS)" \
13-
-e2e.config="$(E2E_CONF_FILE_ENVSUBST)" \
14-
-e2e.skip-log-collection="$(SKIP_LOG_COLLECTION)" \
15-
-e2e.skip-resource-cleanup=$(SKIP_CLEANUP) -e2e.use-existing-cluster=$(SKIP_CREATE_MGMT_CLUSTER) $(E2E_ARGS)
9+
@$(ENVSUBST) < $(E2E_CONF_FILE) > $(E2E_CONF_FILE_ENVSUBST) && \
10+
if [ -z "${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY}" ]; then \
11+
export AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY=$(shell cat $(AZURE_IDENTITY_ID_FILEPATH)); \
12+
fi; \
13+
$(GINKGO) -v --trace --timeout=4h --tags=e2e --focus="$(GINKGO_FOCUS)" --skip="$(GINKGO_SKIP)" --nodes=$(GINKGO_NODES) --no-color=$(GINKGO_NOCOLOR) --output-dir="$(ARTIFACTS)" --junit-report="junit.e2e_suite.1.xml" $(GINKGO_ARGS) ./test/e2e -- \
14+
-e2e.artifacts-folder="$(ARTIFACTS)" \
15+
-e2e.config="$(E2E_CONF_FILE_ENVSUBST)" \
16+
-e2e.skip-log-collection="$(SKIP_LOG_COLLECTION)" \
17+
-e2e.skip-resource-cleanup=$(SKIP_CLEANUP) -e2e.use-existing-cluster=$(SKIP_CREATE_MGMT_CLUSTER) $(E2E_ARGS) \
18+
$(MAKE) cleanup-workload-identity
1619
$(MAKE) clean-release-git
1720

1821
.PHONY: test-e2e

hack/create-dev-cluster.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export AZURE_VNET_NAME=${CLUSTER_NAME}-vnet
3838
export AZURE_LOCATION="${AZURE_LOCATION:-southcentralus}"
3939
export AZURE_RESOURCE_GROUP=${CLUSTER_NAME}
4040

41+
AZURE_SUBSCRIPTION_ID="${AZURE_SUBSCRIPTION_ID:=}"
42+
AZURE_TENANT_ID="${AZURE_TENANT_ID:=}"
43+
AZURE_CLIENT_ID="${AZURE_CLIENT_ID:=}"
44+
AZURE_CLIENT_SECRET="${AZURE_CLIENT_SECRET:=}"
45+
4146
AZURE_SUBSCRIPTION_ID_B64="$(echo -n "$AZURE_SUBSCRIPTION_ID" | base64 | tr -d '\n')"
4247
AZURE_TENANT_ID_B64="$(echo -n "$AZURE_TENANT_ID" | base64 | tr -d '\n')"
4348
AZURE_CLIENT_ID_B64="$(echo -n "$AZURE_CLIENT_ID" | base64 | tr -d '\n')"

hack/log/redact.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ redact_vars=(
2828
"${AZURE_SUBSCRIPTION_ID:-}"
2929
"${AZURE_TENANT_ID:-}"
3030
"${AZURE_JSON_B64:-}"
31+
"${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY:-}"
3132
"$(echo -n "${AZURE_SUBSCRIPTION_ID:-}" | base64 | tr -d '\n')"
3233
"$(echo -n "${AZURE_TENANT_ID:-}" | base64 | tr -d '\n')"
3334
"$(echo -n "${AZURE_CLIENT_ID:-}" | base64 | tr -d '\n')"
3435
"$(echo -n "${AZURE_CLIENT_SECRET:-}" | base64 | tr -d '\n')"
36+
"$(echo -n "${AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY:-}" | base64 | tr -d '\n')"
3537
)
3638

3739
for log_file in "${log_files[@]}"; do

hack/util.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,4 @@ capz::util::generate_ssh_key() {
108108
capz::util::ensure_azure_envs() {
109109
: "${AZURE_SUBSCRIPTION_ID:?Environment variable empty or not defined.}"
110110
: "${AZURE_TENANT_ID:?Environment variable empty or not defined.}"
111-
: "${AZURE_CLIENT_ID:?Environment variable empty or not defined.}"
112-
: "${AZURE_CLIENT_SECRET:?Environment variable empty or not defined.}"
113111
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2024 The Kubernetes Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -o errexit
17+
set -o nounset
18+
set -o pipefail
19+
20+
# Install kubectl and kind
21+
REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
22+
# shellcheck source=hack/ensure-azcli.sh
23+
source "${REPO_ROOT}/hack/ensure-azcli.sh"
24+
25+
AZWI_RESOURCE_GROUP="${AZWI_RESOURCE_GROUP:-}"
26+
27+
if [[ -z "${AZWI_RESOURCE_GROUP}" ]]; then
28+
echo AZWI_RESOURCE_GROUP environment variable must be set
29+
exit 1
30+
fi
31+
32+
echo "Cleaning up CI workload-identity infra..."
33+
az group delete --no-wait -y -n "${AZWI_RESOURCE_GROUP}"

0 commit comments

Comments
 (0)