Skip to content

Instantly share code, notes, and snippets.

@alexisP
Created May 5, 2023 14:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexisP/88222ce7a6ed6188e726186f4b763e23 to your computer and use it in GitHub Desktop.
Save alexisP/88222ce7a6ed6188e726186f4b763e23 to your computer and use it in GitHub Desktop.
AKS - Spring Boot application with workload identity and passwordless PostgreSQL connection
export RESOURCE_GROUP="spring-boot-demo"
export CLUSTER_NAME="spring-boot-demo"
export LOCATION="westeurope"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export USER_ASSIGNED_IDENTITY_NAME="spring-boot-demo-identity"
export DATABASE_NAME="spring-boot-demo"
export DATABASE_LOCAL_USER="spring"
export DATABASE_PASSWORD="..."
export DATABASE_APPLICATION_USER=myuser@$DATABASE_NAME
export NAMESPACE_NAME="spring-boot-demo"
export SERVICE_ACCOUNT_NAME="spring-boot-demo-identity-sa"
# Create the cluster
az group create --location $LOCATION --name $RESOURCE_GROUP
az aks create -g ${RESOURCE_GROUP} -n ${CLUSTER_NAME} --enable-oidc-issuer --enable-workload-identity
# Update an existing cluster
az aks update -g ${RESOURCE_GROUP} -n ${CLUSTER_NAME} --enable-oidc-issuer --enable-workload-identity
# Get the IODC issuer URL
export AKS_OIDC_ISSUER="$(az aks show -n "${CLUSTER_NAME}" -g "${RESOURCE_GROUP}" --query "oidcIssuerProfile.issuerUrl" -otsv)"
# Create a managed identity and get its client id
az identity create \
--name "${USER_ASSIGNED_IDENTITY_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--location "${LOCATION}" \
--subscription "${SUBSCRIPTION}"
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)"
echo "Creating PostgreSQL Server instance"
az postgres server create \
--resource-group $RESOURCE_GROUP \
--name $DATABASE_NAME \
--location $LOCATION \
--sku-name B_Gen5_1 \
--storage-size 5120 \
--admin-user $DATABASE_LOCAL_USER \
--admin-password $DATABASE_PASSWORD \
-o tsv
echo "-----------------------------------------------------"
echo "Configuring PostgreSQL Server firewall"
az postgres server firewall-rule create \
--resource-group $RESOURCE_GROUP \
--name $DATABASE_NAME-database-allow-local-ip \
--server $DATABASE_NAME \
--start-ip-address 0.0.0.0 \
--end-ip-address 255.255.255.255 \
-o tsv
echo "-----------------------------------------------------"
echo "Configuring PostgreSQL Server database"
az postgres db create \
--resource-group $RESOURCE_GROUP \
--name demo \
--server-name $DATABASE_NAME \
-o tsv
# Put yourself as an AAD admin
echo "-----------------------------------------------------"
echo "Add yourself as an Azure AD Admin"
export DATABASE_AAD_ADMIN_OBJECT_ID=$(az ad signed-in-user show --query "[id]" -o tsv)
export DATABASE_AAD_ADMIN_NAME=$(az ad signed-in-user show --query "[mail]" -o tsv)
az postgres server ad-admin create \
--server-name $DATABASE_NAME \
-g $RESOURCE_GROUP \
--display-name $DATABASE_AAD_ADMIN_NAME \
--object-id $DATABASE_AAD_ADMIN_OBJECT_ID
export PGPASSWORD=$(az account get-access-token --resource-type oss-rdbms --query "[accessToken]" -o tsv)
psql "host=$DATABASE_NAME.postgres.database.azure.com port=5432 dbname=demo user=<YOUR-ALIAS>@$DATABASE_NAME sslmode=require"
# Commands to execute in the psql context (replace <MANAGED_IDENTITY_CLIENT_ID> by the value of $USER_ASSIGNED_CLIENT_ID)
# SET aad_validate_oids_in_tenant = off;
# CREATE ROLE myuser WITH LOGIN PASSWORD '<MANAGED_IDENTITY_CLIENT_ID>' IN ROLE azure_ad_user;
# GRANT ALL PRIVILEGES ON DATABASE demo TO "myuser";
# exit
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
# Create a namespace and the service account
kubectl create namespace "${NAMESPACE_NAME}"
# Create the service account
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
azure.workload.identity/client-id: ${USER_ASSIGNED_CLIENT_ID}
labels:
azure.workload.identity/use: "true"
name: ${SERVICE_ACCOUNT_NAME}
namespace: ${NAMESPACE_NAME}
EOF
export FEDERATED_IDENTITY_CREDENTIAL_NAME="my-fed-identity-cred"
# Create the fererated credential
az identity federated-credential create \
--name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} \
--identity-name ${USER_ASSIGNED_IDENTITY_NAME} \
--resource-group ${RESOURCE_GROUP} \
--issuer ${AKS_OIDC_ISSUER} \
--subject system:serviceaccount:${NAMESPACE_NAME}:${SERVICE_ACCOUNT_NAME}
# Deploy the app
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: spring-boot-demo-workload-identity-passwordless
namespace: ${NAMESPACE_NAME}
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: ${SERVICE_ACCOUNT_NAME}
containers:
- image: aplantin.azurecr.io/spring-boot/spring-boot-demo-workload-identity-passwordless:1.2
name: spring-boot-demo-workload-identity-passwordless
env:
- name: AZ_DATABASE_NAME
value: ${DATABASE_NAME}
- name: AZ_DATABASE_USER
value: ${DATABASE_APPLICATION_USER}
EOF
# Check everything is working in the logs
kubectl logs -f spring-boot-demo-workload-identity-passwordless -n $NAMESPACE_NAME
# Check the app is working
kubectl port-forward spring-boot-demo-workload-identity-passwordless 8080:8080 -n $NAMESPACE_NAME
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment