@@ -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 -help
103+ openssl genrsa -out " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " 2048
104+ openssl rsa -help
105+ openssl rsa -in " ${SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH} " -pubout -out " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} "
106+ AZWI_JWKS_JSON_FILEPATH=" ${REPO_ROOT} /jwks.json"
107+ " ${AZWI} " jwks --public-keys " ${SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH} " --output-file " ${AZWI_JWKS_JSON_FILEPATH} "
108+ echo " Uploading openid-configuration document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
109+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_OPENID_CONFIG_FILEPATH} " " .well-known/openid-configuration"
110+ echo " Uploading jwks document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
111+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_JWKS_JSON_FILEPATH} " " openid/v1/jwks"
112+ az identity create -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " -l " ${AZWI_LOCATION} " --output none --only-show-errors
113+ AZURE_IDENTITY_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query clientId -o tsv)
114+ AZURE_IDENTITY_ID_PRINCIPAL_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query principalId -o tsv)
115+ echo $AZURE_IDENTITY_ID > " ${AZURE_IDENTITY_ID_FILEPATH} "
116+ 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
117+ sleep 5
118+ done
119+ az identity federated-credential create -n " capz-federated-identity" \
120+ --identity-name " ${USER_IDENTITY} " \
121+ -g " ${AZWI_RESOURCE_GROUP} " \
122+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
123+ --subject " system:serviceaccount:capz-system:capz-manager" --output none --only-show-errors
124+ az identity federated-credential create -n " aso-federated-identity" \
125+ --identity-name " ${USER_IDENTITY} " \
126+ -g " ${AZWI_RESOURCE_GROUP} " \
127+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
128+ --subject " system:serviceaccount:capz-system:azureserviceoperator-default" --output none --only-show-errors
129+ }
130+
131+ function upload_to_blob() {
132+ local container_name=$1
133+ local file_path=$2
134+ local blob_name=$3
135+
136+ echo " Uploading ${file_path} to '${AZWI_STORAGE_ACCOUNT} ' storage account"
137+ az storage blob upload \
138+ --container-name " ${container_name} " \
139+ --file " ${file_path} " \
140+ --name " ${blob_name} " \
141+ --account-name " ${AZWI_STORAGE_ACCOUNT} " \
142+ --output none --only-show-errors
61143}
62144
63145# This function create a kind cluster for Workload identity which requires key pairs path
64146# to be mounted on the kind cluster and hence extra mount flags are required.
65147function createKindForAZWI() {
66- echo " creating azwi kind"
148+ echo " creating workload-identity-enabled kind configuration "
67149 cat << EOF | "${KIND} " create cluster --name "${KIND_CLUSTER_NAME} " --config=-
68150 kind: Cluster
69151 apiVersion: kind.x-k8s.io/v1alpha4
70152 nodes:
71153 - role: control-plane
72154 extraMounts:
73- - hostPath: $HOME /azwi/creds/sa.pub
155+ - hostPath: $SERVICE_ACCOUNT_SIGNING_PUB_FILEPATH
74156 containerPath: /etc/kubernetes/pki/sa.pub
75- - hostPath: $HOME /azwi/creds/sa.key
157+ - hostPath: $SERVICE_ACCOUNT_SIGNING_KEY_FILEPATH
76158 containerPath: /etc/kubernetes/pki/sa.key
77159 kubeadmConfigPatches:
78160 - |
@@ -102,11 +184,11 @@ EOF
102184# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
103185if [ " $AZWI_ENABLED " == ' true' ]
104186 then
105- echo " azwi is enabled..."
187+ echo " workload-identity is enabled..."
106188 checkAZWIENVPreReqsAndCreateFiles
107189 createKindForAZWI
108190else
109- echo " azwi is not enabled..."
191+ echo " workload-identity is not enabled..."
110192 cat << EOF | ${KIND} create cluster --name "${KIND_CLUSTER_NAME} " --config=-
111193kind: Cluster
112194apiVersion: kind.x-k8s.io/v1alpha4
0 commit comments