@@ -19,9 +19,20 @@ 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+ AZWI_STORAGE_ACCOUNT=" oidcissuer${RAND_SUFFIX} "
31+ AZWI_STORAGE_CONTAINER=" oidc"
32+ SERVICE_ACCOUNT_ISSUER=${SERVICE_ACCOUNT_ISSUER:- }
33+ SERVICE_ACCOUNT_SIGNING_PUB=${SERVICE_ACCOUNT_SIGNING_PUB:- }
34+ SERVICE_ACCOUNT_SIGNING_KEY=${SERVICE_ACCOUNT_SIGNING_KEY:- }
35+ AZWI_JWKS_JSON_FILEPATH=${AZWI_JWKS_JSON_FILEPATH:- }
2536make --directory=" ${REPO_ROOT} " " ${KUBECTL##*/ } " " ${KIND##*/ } "
2637
2738# Export desired cluster name; default is "capz"
4455
4556# To use workload identity, service account signing key pairs base64 encoded should be exposed via the
4657# env variables. The function creates the key pair files after reading it from the env variables.
58+ # TODO we need to document that these env vars are a new requirement
4759function checkAZWIENVPreReqsAndCreateFiles() {
48- if [[ -z " ${SERVICE_ACCOUNT_SIGNING_PUB} " ]]; then
49- echo " 'SERVICE_ACCOUNT_SIGNING_PUB' is not set."
50- exit 1
60+ # check if user is logged into azure cli
61+ if ! az account show > /dev/null 2>&1 ; then
62+ echo " Please login to Azure CLI using 'az login'"
63+ exit 1
5164 fi
5265
66+ if [ " $( az group exists --name " ${AZWI_RESOURCE_GROUP} " --output tsv) " == ' false' ]; then
67+ echo " Creating resource group '${AZWI_RESOURCE_GROUP} ' in '${AZWI_LOCATION} '"
68+ az group create --name " ${AZWI_RESOURCE_GROUP} " --location " ${AZWI_LOCATION} " --output none --only-show-errors
69+ fi
70+ if ! az storage account show --name " ${AZWI_STORAGE_ACCOUNT} " --resource-group " ${AZWI_RESOURCE_GROUP} " > /dev/null 2>&1 ; then
71+ echo " Creating storage account '${AZWI_STORAGE_ACCOUNT} ' in '${AZWI_RESOURCE_GROUP} '"
72+ az storage account create --resource-group " ${AZWI_RESOURCE_GROUP} " --name " ${AZWI_STORAGE_ACCOUNT} " --allow-blob-public-access true --output none --only-show-errors
73+ fi
74+ if ! az storage container show --name " ${AZWI_STORAGE_CONTAINER} " --account-name " ${AZWI_STORAGE_ACCOUNT} " > /dev/null 2>&1 ; then
75+ echo " Creating storage container '${AZWI_STORAGE_CONTAINER} ' in '${AZWI_STORAGE_ACCOUNT} '"
76+ az storage container create --name " ${AZWI_STORAGE_CONTAINER} " --account-name " ${AZWI_STORAGE_ACCOUNT} " --public-access blob --output none --only-show-errors
77+ fi
78+ if [[ -z " ${SERVICE_ACCOUNT_ISSUER} " ]]; then
79+ export SERVICE_ACCOUNT_ISSUER=" https://${AZWI_STORAGE_ACCOUNT} .blob.core.windows.net/${AZWI_STORAGE_CONTAINER} /"
80+ fi
81+ AZWI_OPENID_CONFIG_FILEPATH=" ${REPO_ROOT} /openid-configuration.json"
82+ cat << EOF > $AZWI_OPENID_CONFIG_FILEPATH
83+ {
84+ "issuer": "${SERVICE_ACCOUNT_ISSUER} ",
85+ "jwks_uri": "${SERVICE_ACCOUNT_ISSUER} openid/v1/jwks",
86+ "response_types_supported": [
87+ "id_token"
88+ ],
89+ "subject_types_supported": [
90+ "public"
91+ ],
92+ "id_token_signing_alg_values_supported": [
93+ "RS256"
94+ ]
95+ }
96+ EOF
97+ if [[ -z " ${SERVICE_ACCOUNT_SIGNING_PUB} " ]]; then
98+ SERVICE_ACCOUNT_SIGNING_PUB=" ${REPO_ROOT} /capz-ci-sa.pub"
99+ fi
53100 if [[ -z " ${SERVICE_ACCOUNT_SIGNING_KEY} " ]]; then
54- echo " 'SERVICE_ACCOUNT_SIGNING_KEY' is not set."
55- exit 1
101+ SERVICE_ACCOUNT_SIGNING_KEY=" ${REPO_ROOT} /capz-ci-sa.key"
102+ fi
103+ if ! [ -f $SERVICE_ACCOUNT_SIGNING_KEY ]; then
104+ openssl genrsa -out $SERVICE_ACCOUNT_SIGNING_KEY 2048
105+ fi
106+ if ! [ -f $SERVICE_ACCOUNT_SIGNING_PUB ]; then
107+ openssl rsa -in $SERVICE_ACCOUNT_SIGNING_KEY -pubout -out $SERVICE_ACCOUNT_SIGNING_PUB
108+ fi
109+ if [[ -z " ${AZWI_JWKS_JSON_FILEPATH} " ]]; then
110+ AZWI_JWKS_JSON_FILEPATH=" ${REPO_ROOT} /jwks.json"
56111 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/ } "
112+ if ! [ -f $AZWI_JWKS_JSON_FILEPATH ]; then
113+ " ${AZWI} " jwks --public-keys $SERVICE_ACCOUNT_SIGNING_PUB --output-file " ${AZWI_JWKS_JSON_FILEPATH} "
114+ fi
115+ echo " Uploading openid-configuration document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
116+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_OPENID_CONFIG_FILEPATH} " " .well-known/openid-configuration"
117+ echo " Uploading jwks document to '${AZWI_STORAGE_ACCOUNT} ' storage account"
118+ upload_to_blob " ${AZWI_STORAGE_CONTAINER} " " ${AZWI_JWKS_JSON_FILEPATH} " " openid/v1/jwks"
119+ az identity create -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " -l " ${AZWI_LOCATION} " --output none --only-show-errors
120+ AZURE_IDENTITY_ID=$( az identity show -n " ${USER_IDENTITY} " -g " ${AZWI_RESOURCE_GROUP} " --query clientId -o tsv)
121+ echo $AZURE_IDENTITY_ID > $AZURE_IDENTITY_ID_FILEPATH
122+ until az role assignment create --assignee $AZURE_IDENTITY_ID --role " Contributor" --scope " /subscriptions/${AZURE_SUBSCRIPTION_ID} " --output none --only-show-errors; do
123+ sleep 5
124+ done
125+ az identity federated-credential create -n " capz-federated-identity" \
126+ --identity-name " ${USER_IDENTITY} " \
127+ -g " ${AZWI_RESOURCE_GROUP} " \
128+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
129+ --subject " system:serviceaccount:capz-system:capz-manager" --output none --only-show-errors
130+ az identity federated-credential create -n " aso-federated-identity" \
131+ --identity-name " ${USER_IDENTITY} " \
132+ -g " ${AZWI_RESOURCE_GROUP} " \
133+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
134+ --subject " system:serviceaccount:capz-system:azureserviceoperator-default" --output none --only-show-errors
135+ }
136+
137+ function upload_to_blob() {
138+ local container_name=$1
139+ local file_path=$2
140+ local blob_name=$3
141+
142+ echo " Uploading ${file_path} to '${AZWI_STORAGE_ACCOUNT} ' storage account"
143+ az storage blob upload \
144+ --container-name " ${container_name} " \
145+ --file " ${file_path} " \
146+ --name " ${blob_name} " \
147+ --account-name " ${AZWI_STORAGE_ACCOUNT} " \
148+ --output none --only-show-errors
61149}
62150
63151# This function create a kind cluster for Workload identity which requires key pairs path
64152# to be mounted on the kind cluster and hence extra mount flags are required.
65153function createKindForAZWI() {
66- echo " creating azwi kind"
154+ echo " creating workload-identity-enabled kind configuration "
67155 cat << EOF | "${KIND} " create cluster --name "${KIND_CLUSTER_NAME} " --config=-
68156 kind: Cluster
69157 apiVersion: kind.x-k8s.io/v1alpha4
70158 nodes:
71159 - role: control-plane
72160 extraMounts:
73- - hostPath: $HOME /azwi/creds/sa.pub
161+ - hostPath: $SERVICE_ACCOUNT_SIGNING_PUB
74162 containerPath: /etc/kubernetes/pki/sa.pub
75- - hostPath: $HOME /azwi/creds/sa.key
163+ - hostPath: $SERVICE_ACCOUNT_SIGNING_KEY
76164 containerPath: /etc/kubernetes/pki/sa.key
77165 kubeadmConfigPatches:
78166 - |
@@ -102,11 +190,11 @@ EOF
102190# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
103191if [ " $AZWI_ENABLED " == ' true' ]
104192 then
105- echo " azwi is enabled..."
193+ echo " workload-identity is enabled..."
106194 checkAZWIENVPreReqsAndCreateFiles
107195 createKindForAZWI
108196else
109- echo " azwi is not enabled..."
197+ echo " workload-identity is not enabled..."
110198 cat << EOF | ${KIND} create cluster --name "${KIND_CLUSTER_NAME} " --config=-
111199kind: Cluster
112200apiVersion: kind.x-k8s.io/v1alpha4
0 commit comments