@@ -19,9 +19,19 @@ set -o pipefail
1919
2020# Install kubectl and kind
2121REPO_ROOT=$( dirname " ${BASH_SOURCE[0]} " ) /..
22+ # shellcheck source=hack/ensure-azcli.sh
23+ source " ${REPO_ROOT} /hack/ensure-azcli.sh"
24+
2225KUBECTL=" ${REPO_ROOT} /hack/tools/bin/kubectl"
2326KIND=" ${REPO_ROOT} /hack/tools/bin/kind"
24- AZWI_ENABLED=${AZWI:- }
27+ AZWI=" ${REPO_ROOT} /hack/tools/bin/azwi"
28+ AZWI_ENABLED=${AZWI_ENABLED:- true}
29+ RAND_SUFFIX=$( openssl rand -hex 4)
30+ export AZWI_STORAGE_ACCOUNT=" oidcissuer${RAND_SUFFIX} "
31+ export AZWI_STORAGE_CONTAINER=" oidc"
32+ export SERVICE_ACCOUNT_ISSUER=${SERVICE_ACCOUNT_ISSUER:- }
33+ export SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH=${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH:- }
34+ export SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH=${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH:- }
2535make --directory=" ${REPO_ROOT} " " ${KUBECTL##*/ } " " ${KIND##*/ } "
2636
2737# Export desired cluster name; default is "capz"
4454
4555# To use workload identity, service account signing key pairs base64 encoded should be exposed via the
4656# env variables. The function creates the key pair files after reading it from the env variables.
57+ # TODO we need to document that these env vars are a new requirement
4758function checkAZWIENVPreReqsAndCreateFiles() {
48- if [[ -z " ${SERVICE_ACCOUNT_SIGNING_PUB} " ]]; then
49- echo " 'SERVICE_ACCOUNT_SIGNING_PUB' is not set."
50- exit 1
59+ unset AZURE_STORAGE_KEY
60+ unset AZURE_STORAGE_ACCOUNT
61+ # check if user is logged into azure cli
62+ if ! az account show > /dev/null 2>&1 ; then
63+ echo " Please login to Azure CLI using 'az login'"
64+ exit 1
5165 fi
5266
53- if [[ -z " ${SERVICE_ACCOUNT_SIGNING_KEY} " ]]; then
54- echo " 'SERVICE_ACCOUNT_SIGNING_KEY' is not set."
55- exit 1
67+ if [ " $( az group exists --name " ${AZWI_RESOURCE_GROUP} " --output tsv) " == ' false' ]; then
68+ echo " Creating resource group '${AZWI_RESOURCE_GROUP} ' in '${AZWI_LOCATION} '"
69+ az group create --name " ${AZWI_RESOURCE_GROUP} " --location " ${AZWI_LOCATION} " --output none --only-show-errors
70+ fi
71+ if ! az storage account show --name " ${AZWI_STORAGE_ACCOUNT} " --resource-group " ${AZWI_RESOURCE_GROUP} " > /dev/null 2>&1 ; then
72+ echo " Creating storage account '${AZWI_STORAGE_ACCOUNT} ' in '${AZWI_RESOURCE_GROUP} '"
73+ az storage account create --resource-group " ${AZWI_RESOURCE_GROUP} " --name " ${AZWI_STORAGE_ACCOUNT} " --allow-blob-public-access true --output none --only-show-errors
74+ fi
75+ if ! az storage container show --name " ${AZWI_STORAGE_CONTAINER} " --account-name " ${AZWI_STORAGE_ACCOUNT} " > /dev/null 2>&1 ; then
76+ echo " Creating storage container '${AZWI_STORAGE_CONTAINER} ' in '${AZWI_STORAGE_ACCOUNT} '"
77+ az storage container create --name " ${AZWI_STORAGE_CONTAINER} " --account-name " ${AZWI_STORAGE_ACCOUNT} " --public-access blob --output none --only-show-errors
78+ fi
79+ export SERVICE_ACCOUNT_ISSUER=" https://${AZWI_STORAGE_ACCOUNT} .blob.core.windows.net/${AZWI_STORAGE_CONTAINER} /"
80+ AZWI_OPENID_CONFIG_FILEPATH=" ${REPO_ROOT} /openid-configuration.json"
81+ cat << EOF > "${AZWI_OPENID_CONFIG_FILEPATH} "
82+ {
83+ "issuer": "${SERVICE_ACCOUNT_ISSUER} ",
84+ "jwks_uri": "${SERVICE_ACCOUNT_ISSUER} openid/v1/jwks",
85+ "response_types_supported": [
86+ "id_token"
87+ ],
88+ "subject_types_supported": [
89+ "public"
90+ ],
91+ "id_token_signing_alg_values_supported": [
92+ "RS256"
93+ ]
94+ }
95+ EOF
96+ if [[ -z " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} " ]]; then
97+ export SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH=" ${REPO_ROOT} /capz-wi-sa.pub"
98+ fi
99+ if [[ -z " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " ]]; then
100+ export SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH=" ${REPO_ROOT} /capz-wi-sa.key"
56101 fi
57- mkdir -p " $HOME " /azwi/creds
58- echo " ${SERVICE_ACCOUNT_SIGNING_PUB} " > " $HOME " /azwi/creds/sa.pub
59- echo " ${SERVICE_ACCOUNT_SIGNING_KEY} " > " $HOME " /azwi/creds/sa.key
60- SERVICE_ACCOUNT_ISSUER=" ${SERVICE_ACCOUNT_ISSUER:- https:// oidcissuercapzci.blob.core.windows.net/ oidc-capzci/ } "
102+ openssl genrsa -out " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " 2048
103+ openssl rsa -in " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " -pubout -out " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} "
104+ AZWI_JWKS_JSON_FILEPATH=" ${REPO_ROOT} /jwks.json"
105+ " ${AZWI} " jwks --public-keys " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} " --output-file " ${AZWI_JWKS_JSON_FILEPATH} "
106+ echo " Uploading openid-configuration document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
107+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_OPENID_CONFIG_FILEPATH} " " .well-known/openid-configuration"
108+ echo " Uploading jwks document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
109+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_JWKS_JSON_FILEPATH} " " openid/v1/jwks"
110+ az identity create -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " -l " ${AZWI_LOCATION} " --output none --only-show-errors
111+ AZURE_IDENTITY_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query clientId -o tsv)
112+ AZURE_IDENTITY_ID_PRINCIPAL_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query principalId -o tsv)
113+ echo " ${AZURE_IDENTITY_ID} " > " ${AZURE_IDENTITY_ID_FILEPATH} "
114+ until az role assignment create --assignee-object-id " ${AZURE_IDENTITY_ID_PRINCIPAL_ID} " --role " Contributor" --scope " /subscriptions/${AZURE_SUBSCRIPTION_ID} " --assignee-principal-type ServicePrincipal --output none --only-show-errors; do
115+ sleep 5
116+ done
117+ az identity federated-credential create -n " capz-federated-identity" \
118+ --identity-name " ${USER_IDENTITY} " \
119+ -g " ${AZWI_RESOURCE_GROUP} " \
120+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
121+ --subject " system:serviceaccount:capz-system:capz-manager" --output none --only-show-errors
122+ az identity federated-credential create -n " aso-federated-identity" \
123+ --identity-name " ${USER_IDENTITY} " \
124+ -g " ${AZWI_RESOURCE_GROUP} " \
125+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
126+ --subject " system:serviceaccount:capz-system:azureserviceoperator-default" --output none --only-show-errors
127+ }
128+
129+ function upload_to_blob() {
130+ local container_name=$1
131+ local file_path=$2
132+ local blob_name=$3
133+
134+ echo " Uploading ${file_path} to '${AZWI_STORAGE_ACCOUNT} ' storage account"
135+ az storage blob upload \
136+ --container-name " ${container_name} " \
137+ --file " ${file_path} " \
138+ --name " ${blob_name} " \
139+ --account-name " ${AZWI_STORAGE_ACCOUNT} " \
140+ --output none --only-show-errors
61141}
62142
63143# This function create a kind cluster for Workload identity which requires key pairs path
64144# to be mounted on the kind cluster and hence extra mount flags are required.
65145function createKindForAZWI() {
66- echo " creating azwi kind"
146+ echo " creating workload-identity-enabled kind configuration "
67147 cat << EOF | "${KIND} " create cluster --name "${KIND_CLUSTER_NAME} " --config=-
68148 kind: Cluster
69149 apiVersion: kind.x-k8s.io/v1alpha4
70150 nodes:
71151 - role: control-plane
72152 extraMounts:
73- - hostPath: $HOME /azwi/creds/sa.pub
153+ - hostPath: $SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH
74154 containerPath: /etc/kubernetes/pki/sa.pub
75- - hostPath: $HOME /azwi/creds/sa.key
155+ - hostPath: $SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH
76156 containerPath: /etc/kubernetes/pki/sa.key
77157 kubeadmConfigPatches:
78158 - |
@@ -102,11 +182,11 @@ EOF
102182# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
103183if [ " $AZWI_ENABLED " == ' true' ]
104184 then
105- echo " azwi is enabled..."
185+ echo " workload-identity is enabled..."
106186 checkAZWIENVPreReqsAndCreateFiles
107187 createKindForAZWI
108188else
109- echo " azwi is not enabled..."
189+ echo " workload-identity is not enabled..."
110190 cat << EOF | ${KIND} create cluster --name "${KIND_CLUSTER_NAME} " --config=-
111191kind: Cluster
112192apiVersion: kind.x-k8s.io/v1alpha4
0 commit comments