Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,4 @@ obj/
project.lock.json
project.fragment.lock.json
artifacts/
challenge-2/RepairPlanner/
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the RepairPlanner should be included in git since the hack participants might want to commit their changes

7 changes: 6 additions & 1 deletion challenge-0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export RESOURCE_GROUP="rg-tire-factory-hack-${RG_SUFFIX}"
export LOCATION="swedencentral"

# Create resource group
az group create --name $RESOURCE_GROUP --location $LOCATION
az group create --name $RESOURCE_GROUP --location $LOCATION --tags SecurityControl=Ignore SecurityExemption=StorageAccountKeyAccess
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not to have MSFT specific tags in the documentation


# Deploy infrastructure
az deployment group create \
Expand All @@ -223,6 +223,11 @@ az deployment group create \
--parameters location=$LOCATION
```

# If redeployed - purge all soft-deleted Azure Resources
```
./purge-soft-deleted.sh --resource-group $RESOURCE_GROUP
```

⏱️Deployment takes approximately 5-10 minutes.


Expand Down
138 changes: 138 additions & 0 deletions challenge-0/purge-soft-deleted.sh
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see redeployment as an issue during the hacks since the participants typically use only one version of the deployed resources and there is no need to run multiple deployments. Adding this to the instructions can cause confusion.

Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/bin/bash
# Script to purge all soft-deleted Azure resources
# Usage: ./purge-soft-deleted.sh [--resource-group <name>]

set -e

# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--resource-group|-g)
RESOURCE_GROUP="$2"
shift 2
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done

if [ -z "$RESOURCE_GROUP" ]; then
echo "Usage: ./purge-soft-deleted.sh --resource-group <resource-group-name>"
exit 1
fi

echo "=== Purging soft-deleted resources for resource group: $RESOURCE_GROUP ==="

# Get location from resource group
LOCATION=$(az group show --name "$RESOURCE_GROUP" --query location -o tsv 2>/dev/null || echo "")

# 1. Purge soft-deleted Key Vaults
echo ""
echo ">>> Checking for soft-deleted Key Vaults..."
DELETED_VAULTS=$(az keyvault list-deleted --query "[?properties.vaultId && contains(properties.vaultId, '$RESOURCE_GROUP')].name" -o tsv 2>/dev/null || echo "")

if [ -n "$DELETED_VAULTS" ]; then
for vault in $DELETED_VAULTS; do
echo "Purging Key Vault: $vault"
az keyvault purge --name "$vault" --no-wait || echo " Failed to purge $vault"
done
else
echo " No soft-deleted Key Vaults found."
fi

# Also check all deleted vaults in the location
if [ -n "$LOCATION" ]; then
echo ">>> Checking all soft-deleted Key Vaults in location: $LOCATION..."
DELETED_VAULTS_LOC=$(az keyvault list-deleted --query "[?properties.location=='$LOCATION'].name" -o tsv 2>/dev/null || echo "")
if [ -n "$DELETED_VAULTS_LOC" ]; then
for vault in $DELETED_VAULTS_LOC; do
echo "Purging Key Vault: $vault"
az keyvault purge --name "$vault" --location "$LOCATION" --no-wait 2>/dev/null || echo " Failed to purge $vault (may already be purged)"
done
fi
fi

# 2. Purge soft-deleted Cognitive Services accounts (includes Azure OpenAI)
echo ""
echo ">>> Checking for soft-deleted Cognitive Services accounts..."
DELETED_COGNITIVE=$(az cognitiveservices account list-deleted --query "[?contains(id, '$RESOURCE_GROUP')].{name:name, location:location}" -o json 2>/dev/null || echo "[]")

if [ "$DELETED_COGNITIVE" != "[]" ] && [ -n "$DELETED_COGNITIVE" ]; then
echo "$DELETED_COGNITIVE" | jq -r '.[] | "\(.name)|\(.location)"' | while IFS='|' read -r name location; do
if [ -n "$name" ] && [ -n "$location" ]; then
echo "Purging Cognitive Services account: $name in $location"
az cognitiveservices account purge --name "$name" --resource-group "$RESOURCE_GROUP" --location "$location" 2>/dev/null || echo " Failed to purge $name"
fi
done
else
echo " No soft-deleted Cognitive Services accounts found."
fi

# Also list all deleted cognitive services in case RG match didn't work
echo ">>> Checking all soft-deleted Cognitive Services accounts..."
ALL_DELETED_COGNITIVE=$(az cognitiveservices account list-deleted -o json 2>/dev/null || echo "[]")
if [ "$ALL_DELETED_COGNITIVE" != "[]" ] && [ -n "$ALL_DELETED_COGNITIVE" ]; then
echo "Found soft-deleted Cognitive Services:"
echo "$ALL_DELETED_COGNITIVE" | jq -r '.[] | " - \(.name) (location: \(.location))"'

# Try to purge each one
echo "$ALL_DELETED_COGNITIVE" | jq -r '.[] | "\(.name)|\(.location)"' | while IFS='|' read -r name location; do
if [ -n "$name" ] && [ -n "$location" ]; then
echo "Purging Cognitive Services account: $name in $location"
az cognitiveservices account purge --name "$name" --resource-group "$RESOURCE_GROUP" --location "$location" 2>/dev/null || echo " Note: May need different resource group for $name"
fi
done
fi

# 3. Purge soft-deleted API Management instances
echo ""
echo ">>> Checking for soft-deleted API Management instances..."
DELETED_APIM=$(az apim deletedservice list --query "[?contains(serviceId, '$RESOURCE_GROUP')].{name:name, location:location}" -o json 2>/dev/null || echo "[]")

if [ "$DELETED_APIM" != "[]" ] && [ -n "$DELETED_APIM" ]; then
echo "$DELETED_APIM" | jq -r '.[] | "\(.name)|\(.location)"' | while IFS='|' read -r name location; do
if [ -n "$name" ] && [ -n "$location" ]; then
echo "Purging API Management: $name in $location"
az apim deletedservice purge --service-name "$name" --location "$location" 2>/dev/null || echo " Failed to purge $name"
fi
done
else
echo " No soft-deleted API Management instances found."
fi

# Also list all deleted APIM
echo ">>> Checking all soft-deleted API Management instances..."
ALL_DELETED_APIM=$(az apim deletedservice list -o json 2>/dev/null || echo "[]")
if [ "$ALL_DELETED_APIM" != "[]" ] && [ -n "$ALL_DELETED_APIM" ]; then
echo "Found soft-deleted API Management instances:"
echo "$ALL_DELETED_APIM" | jq -r '.[] | " - \(.name) (location: \(.location))"'

echo "$ALL_DELETED_APIM" | jq -r '.[] | "\(.name)|\(.location)"' | while IFS='|' read -r name location; do
if [ -n "$name" ] && [ -n "$location" ]; then
echo "Purging API Management: $name in $location"
az apim deletedservice purge --service-name "$name" --location "$location" --no-wait 2>/dev/null || echo " Failed to purge $name"
fi
done
fi

# 4. Purge soft-deleted App Configuration stores
echo ""
echo ">>> Checking for soft-deleted App Configuration stores..."
DELETED_APPCONFIG=$(az appconfig list-deleted --query "[?contains(configurationStoreId, '$RESOURCE_GROUP')].{name:name, location:location}" -o json 2>/dev/null || echo "[]")

if [ "$DELETED_APPCONFIG" != "[]" ] && [ -n "$DELETED_APPCONFIG" ]; then
echo "$DELETED_APPCONFIG" | jq -r '.[] | "\(.name)|\(.location)"' | while IFS='|' read -r name location; do
if [ -n "$name" ] && [ -n "$location" ]; then
echo "Purging App Configuration: $name in $location"
az appconfig purge --name "$name" --location "$location" --yes 2>/dev/null || echo " Failed to purge $name"
fi
done
else
echo " No soft-deleted App Configuration stores found."
fi

echo ""
echo "=== Soft-delete purge completed ==="
echo "Note: Some purge operations run asynchronously and may take a few minutes to complete."
2 changes: 1 addition & 1 deletion challenge-2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ Try out your agent.

```bash
# Load environment variables
export $(cat ../.env | xargs)
export $(cat ../../.env | xargs)

dotnet run
```
Expand Down