Skip to content

Commit e2ae298

Browse files
committed
implemented azure container instance sample app
1 parent 746a9b4 commit e2ae298

58 files changed

Lines changed: 477 additions & 155 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

run-samples.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ SAMPLES=(
3535
"samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
3636
"samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
3737
"samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh"
38-
"samples/aci-vacation-planner/python|bash scripts/deploy.sh|bash scripts/validate.sh"
38+
"samples/aci-blob-storage/python|bash scripts/deploy.sh|bash scripts/validate.sh"
3939
)
4040

4141
# 1a. Define Terraform Samples

samples/aci-vacation-planner/python/README.md renamed to samples/aci-blob-storage/python/README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,30 @@ azlocal start_interception
5050
cd python
5151
bash scripts/deploy.sh
5252

53-
# Validate the deployment
53+
# Validate the deployment (includes stop/start/restart lifecycle tests)
5454
bash scripts/validate.sh
5555
```
5656

57+
## Advanced Deployment
58+
59+
The advanced script demonstrates additional ACI features on top of the basic deployment:
60+
61+
- **Init containers** — Run a health-check container before the app starts
62+
- **emptyDir volumes** — Shared temporary storage between init and app containers
63+
- **Secret volumes** — Config files decoded from base64 and mounted read-only
64+
- **Secure environment variables** — Connection string hidden from API responses
65+
- **DNS name label / FQDN** — Generates a fully qualified domain name
66+
67+
```bash
68+
# Run the basic deployment first, then:
69+
bash scripts/deploy-advanced.sh
70+
```
71+
5772
## Cleanup
5873

5974
```bash
60-
azlocal group delete --name local-aci-rg --yes
75+
# Removes all resources created by deploy.sh and deploy-advanced.sh
76+
bash scripts/cleanup.sh
6177
```
6278

6379
## Application
@@ -81,3 +97,31 @@ The Vacation Planner is a Flask web application with a Bootstrap UI that lets us
8197
| `AZURE_STORAGE_CONNECTION_STRING` | Blob Storage connection string (from Key Vault) |
8298
| `BLOB_CONTAINER_NAME` | Name of the blob container for activities |
8399
| `LOGIN_NAME` | Username for the activity list (default: "paolo") |
100+
101+
## Scripts
102+
103+
| Script | Description |
104+
|--------|-------------|
105+
| `scripts/deploy.sh` | Basic deployment: Storage, Key Vault, ACR, ACI with env vars and DNS label |
106+
| `scripts/validate.sh` | Validates all resources and exercises ACI lifecycle (get, list, logs, exec, stop, start, restart) |
107+
| `scripts/deploy-advanced.sh` | Advanced deployment: init containers, emptyDir/secret volumes, secure env vars |
108+
| `scripts/cleanup.sh` | Removes all resources created by deploy.sh and deploy-advanced.sh |
109+
110+
## ACI Features Demonstrated
111+
112+
| Feature | Basic Deploy | Advanced Deploy |
113+
|---------|:---:|:---:|
114+
| Container group create | x | x |
115+
| Public IP + ports | x | x |
116+
| Environment variables | x | x |
117+
| Registry credentials (ACR) | x | x |
118+
| CPU / memory resources | x | x |
119+
| DNS name label / FQDN | x | x |
120+
| Secure environment variables | | x |
121+
| Init containers | | x |
122+
| emptyDir volumes | | x |
123+
| Secret volumes | | x |
124+
| Stop / Start / Restart | validate.sh | |
125+
| List container groups | validate.sh | |
126+
| Logs with --tail | validate.sh | |
127+
| Container exec | validate.sh | |
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/bin/bash
2+
3+
# =============================================================================
4+
# ACI Vacation Planner - Cleanup Script
5+
#
6+
# Removes all Azure resources created by deploy.sh and deploy-advanced.sh.
7+
# Deletes resources in reverse order to avoid dependency issues.
8+
# =============================================================================
9+
10+
# Variables (must match deploy.sh)
11+
PREFIX='local'
12+
RESOURCE_GROUP_NAME="${PREFIX}-aci-rg"
13+
ACI_GROUP_NAME="${PREFIX}-aci-planner"
14+
ACI_GROUP_ADVANCED="${PREFIX}-aci-planner-advanced"
15+
KEY_VAULT_NAME="${PREFIX}acikv"
16+
ACR_NAME="${PREFIX}aciacr"
17+
STORAGE_ACCOUNT_NAME="${PREFIX}acistorage"
18+
ENVIRONMENT=$(az account show --query environmentName --output tsv)
19+
20+
# Choose the appropriate CLI based on the environment
21+
if [[ $ENVIRONMENT == "LocalStack" ]]; then
22+
AZ="azlocal"
23+
else
24+
AZ="az"
25+
fi
26+
27+
echo "============================================================"
28+
echo "Cleaning up ACI Vacation Planner Resources"
29+
echo "============================================================"
30+
echo ""
31+
32+
# 1. Delete ACI container groups (basic + advanced)
33+
echo "[1/5] Deleting ACI container groups..."
34+
$AZ container delete \
35+
--name "$ACI_GROUP_NAME" \
36+
--resource-group "$RESOURCE_GROUP_NAME" \
37+
--yes \
38+
--only-show-errors 2>/dev/null && echo " Deleted: $ACI_GROUP_NAME" || echo " Skipped: $ACI_GROUP_NAME (not found)"
39+
40+
$AZ container delete \
41+
--name "$ACI_GROUP_ADVANCED" \
42+
--resource-group "$RESOURCE_GROUP_NAME" \
43+
--yes \
44+
--only-show-errors 2>/dev/null && echo " Deleted: $ACI_GROUP_ADVANCED" || echo " Skipped: $ACI_GROUP_ADVANCED (not found)"
45+
echo ""
46+
47+
# 2. Delete ACR
48+
echo "[2/5] Deleting ACR [$ACR_NAME]..."
49+
$AZ acr delete \
50+
--name "$ACR_NAME" \
51+
--resource-group "$RESOURCE_GROUP_NAME" \
52+
--yes \
53+
--only-show-errors 2>/dev/null && echo " Deleted: $ACR_NAME" || echo " Skipped: $ACR_NAME (not found)"
54+
echo ""
55+
56+
# 3. Delete Key Vault (delete + purge to release the vault name)
57+
echo "[3/5] Deleting Key Vault [$KEY_VAULT_NAME]..."
58+
$AZ keyvault delete \
59+
--name "$KEY_VAULT_NAME" \
60+
--resource-group "$RESOURCE_GROUP_NAME" \
61+
--only-show-errors 2>/dev/null && echo " Deleted: $KEY_VAULT_NAME" || echo " Skipped: $KEY_VAULT_NAME (not found)"
62+
$AZ keyvault purge \
63+
--name "$KEY_VAULT_NAME" \
64+
--only-show-errors 2>/dev/null && echo " Purged: $KEY_VAULT_NAME" || true
65+
echo ""
66+
67+
# 4. Delete Storage Account
68+
echo "[4/5] Deleting Storage Account [$STORAGE_ACCOUNT_NAME]..."
69+
$AZ storage account delete \
70+
--name "$STORAGE_ACCOUNT_NAME" \
71+
--resource-group "$RESOURCE_GROUP_NAME" \
72+
--yes \
73+
--only-show-errors 2>/dev/null && echo " Deleted: $STORAGE_ACCOUNT_NAME" || echo " Skipped: $STORAGE_ACCOUNT_NAME (not found)"
74+
echo ""
75+
76+
# 5. Delete Resource Group
77+
echo "[5/5] Deleting Resource Group [$RESOURCE_GROUP_NAME]..."
78+
$AZ group delete \
79+
--name "$RESOURCE_GROUP_NAME" \
80+
--yes \
81+
--only-show-errors 2>/dev/null && echo " Deleted: $RESOURCE_GROUP_NAME" || echo " Skipped: $RESOURCE_GROUP_NAME (not found)"
82+
echo ""
83+
84+
echo "============================================================"
85+
echo "Cleanup complete."
86+
echo "============================================================"

samples/aci-vacation-planner/python/scripts/deploy.sh renamed to samples/aci-blob-storage/python/scripts/deploy.sh

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
2929
cd "$CURRENT_DIR" || exit
3030

3131
# Choose the appropriate CLI based on the environment
32-
# When start_interception is active, 'az' already routes to LocalStack,
33-
# so we use 'az' directly to avoid double-wrapping.
3432
if [[ $ENVIRONMENT == "LocalStack" ]]; then
35-
echo "Using az with LocalStack interception active."
36-
AZ="az"
33+
echo "Using azlocal for LocalStack emulator environment."
34+
AZ="azlocal"
3735
else
3836
echo "Using standard az for AzureCloud environment."
3937
AZ="az"
@@ -120,17 +118,21 @@ else
120118
exit 1
121119
fi
122120

123-
# For LocalStack, convert https:// to http:// to avoid SSL certificate issues
124-
# with self-signed certs on data-plane endpoints
125-
if [[ $ENVIRONMENT == "LocalStack" ]]; then
126-
BLOB_ENDPOINT="${BLOB_ENDPOINT/https:\/\//http:\/\/}"
127-
echo "Converted blob endpoint to HTTP: $BLOB_ENDPOINT"
128-
fi
129-
130-
# Build connection string
121+
# Build the connection string using the original blob endpoint (resolvable from the host).
131122
STORAGE_CONN_STRING="DefaultEndpointsProtocol=http;AccountName=${STORAGE_ACCOUNT_NAME};AccountKey=${STORAGE_ACCOUNT_KEY};BlobEndpoint=${BLOB_ENDPOINT}"
132123
echo "Connection string built successfully."
133124

125+
# For LocalStack, the ACI emulator configures containers with LocalStack's DNS
126+
# server, so *.localhost.localstack.cloud resolves to the LocalStack container.
127+
# We only need to downgrade HTTPS to HTTP (containers don't have the LS TLS cert).
128+
if [[ $ENVIRONMENT == "LocalStack" ]]; then
129+
CONTAINER_BLOB_ENDPOINT="${BLOB_ENDPOINT/https:\/\//http:\/\/}"
130+
CONTAINER_CONN_STRING="DefaultEndpointsProtocol=http;AccountName=${STORAGE_ACCOUNT_NAME};AccountKey=${STORAGE_ACCOUNT_KEY};BlobEndpoint=${CONTAINER_BLOB_ENDPOINT}"
131+
echo "Container blob endpoint: $CONTAINER_BLOB_ENDPOINT"
132+
else
133+
CONTAINER_CONN_STRING="$STORAGE_CONN_STRING"
134+
fi
135+
134136
# =============================================================================
135137
# Step 5: Create Blob Container
136138
# =============================================================================
@@ -159,17 +161,20 @@ echo ""
159161
echo "============================================================"
160162
echo "Step 6: Creating Key Vault [$KEY_VAULT_NAME]..."
161163
echo "============================================================"
162-
$AZ keyvault create \
164+
KV_OUTPUT=$($AZ keyvault create \
163165
--name "$KEY_VAULT_NAME" \
164166
--resource-group "$RESOURCE_GROUP_NAME" \
165167
--location "$LOCATION" \
166168
--enable-rbac-authorization true \
167-
--only-show-errors 1>/dev/null
169+
--only-show-errors 2>&1)
168170

169171
if [ $? -eq 0 ]; then
170172
echo "Key Vault [$KEY_VAULT_NAME] created successfully."
173+
elif echo "$KV_OUTPUT" | grep -qi "already exists"; then
174+
echo "Key Vault [$KEY_VAULT_NAME] already exists, reusing."
171175
else
172176
echo "Failed to create Key Vault [$KEY_VAULT_NAME]."
177+
echo " $KV_OUTPUT"
173178
exit 1
174179
fi
175180

@@ -180,10 +185,11 @@ echo ""
180185
echo "============================================================"
181186
echo "Step 7: Storing storage connection string in Key Vault..."
182187
echo "============================================================"
188+
# Store the container-friendly connection string so ACI can reach LocalStack
183189
$AZ keyvault secret set \
184190
--vault-name "$KEY_VAULT_NAME" \
185191
--name "storage-conn" \
186-
--value "$STORAGE_CONN_STRING" \
192+
--value "$CONTAINER_CONN_STRING" \
187193
--only-show-errors 1>/dev/null
188194

189195
if [ $? -eq 0 ]; then
@@ -339,6 +345,7 @@ if [ "$USE_ACR_IMAGE" = true ]; then
339345
BLOB_CONTAINER_NAME="$BLOB_CONTAINER_NAME" \
340346
LOGIN_NAME="$LOGIN_NAME" \
341347
--ip-address Public \
348+
--dns-name-label "$ACI_GROUP_NAME" \
342349
--ports 80 \
343350
--cpu 1 --memory 1 \
344351
--os-type Linux \
@@ -355,6 +362,7 @@ else
355362
BLOB_CONTAINER_NAME="$BLOB_CONTAINER_NAME" \
356363
LOGIN_NAME="$LOGIN_NAME" \
357364
--ip-address Public \
365+
--dns-name-label "$ACI_GROUP_NAME" \
358366
--ports 80 \
359367
--cpu 1 --memory 1 \
360368
--os-type Linux \
@@ -384,6 +392,7 @@ echo "Key Vault: $KEY_VAULT_NAME"
384392
echo "ACR: $ACR_NAME ($LOGIN_SERVER)"
385393
echo "ACI Container: $ACI_GROUP_NAME"
386394
echo "Image: $FULL_IMAGE"
395+
echo "FQDN: ${ACI_GROUP_NAME}.${LOCATION}.azurecontainer.io"
387396
echo ""
388397
echo "Run 'bash scripts/validate.sh' to verify the deployment."
389398
echo "============================================================"

0 commit comments

Comments
 (0)