@@ -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=${SERVICE_ACCOUNT_SIGNING_PUB:- }
34+ export SERVICE_ACCOUNT_SIGNING_KEY=${SERVICE_ACCOUNT_SIGNING_KEY:- }
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+ # check if user is logged into azure cli
60+ if ! az account show > /dev/null 2>&1 ; then
61+ echo " Please login to Azure CLI using 'az login'"
62+ exit 1
5163 fi
5264
65+ if [ " $( az group exists --name " ${AZWI_RESOURCE_GROUP} " --output tsv) " == ' false' ]; then
66+ echo " Creating resource group '${AZWI_RESOURCE_GROUP} ' in '${AZWI_LOCATION} '"
67+ az group create --name " ${AZWI_RESOURCE_GROUP} " --location " ${AZWI_LOCATION} " --output none --only-show-errors
68+ fi
69+ if ! az storage account show --name " ${AZWI_STORAGE_ACCOUNT} " --resource-group " ${AZWI_RESOURCE_GROUP} " > /dev/null 2>&1 ; then
70+ echo " Creating storage account '${AZWI_STORAGE_ACCOUNT} ' in '${AZWI_RESOURCE_GROUP} '"
71+ az storage account create --resource-group " ${AZWI_RESOURCE_GROUP} " --name " ${AZWI_STORAGE_ACCOUNT} " --allow-blob-public-access true --output none --only-show-errors
72+ fi
73+ if ! az storage container show --name " ${AZWI_STORAGE_CONTAINER} " --account-name " ${AZWI_STORAGE_ACCOUNT} " > /dev/null 2>&1 ; then
74+ echo " Creating storage container '${AZWI_STORAGE_CONTAINER} ' in '${AZWI_STORAGE_ACCOUNT} '"
75+ az storage container create --name " ${AZWI_STORAGE_CONTAINER} " --account-name " ${AZWI_STORAGE_ACCOUNT} " --public-access blob --output none --only-show-errors
76+ fi
77+ if [[ -z " ${SERVICE_ACCOUNT_ISSUER} " ]]; then
78+ export SERVICE_ACCOUNT_ISSUER=" https://${AZWI_STORAGE_ACCOUNT} .blob.core.windows.net/${AZWI_STORAGE_CONTAINER} /"
79+ fi
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} " ]]; then
97+ export SERVICE_ACCOUNT_SIGNING_PUB=" ${REPO_ROOT} /capz-ci-sa.pub"
98+ fi
5399 if [[ -z " ${SERVICE_ACCOUNT_SIGNING_KEY} " ]]; then
54- echo " 'SERVICE_ACCOUNT_SIGNING_KEY' is not set."
55- exit 1
100+ export SERVICE_ACCOUNT_SIGNING_KEY=" ${REPO_ROOT} /capz-ci-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 2048
103+ openssl rsa -in $SERVICE_ACCOUNT_SIGNING_KEY -pubout -out $SERVICE_ACCOUNT_SIGNING_PUB
104+ AZWI_JWKS_JSON_FILEPATH=" ${REPO_ROOT} /jwks.json"
105+ " ${AZWI} " jwks --public-keys $SERVICE_ACCOUNT_SIGNING_PUB --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+ echo $AZURE_IDENTITY_ID > $AZURE_IDENTITY_ID_FILEPATH
113+ until az role assignment create --assignee $AZURE_IDENTITY_ID --role " Contributor" --scope " /subscriptions/${AZURE_SUBSCRIPTION_ID} " --output none --only-show-errors; do
114+ sleep 5
115+ done
116+ az identity federated-credential create -n " capz-federated-identity" \
117+ --identity-name " ${USER_IDENTITY} " \
118+ -g " ${AZWI_RESOURCE_GROUP} " \
119+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
120+ --subject " system:serviceaccount:capz-system:capz-manager" --output none --only-show-errors
121+ az identity federated-credential create -n " aso-federated-identity" \
122+ --identity-name " ${USER_IDENTITY} " \
123+ -g " ${AZWI_RESOURCE_GROUP} " \
124+ --issuer " ${SERVICE_ACCOUNT_ISSUER} " \
125+ --subject " system:serviceaccount:capz-system:azureserviceoperator-default" --output none --only-show-errors
126+ }
127+
128+ function upload_to_blob() {
129+ local container_name=$1
130+ local file_path=$2
131+ local blob_name=$3
132+
133+ echo " Uploading ${file_path} to '${AZWI_STORAGE_ACCOUNT} ' storage account"
134+ az storage blob upload \
135+ --container-name " ${container_name} " \
136+ --file " ${file_path} " \
137+ --name " ${blob_name} " \
138+ --account-name " ${AZWI_STORAGE_ACCOUNT} " \
139+ --output none --only-show-errors
61140}
62141
63142# This function create a kind cluster for Workload identity which requires key pairs path
64143# to be mounted on the kind cluster and hence extra mount flags are required.
65144function createKindForAZWI() {
66- echo " creating azwi kind"
145+ echo " creating workload-identity-enabled kind configuration "
67146 cat << EOF | "${KIND} " create cluster --name "${KIND_CLUSTER_NAME} " --config=-
68147 kind: Cluster
69148 apiVersion: kind.x-k8s.io/v1alpha4
70149 nodes:
71150 - role: control-plane
72151 extraMounts:
73- - hostPath: $HOME /azwi/creds/sa.pub
152+ - hostPath: $SERVICE_ACCOUNT_SIGNING_PUB
74153 containerPath: /etc/kubernetes/pki/sa.pub
75- - hostPath: $HOME /azwi/creds/sa.key
154+ - hostPath: $SERVICE_ACCOUNT_SIGNING_KEY
76155 containerPath: /etc/kubernetes/pki/sa.key
77156 kubeadmConfigPatches:
78157 - |
@@ -102,11 +181,11 @@ EOF
102181# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
103182if [ " $AZWI_ENABLED " == ' true' ]
104183 then
105- echo " azwi is enabled..."
184+ echo " workload-identity is enabled..."
106185 checkAZWIENVPreReqsAndCreateFiles
107186 createKindForAZWI
108187else
109- echo " azwi is not enabled..."
188+ echo " workload-identity is not enabled..."
110189 cat << EOF | ${KIND} create cluster --name "${KIND_CLUSTER_NAME} " --config=-
111190kind: Cluster
112191apiVersion: kind.x-k8s.io/v1alpha4
0 commit comments