Last active
July 12, 2024 15:54
-
-
Save vyta/4857bbc3e2da2f2e377664742bf2a16d to your computer and use it in GitHub Desktop.
Kind with OIDC issuer tl;dr;
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Script pre-reqs: az cli (and logged in) and kind (k8s in docker) | |
export RESOURCE_GROUP="oidc-issuer" | |
export SUBSCRIPTION_ID="$(az account show --query id -o tsv)" | |
export AZURE_TENANT_ID="$(az account show --query tenantId -otsv)" | |
export AZURE_STORAGE_ACCOUNT="oidcissuer$(openssl rand -hex 4)" | |
export AZURE_STORAGE_CONTAINER="oidc-test" | |
export SERVICE_ACCOUNT_ISSUER="https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/" | |
export SERVICE_ACCOUNT_KEY_FILE="$(pwd)/sa.pub" | |
export SERVICE_ACCOUNT_SIGNING_KEY_FILE="$(pwd)/sa.key" | |
export SERVICE_ACCOUNT_NAME="test-azwi" | |
export SERVICE_ACCOUNT_NAMESPACE="default" | |
export KEYVAULT_NAME="azwi-kv-$(openssl rand -hex 2)" | |
export KEYVAULT_SECRET_NAME="my-secret" | |
export USER_ASSIGNED_IDENTITY_NAME="azwi-test" | |
# Create keyvault, identity, assign roles and create secret to be accessed by workload | |
az keyvault create --resource-group "${RESOURCE_GROUP}" --name "${KEYVAULT_NAME}" | |
az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" | |
export USER_ASSIGNED_IDENTITY_CLIENT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'clientId' -otsv)" | |
export USER_ASSIGNED_IDENTITY_OBJECT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'principalId' -otsv)" | |
# Assign admin roles to self to create secret | |
az role assignment create --assignee "$(az ad signed-in-user show --query id -o tsv)" \ | |
--role "Key Vault Administrator" \ | |
--scope /subscriptions/${SUBSCRIPTION_ID}/resourcegroups/${RESOURCE_GROUP}/providers/microsoft.keyvault/vaults/${KEYVAULT_NAME} | |
az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value "Hello\!" | |
# Assign secret user role to identity to be used in workload later | |
az role assignment create --assignee "${USER_ASSIGNED_IDENTITY_OBJECT_ID}" \ | |
--role "Key Vault Secrets User" \ | |
--scope /subscriptions/${SUBSCRIPTION_ID}/resourcegroups/${RESOURCE_GROUP}/providers/microsoft.keyvault/vaults/${KEYVAULT_NAME} | |
# Create key-pair for service account issuer | |
openssl genrsa -out sa.key 2048 | |
openssl rsa -in sa.key -pubout -out sa.pub | |
# Use azwi cli for JWK creation | |
curl -LO https://github.com/Azure/azure-workload-identity/releases/download/v1.3.0/azwi-v1.3.0-linux-amd64.tar.gz | |
tar -zxvf azwi-v1.3.0-linux-amd64.tar.gz | |
chmod +x azwi | |
./azwi jwks --public-keys sa.pub --output-file jwks.json | |
# Upload discovery doc and JWK to public endpoint | |
az storage account create --resource-group "${RESOURCE_GROUP}" --name "${AZURE_STORAGE_ACCOUNT}" --allow-blob-public-access true | |
az storage container create --name "${AZURE_STORAGE_CONTAINER}" --public-access blob | |
cat <<EOF > openid-configuration.json | |
{ | |
"issuer": "https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/", | |
"jwks_uri": "https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/openid/v1/jwks", | |
"response_types_supported": [ | |
"id_token" | |
], | |
"subject_types_supported": [ | |
"public" | |
], | |
"id_token_signing_alg_values_supported": [ | |
"RS256" | |
] | |
} | |
EOF | |
az storage blob upload \ | |
--container-name "${AZURE_STORAGE_CONTAINER}" \ | |
--file openid-configuration.json \ | |
--name .well-known/openid-configuration | |
az storage blob upload \ | |
--container-name "${AZURE_STORAGE_CONTAINER}" \ | |
--file jwks.json \ | |
--name openid/v1/jwks | |
# Configure with issuer and keys and create kind cluster | |
cat <<EOF | kind create cluster --name kind-oidc --config=- | |
kind: Cluster | |
apiVersion: kind.x-k8s.io/v1alpha4 | |
nodes: | |
- role: control-plane | |
extraMounts: | |
- hostPath: ${SERVICE_ACCOUNT_KEY_FILE} | |
containerPath: /etc/kubernetes/pki/sa.pub | |
- hostPath: ${SERVICE_ACCOUNT_SIGNING_KEY_FILE} | |
containerPath: /etc/kubernetes/pki/sa.key | |
kubeadmConfigPatches: | |
- | | |
kind: ClusterConfiguration | |
apiServer: | |
extraArgs: | |
service-account-issuer: ${SERVICE_ACCOUNT_ISSUER} | |
service-account-key-file: /etc/kubernetes/pki/sa.pub | |
service-account-signing-key-file: /etc/kubernetes/pki/sa.key | |
controllerManager: | |
extraArgs: | |
service-account-private-key-file: /etc/kubernetes/pki/sa.key | |
EOF | |
# Install azure workload identity mutating admission webhook | |
helm repo add azure-workload-identity https://azure.github.io/azure-workload-identity/charts | |
helm repo update | |
helm install workload-identity-webhook azure-workload-identity/workload-identity-webhook \ | |
--namespace azure-workload-identity-system \ | |
--create-namespace \ | |
--set azureTenantID="${AZURE_TENANT_ID}" | |
# Create service account with azure.workload.identity/tenant-id annotation | |
cat <<EOF | kubectl apply -f - | |
apiVersion: v1 | |
kind: ServiceAccount | |
metadata: | |
annotations: | |
azure.workload.identity/client-id: ${USER_ASSIGNED_IDENTITY_CLIENT_ID} | |
name: ${SERVICE_ACCOUNT_NAME} | |
namespace: ${SERVICE_ACCOUNT_NAMESPACE} | |
EOF | |
# Create federated credential between managed identity and service account issuer and subject | |
az identity federated-credential create \ | |
--name "kubernetes-federated-credential" \ | |
--identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \ | |
--resource-group "${RESOURCE_GROUP}" \ | |
--issuer "${SERVICE_ACCOUNT_ISSUER}" \ | |
--subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}" | |
# Use service account to access keyvault secret | |
export KEYVAULT_URL="$(az keyvault show -g ${RESOURCE_GROUP} -n ${KEYVAULT_NAME} --query properties.vaultUri -o tsv)" | |
cat <<EOF | kubectl apply -f - | |
apiVersion: v1 | |
kind: Pod | |
metadata: | |
name: quick-start | |
namespace: ${SERVICE_ACCOUNT_NAMESPACE} | |
labels: | |
azure.workload.identity/use: "true" | |
spec: | |
serviceAccountName: ${SERVICE_ACCOUNT_NAME} | |
containers: | |
- image: ghcr.io/azure/azure-workload-identity/msal-go | |
name: oidc | |
env: | |
- name: KEYVAULT_URL | |
value: ${KEYVAULT_URL} | |
- name: SECRET_NAME | |
value: ${KEYVAULT_SECRET_NAME} | |
nodeSelector: | |
kubernetes.io/os: linux | |
EOF | |
kubectl logs quick-start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment