@@ -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
5678 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/ } "
79+ if [[ -z " ${SERVICE_ACCOUNT_ISSUER} " ]]; then
80+ export SERVICE_ACCOUNT_ISSUER=" https://${AZWI_STORAGE_ACCOUNT} .blob.core.windows.net/${AZWI_STORAGE_CONTAINER} /"
81+ fi
82+ AZWI_OPENID_CONFIG_FILEPATH=" ${REPO_ROOT} /openid-configuration.json"
83+ cat << EOF > $AZWI_OPENID_CONFIG_FILEPATH
84+ {
85+ "issuer": "${SERVICE_ACCOUNT_ISSUER} ",
86+ "jwks_uri": "${SERVICE_ACCOUNT_ISSUER} openid/v1/jwks",
87+ "response_types_supported": [
88+ "id_token"
89+ ],
90+ "subject_types_supported": [
91+ "public"
92+ ],
93+ "id_token_signing_alg_values_supported": [
94+ "RS256"
95+ ]
96+ }
97+ EOF
98+ if [[ -z " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} " ]]; then
99+ export SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH=" ${REPO_ROOT} /capz-wi-sa.pub"
100+ fi
101+ if [[ -z " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " ]]; then
102+ export SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH=" ${REPO_ROOT} /capz-wi-sa.key"
103+ fi
104+ openssl genrsa -help
105+ openssl genrsa -out " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " 2048
106+ openssl rsa -help
107+ openssl rsa -in " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " -pubout -out " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} "
108+ AZWI_JWKS_JSON_FILEPATH=" ${REPO_ROOT} /jwks.json"
109+ " ${AZWI} " jwks --public-keys " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} " --output-file " ${AZWI_JWKS_JSON_FILEPATH} "
110+ echo " Uploading openid-configuration document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
111+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_OPENID_CONFIG_FILEPATH} " " .well-known/openid-configuration"
112+ echo " Uploading jwks document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
113+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_JWKS_JSON_FILEPATH} " " openid/v1/jwks"
114+ az identity create -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " -l " ${AZWI_LOCATION} " --output none --only-show-errors
115+ AZURE_IDENTITY_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query clientId -o tsv)
116+ AZURE_IDENTITY_ID_PRINCIPAL_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query principalId -o tsv)
117+ echo $AZURE_IDENTITY_ID > " ${AZURE_IDENTITY_ID_FILEPATH} "
118+ 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
119+ sleep 5
120+ done
121+ az identity federated-credential create -n " capz-federated-identity" \
122+ --identity-name " ${USER_IDENTITY} " \
123+ -g " ${AZWI_RESOURCE_GROUP} " \
124+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
125+ --subject " system:serviceaccount:capz-system:capz-manager" --output none --only-show-errors
126+ az identity federated-credential create -n " aso-federated-identity" \
127+ --identity-name " ${USER_IDENTITY} " \
128+ -g " ${AZWI_RESOURCE_GROUP} " \
129+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
130+ --subject " system:serviceaccount:capz-system:azureserviceoperator-default" --output none --only-show-errors
131+ }
132+
133+ function upload_to_blob() {
134+ local container_name=$1
135+ local file_path=$2
136+ local blob_name=$3
137+
138+ echo " Uploading ${file_path} to '${AZWI_STORAGE_ACCOUNT} ' storage account"
139+ az storage blob upload \
140+ --container-name " ${container_name} " \
141+ --file " ${file_path} " \
142+ --name " ${blob_name} " \
143+ --account-name " ${AZWI_STORAGE_ACCOUNT} " \
144+ --output none --only-show-errors
61145}
62146
63147# This function create a kind cluster for Workload identity which requires key pairs path
64148# to be mounted on the kind cluster and hence extra mount flags are required.
65149function createKindForAZWI() {
66- echo " creating azwi kind"
150+ echo " creating workload-identity-enabled kind configuration "
67151 cat << EOF | "${KIND} " create cluster --name "${KIND_CLUSTER_NAME} " --config=-
68152 kind: Cluster
69153 apiVersion: kind.x-k8s.io/v1alpha4
70154 nodes:
71155 - role: control-plane
72156 extraMounts:
73- - hostPath: $HOME /azwi/creds/sa.pub
157+ - hostPath: $SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH
74158 containerPath: /etc/kubernetes/pki/sa.pub
75- - hostPath: $HOME /azwi/creds/sa.key
159+ - hostPath: $SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH
76160 containerPath: /etc/kubernetes/pki/sa.key
77161 kubeadmConfigPatches:
78162 - |
@@ -102,11 +186,11 @@ EOF
102186# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
103187if [ " $AZWI_ENABLED " == ' true' ]
104188 then
105- echo " azwi is enabled..."
189+ echo " workload-identity is enabled..."
106190 checkAZWIENVPreReqsAndCreateFiles
107191 createKindForAZWI
108192else
109- echo " azwi is not enabled..."
193+ echo " workload-identity is not enabled..."
110194 cat << EOF | ${KIND} create cluster --name "${KIND_CLUSTER_NAME} " --config=-
111195kind: Cluster
112196apiVersion: kind.x-k8s.io/v1alpha4
0 commit comments