Skip to content

Commit 6a4c45d

Browse files
committed
added terraform and biceps scripts for sample app
1 parent 871e85e commit 6a4c45d

10 files changed

Lines changed: 843 additions & 1 deletion

File tree

run-samples.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ TERRAFORM_SAMPLES=(
4545
"samples/web-app-cosmosdb-mongodb-api/python/terraform|bash deploy.sh"
4646
"samples/web-app-managed-identity/python/terraform|bash deploy.sh"
4747
"samples/web-app-sql-database/python/terraform|bash deploy.sh"
48+
"samples/aci-blob-storage/python/terraform|bash deploy.sh"
4849
)
4950

5051
# 1b. Define Bicep Samples
@@ -54,6 +55,7 @@ BICEP_SAMPLES=(
5455
"samples/function-app-storage-http/dotnet/bicep|bash deploy.sh"
5556
"samples/web-app-cosmosdb-mongodb-api/python/bicep|bash deploy.sh"
5657
"samples/web-app-managed-identity/python/bicep|bash deploy.sh"
58+
"samples/aci-blob-storage/python/bicep|bash deploy.sh"
5759
)
5860

5961
# Combine script-based, Terraform, and Bicep samples into one array

samples/aci-blob-storage/python/README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ A sample application demonstrating how to deploy a containerized Flask web app u
3434
- [Docker](https://docs.docker.com/get-docker/)
3535
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
3636
- [azlocal](https://pypi.org/project/azlocal/) (`pip install azlocal`)
37+
- [Terraform](https://developer.hashicorp.com/terraform/downloads) (optional, for Terraform deployment)
3738

3839
## Quick Start
3940

@@ -54,6 +55,22 @@ bash scripts/deploy.sh
5455
bash scripts/validate.sh
5556
```
5657

58+
## Alternative Deployments
59+
60+
### Bicep
61+
62+
```bash
63+
cd python
64+
bash bicep/deploy.sh
65+
```
66+
67+
### Terraform
68+
69+
```bash
70+
cd python
71+
bash terraform/deploy.sh
72+
```
73+
5774
## Cleanup
5875

5976
```bash
@@ -90,6 +107,8 @@ The Vacation Planner is a Flask web application with a Bootstrap UI that lets us
90107
| `scripts/deploy.sh` | Deploys Storage, Key Vault, ACR, and ACI with env vars and DNS label |
91108
| `scripts/validate.sh` | Validates all resources and exercises ACI lifecycle (get, list, logs, exec, stop, start, restart) |
92109
| `scripts/cleanup.sh` | Removes all resources created by deploy.sh |
110+
| `bicep/deploy.sh` | Deploys all resources using a Bicep template |
111+
| `terraform/deploy.sh` | Deploys all resources using Terraform |
93112

94113
## ACI Features Demonstrated
95114

@@ -102,6 +121,6 @@ The Vacation Planner is a Flask web application with a Bootstrap UI that lets us
102121
| CPU / memory resources | deploy.sh |
103122
| DNS name label / FQDN | deploy.sh |
104123
| Container get / list | validate.sh |
105-
| Container logs (+ --tail) | validate.sh |
124+
| Container logs | validate.sh |
106125
| Container exec | validate.sh |
107126
| Stop / Start / Restart | validate.sh |
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#!/bin/bash
2+
3+
# Enable verbose debugging
4+
set -x
5+
6+
# Variables
7+
PREFIX='local'
8+
SUFFIX='test'
9+
TEMPLATE="main.bicep"
10+
PARAMETERS="main.bicepparam"
11+
RESOURCE_GROUP_NAME="$PREFIX-aci-rg"
12+
LOCATION="eastus"
13+
VALIDATE_TEMPLATE=1
14+
USE_WHAT_IF=0
15+
SUBSCRIPTION_NAME=$(az account show --query name --output tsv)
16+
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
17+
IMAGE_NAME="vacation-planner"
18+
IMAGE_TAG="v1"
19+
ENVIRONMENT=$(az account show --query environmentName --output tsv)
20+
21+
echo "=================================================="
22+
echo "DEBUG: Starting bicep deployment for aci-blob-storage"
23+
echo "DEBUG: Resource Group: $RESOURCE_GROUP_NAME"
24+
echo "DEBUG: Environment: $ENVIRONMENT"
25+
echo "=================================================="
26+
27+
# Change the current directory to the script's directory
28+
cd "$CURRENT_DIR" || exit
29+
30+
# Choose the appropriate CLI based on the environment
31+
if [[ $ENVIRONMENT == "LocalStack" ]]; then
32+
echo "Using azlocal for LocalStack emulator environment."
33+
AZ="azlocal"
34+
else
35+
echo "Using standard az for AzureCloud environment."
36+
AZ="az"
37+
fi
38+
39+
# Validates if the resource group exists in the subscription, if not creates it
40+
echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]..."
41+
$AZ group show --name $RESOURCE_GROUP_NAME &>/dev/null
42+
43+
if [[ $? != 0 ]]; then
44+
echo "No resource group [$RESOURCE_GROUP_NAME] exists in the subscription [$SUBSCRIPTION_NAME]"
45+
echo "Creating resource group [$RESOURCE_GROUP_NAME] in the subscription [$SUBSCRIPTION_NAME]..."
46+
47+
# Create the resource group
48+
$AZ group create \
49+
--name $RESOURCE_GROUP_NAME \
50+
--location $LOCATION \
51+
--only-show-errors 1>/dev/null
52+
53+
if [[ $? == 0 ]]; then
54+
echo "Resource group [$RESOURCE_GROUP_NAME] successfully created in the subscription [$SUBSCRIPTION_NAME]"
55+
else
56+
echo "Failed to create resource group [$RESOURCE_GROUP_NAME] in the subscription [$SUBSCRIPTION_NAME]"
57+
exit
58+
fi
59+
else
60+
echo "Resource group [$RESOURCE_GROUP_NAME] already exists in the subscription [$SUBSCRIPTION_NAME]"
61+
fi
62+
63+
# =============================================================================
64+
# Build and push the Docker image before Bicep deployment
65+
# (Bicep creates the ACI group referencing the image in ACR)
66+
# =============================================================================
67+
68+
# Create ACR first so we can push the image
69+
ACR_NAME="${PREFIX}aciacr${SUFFIX}"
70+
echo "Creating ACR [$ACR_NAME] for image push..."
71+
$AZ acr create \
72+
--name "$ACR_NAME" \
73+
--resource-group "$RESOURCE_GROUP_NAME" \
74+
--location "$LOCATION" \
75+
--sku Basic \
76+
--admin-enabled true \
77+
--only-show-errors 1>/dev/null
78+
79+
LOGIN_SERVER=$($AZ acr show \
80+
--name "$ACR_NAME" \
81+
--resource-group "$RESOURCE_GROUP_NAME" \
82+
--query "loginServer" \
83+
--output tsv \
84+
--only-show-errors)
85+
86+
ACR_USERNAME=$($AZ acr credential show \
87+
--name "$ACR_NAME" \
88+
--resource-group "$RESOURCE_GROUP_NAME" \
89+
--query "username" \
90+
--output tsv \
91+
--only-show-errors)
92+
93+
ACR_PASSWORD=$($AZ acr credential show \
94+
--name "$ACR_NAME" \
95+
--resource-group "$RESOURCE_GROUP_NAME" \
96+
--query "passwords[0].value" \
97+
--output tsv \
98+
--only-show-errors)
99+
100+
FULL_IMAGE="${LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG}"
101+
102+
echo "Building Docker image [$IMAGE_NAME:$IMAGE_TAG]..."
103+
docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" ../src/
104+
105+
if [[ $? != 0 ]]; then
106+
echo "Failed to build Docker image."
107+
exit 1
108+
fi
109+
110+
docker tag "${IMAGE_NAME}:${IMAGE_TAG}" "$FULL_IMAGE"
111+
112+
echo "Logging in to ACR [$LOGIN_SERVER]..."
113+
echo "$ACR_PASSWORD" | docker login "$LOGIN_SERVER" --username "$ACR_USERNAME" --password-stdin 2>/dev/null
114+
115+
echo "Pushing image [$FULL_IMAGE]..."
116+
docker push "$FULL_IMAGE" 2>/dev/null
117+
118+
if [[ $? != 0 ]]; then
119+
echo "Failed to push image to ACR."
120+
exit 1
121+
fi
122+
echo "Image pushed to ACR successfully."
123+
124+
# =============================================================================
125+
# Validate and deploy the Bicep template
126+
# =============================================================================
127+
128+
# Validates the Bicep template
129+
if [[ $VALIDATE_TEMPLATE == 1 ]]; then
130+
if [[ $USE_WHAT_IF == 1 ]]; then
131+
# Execute a deployment What-If operation at resource group scope.
132+
echo "Previewing changes deployed by Bicep template [$TEMPLATE]..."
133+
$AZ deployment group what-if \
134+
--resource-group $RESOURCE_GROUP_NAME \
135+
--template-file $TEMPLATE \
136+
--parameters $PARAMETERS \
137+
--parameters location=$LOCATION \
138+
prefix=$PREFIX \
139+
suffix=$SUFFIX \
140+
--only-show-errors
141+
142+
if [[ $? == 0 ]]; then
143+
echo "Bicep template [$TEMPLATE] validation succeeded"
144+
else
145+
echo "Failed to validate Bicep template [$TEMPLATE]"
146+
exit
147+
fi
148+
else
149+
# Validate the Bicep template
150+
echo "Validating Bicep template [$TEMPLATE]..."
151+
output=$($AZ deployment group validate \
152+
--resource-group $RESOURCE_GROUP_NAME \
153+
--template-file $TEMPLATE \
154+
--parameters $PARAMETERS \
155+
--parameters location=$LOCATION \
156+
prefix=$PREFIX \
157+
suffix=$SUFFIX \
158+
--only-show-errors)
159+
160+
if [[ $? == 0 ]]; then
161+
echo "Bicep template [$TEMPLATE] validation succeeded"
162+
else
163+
echo "Failed to validate Bicep template [$TEMPLATE]"
164+
echo "$output"
165+
exit
166+
fi
167+
fi
168+
fi
169+
170+
# Deploy the Bicep template
171+
echo "Deploying Bicep template [$TEMPLATE]..."
172+
if DEPLOYMENT_OUTPUTS=$($AZ deployment group create \
173+
--resource-group $RESOURCE_GROUP_NAME \
174+
--only-show-errors \
175+
--template-file $TEMPLATE \
176+
--parameters $PARAMETERS \
177+
--parameters location=$LOCATION \
178+
prefix=$PREFIX \
179+
suffix=$SUFFIX \
180+
--query 'properties.outputs' -o json); then
181+
echo "Bicep template [$TEMPLATE] deployed successfully. Outputs:"
182+
echo "$DEPLOYMENT_OUTPUTS" | jq .
183+
STORAGE_ACCOUNT_NAME=$(echo "$DEPLOYMENT_OUTPUTS" | jq -r '.storageAccountName.value')
184+
KEY_VAULT_NAME=$(echo "$DEPLOYMENT_OUTPUTS" | jq -r '.keyVaultName.value')
185+
ACR_LOGIN_SERVER=$(echo "$DEPLOYMENT_OUTPUTS" | jq -r '.acrLoginServer.value')
186+
ACI_GROUP_NAME=$(echo "$DEPLOYMENT_OUTPUTS" | jq -r '.aciGroupName.value')
187+
FQDN=$(echo "$DEPLOYMENT_OUTPUTS" | jq -r '.fqdn.value')
188+
echo "Deployment details:"
189+
echo "- storageAccountName: $STORAGE_ACCOUNT_NAME"
190+
echo "- keyVaultName: $KEY_VAULT_NAME"
191+
echo "- acrLoginServer: $ACR_LOGIN_SERVER"
192+
echo "- aciGroupName: $ACI_GROUP_NAME"
193+
echo "- fqdn: $FQDN"
194+
else
195+
echo "Failed to deploy Bicep template [$TEMPLATE]"
196+
exit 1
197+
fi

0 commit comments

Comments
 (0)