Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f51bdee
Add HOME so the script can be run in any folder
petetian Mar 7, 2025
4891990
Merge branch 'Azure-Samples:main' into main
petetian Mar 7, 2025
74c3136
Updated azure-resource.profile and create-azure-resource.sh with new …
petetian Mar 7, 2025
8d42816
Add bash scripts for lab-2
petetian Mar 8, 2025
b406e13
add create.mysql.sh
petetian Mar 9, 2025
6212a30
Remove the dependencies of external parameters
petetian Mar 9, 2025
6aeeeba
new module creation
petetian Mar 9, 2025
c2fe648
create new module
petetian Mar 9, 2025
3249751
Remove unused variable
petetian Mar 10, 2025
29df268
Update azd json with steps in lab2
petetian Mar 10, 2025
fa60784
create docker images for microservices
petetian Mar 10, 2025
7afe183
refactory
petetian Mar 11, 2025
5cf4a91
Refactory
petetian Mar 11, 2025
ae3fac9
Refactor: move azure-resource.profile to ../config sharing with other…
petetian Mar 11, 2025
4f8ab79
Refactor: source the config file created by the previous step. Add ap…
petetian Mar 11, 2025
188d693
Refactor
petetian Mar 11, 2025
94ff0ef
Refactor: use common config file
petetian Mar 11, 2025
27b345a
Write created components to config file
petetian Mar 12, 2025
766ca0a
add new module
petetian Mar 12, 2025
901cf04
update .gitignore
petetian Mar 12, 2025
1dfd416
update .gitignore
petetian Mar 12, 2025
87d939a
export LOCATION
petetian Mar 12, 2025
7e2780b
add lab-3
petetian Mar 13, 2025
d923a1d
Merge remote-tracking branch 'upstream'
petetian Mar 13, 2025
dc6a7ed
create main script as entry point
petetian Mar 13, 2025
058f350
add script for lab 3
petetian Mar 13, 2025
f575923
add lab-3; refactor lab-2
petetian Mar 13, 2025
b210c9f
bug fixing
petetian Mar 13, 2025
fa209e0
bug fixing
petetian Mar 13, 2025
a71b2a3
bug fixing
petetian Mar 13, 2025
678f85a
clean up
petetian Mar 13, 2025
5c65673
clean up
petetian Mar 13, 2025
7366333
create lab-3
petetian Mar 14, 2025
293b48b
bug fixing
petetian Mar 15, 2025
77c96eb
add java modules
petetian Mar 18, 2025
d2b4001
fix bugs in Java modules
petetian Mar 18, 2025
9e43a81
lab-3 fully working version
petetian Mar 18, 2025
77e68cb
add main script for lab-3
petetian Mar 18, 2025
6b03acf
update chat joke url
petetian Mar 18, 2025
55f730d
create scripts in lab-4
petetian Mar 19, 2025
710a35b
more for lab-4
petetian Mar 19, 2025
b891f6f
merge from upstream
petetian Apr 7, 2025
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
39 changes: 39 additions & 0 deletions tools/azd-extension/java-on-ai-azd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"$schema": "https://aka.ms/azd-extension-schema",
"name": "java-on-ai-extension",
"version": "1.1.0",
"description": "Java on AI AZD extension with bash",
"publisher": "Pete Tian",
"commands": [
{
"name": "collecte user information",
"description": "Before performing any additional actions, you’ll need to store your user info as an environment variable that you can use in subsequent steps.",
"entryPoint": "./lab2/collect-user-info.sh"
},
{
"name": "Create an Azure Container Apps environment",
"description": "With your user information stored in environment variables, you’re ready to begin the first step in the deployment: creating an Azure Container Apps instance.",
"entryPoint": "./lab-2/create-aca-env.sh"
},
{
"name": "Create an Azure Database for MySQL instance",
"description": "Create an Azure Database for MySQL - Flexible Server–hosted database.",
"entryPoint": "./lab-2/create-mysql.sh"
},
{
"name": "Set up a configuration repository",
"description": "Set up the application configuration settings that allow your Spring Boot application to connect with the database.",
"entryPoint": "./lab-2/create-container-registry.sh"
},
{
"name": "Create the Java components",
"description": "Configure the config, discovery, and admin applications.",
"entryPoint": "./lab-2/create-java-components.sh"
},
{
"name": "Deploy the component applications to Azure Container Apps",
"description": "Deploy the workload’s component applications to Azure.",
"entryPoint": "./lab-2/deploy-component-apps.sh"
}
]
}
9 changes: 9 additions & 0 deletions tools/azd-extension/lab-2/collect-user-info.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
Copy link
Collaborator

Choose a reason for hiding this comment

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

in some environment like Github codespace, we may fail to get the AAD_USER_ID, we should check if the AAD_USER_ID is valid before continue

# Before performing any additional actions, store user info as an environment variable that
# can be used in subsequent steps.

export USER_NAME=$(az account show --query user.name --output tsv)
echo "Current user:" $USER_NAME

export AAD_USER_ID=$(az ad signed-in-user show --query id --output tsv)
echo "Object ID:" $AAD_USER_ID
89 changes: 89 additions & 0 deletions tools/azd-extension/lab-2/create-aca-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash
# This script creates an Azure Container Apps environment with a dedicated plan and a virtual network.
# It also creates a resource group and a virtual network with a subnet for the Azure Container Apps environment.
# The script uses the Azure CLI to create the resources and requires the user to be logged in to their Azure account.
# The script also requires the user to have the Azure CLI installed and configured on their machine.
# The script uses the `az` command to create the resources and requires the user to have the necessary permissions to create resources in their Azure account.
# The script uses the `openssl` command to generate a random unique ID for the resource group and virtual network names.
# The script uses the `az configure` command to set the default resource group for the Azure CLI commands.

UNIQUEID=$(openssl rand -hex 3)
export APPNAME=petclinic
export RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv)
Copy link
Collaborator

Choose a reason for hiding this comment

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

replace the petclinc to $APPNAME


if [ -z "$RESOURCE_GROUP" ]; then
RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID
Copy link
Collaborator

Choose a reason for hiding this comment

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

we will have user to set the UNIQUEID in profile and import those settings first.
we run "export RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID" at the beginning.

In the current process,

  1. there will be conflict on resource group name
  2. we make sure we can rerun the script

LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus)
echo "Creating resource group [$RESOURCE_GROUP] in region [$LOCATION]..."
az group create -g $RESOURCE_GROUP -l $LOCATION
else
LOCATION=$(az group show --name $RESOURCE_GROUP --query "location" -o tsv)
echo "Provisioning in resource group [$RESOURCE_GROUP]..."
fi

az configure --default group=$RESOURCE_GROUP
Copy link
Collaborator

Choose a reason for hiding this comment

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

we may ask user to input the subscription.

az account set -s SUB

or az configure --default subscription=xxx


#
# Create VNET for Azure Container Apps Environment
#
VIRTUAL_NETWORK_NAME=vnet-$APPNAME-$UNIQUEID
az network vnet create \
--resource-group $RESOURCE_GROUP \
--name $VIRTUAL_NETWORK_NAME \
--location $LOCATION \
--address-prefix 10.1.0.0/16

ACA_SUBNET_CIDR=10.1.0.0/27
az network vnet subnet create \
--resource-group $RESOURCE_GROUP \
--vnet-name $VIRTUAL_NETWORK_NAME \
--address-prefixes $ACA_SUBNET_CIDR \
--name aca-subnet \
--delegations Microsoft.App/environments

SUBNET_ID="$(az network vnet subnet show --resource-group $RESOURCE_GROUP --vnet-name $VIRTUAL_NETWORK_NAME --name aca-subnet --query "id" -o tsv)"
echo "Subnet ID: [$SUBNET_ID]"

#
# Creating the service on an Azure Container Apps Dedicated plan using the workload profiles option.
# This plan gives you more advanced features than the alternative Azure Container Apps Consumption plan type
#
export ACA_ENVIRONMENT=acalab-env-$APPNAME-$UNIQUEID

# If folder ../config does not exist, create it
if [ ! -d "../config" ]; then
mkdir -p ../config
fi
AZURE_CONFIG_FILE="../config/azure-resource.profile"

# winty is to accommodate git bash on Windows
# Otherwise, SUBNET_ID will be appended with local drive path
# NO_PATHCOW is for git bash on Windows
export MSYS_NO_PATHCONV=1

az containerapp env create \
-n $ACA_ENVIRONMENT \
-g $RESOURCE_GROUP \
--location $LOCATION \
--enable-workload-profiles true \
--infrastructure-subnet-resource-id "$SUBNET_ID" \
--logs-destination none

export ACA_ENVIRONMENT_ID=$(az containerapp env show -n $ACA_ENVIRONMENT -g $RESOURCE_GROUP --query id -o tsv)

# Write variables to the azure-resource.profile
{
echo "RESOURCE_GROUP=$RESOURCE_GROUP"
echo "UNIQUEID=$UNIQUEID"
echo "APPNAME=$APPNAME"
echo "ACA_ENVIRONMENT=$ACA_ENVIRONMENT"
echo "ACA_ENVIRONMENT_ID=$ACA_ENVIRONMENT_ID"
} > $AZURE_CONFIG_FILE

# Verify that the azure-resource.profile file is created properly
if [ -f $AZURE_CONFIG_FILE ]; then
echo "azure-resource.profile file created successfully."
else
echo "Error: azure-resource.profile file not created."
exit 1
fi
72 changes: 72 additions & 0 deletions tools/azd-extension/lab-2/create-container-registry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash
#
# Before deploying applications to the Azure Container Apps environment, an Azure Container Registry instance is needed that allows to build and save application container images.
# Allow the Container Apps environment to pull images from this new container registry.
#
# This script creates an Azure Container Registry (ACR) and a user managed identity for the Azure Container Apps environment.
# The script also assigns the user managed identity to the ACR and grants it the necessary permissions to pull images from the registry.
# The script uses the Azure CLI to create the ACR and user managed identity, and to assign the identity to the ACR.
# The script also checks if the ACR and user managed identity already exist, and skips their creation if they do.
# The script also exports the ACR and user managed identity names and IDs as environment variables, and appends them to the Azure configuration file.
# The script also checks if the Azure Container Apps environment name exists, and exits with an error message if it does not.
# The script also disables path conversion for MSYS (Git Bash) to avoid issues with file paths.


AZURE_CONFIG_FILE="../config/azure-resource.profile"
source $AZURE_CONFIG_FILE

APPNAME=petclinic

# Check if a container registry containing the string $APPNAME already exists
MYACR=$(az acr list --resource-group $RESOURCE_GROUP --query "[?contains(name, '$APPNAME')].{Name:name}[0]" -o tsv)

CR_UNIQUEID=$(openssl rand -hex 3)
Copy link
Collaborator

@sonwan2020 sonwan2020 Mar 13, 2025

Choose a reason for hiding this comment

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

I prefer this way: user set the unique id in profile and we use the id for new resources

if [ -n "$MYACR" ]; then
echo "Container registry [$MYACR] already exists. Skipping creation."
else
MYACR=acr$APPNAME$CR_UNIQUEID
echo "Creating new container registry [$MYACR]..."
az acr create \
-n $MYACR \
-g $RESOURCE_GROUP \
--sku Basic \
--admin-enabled true
fi

# Check if ACA environment name containing string "acalab-env" exists
if [ -z "$ACA_ENVIRONMENT" ]; then
echo "Error: ACA environment [$ACA_ENVIRONMENT] not found."
exit 1
fi

# Disable path conversion for MSYS (Git Bash)
export MSYS_NO_PATHCONV=1

# Create the identity that the container apps will use.
export APPS_IDENTITY=uid-petclinic-$CR_UNIQUEID
az identity create --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --output json

APPS_IDENTITY_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --query id --output tsv)
APPS_IDENTITY_SP_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --query principalId --output tsv)

echo "Assign the user identity to your Azure Container Apps environment."
az containerapp env identity assign -g $RESOURCE_GROUP -n $ACA_ENVIRONMENT --user-assigned $APPS_IDENTITY_ID

# Grant the identity with the necessary privileges to pull images from the container registry.
export ACR_ID=$(az acr show -n $MYACR -g $RESOURCE_GROUP --query id -o tsv)
az role assignment create --assignee $APPS_IDENTITY_SP_ID --scope $ACR_ID --role acrpull

# Export the variables
export MYACR
export APPS_IDENTITY
export APPS_IDENTITY_ID
export APPS_IDENTITY_SP_ID

# Append the variables to the AZURE_CONFIG_FILE
{
echo "MYACR=$MYACR"
echo "APPS_IDENTITY=$APPS_IDENTITY"
echo "APPS_IDENTITY_ID=$APPS_IDENTITY_ID"
echo "APPS_IDENTITY_SP_ID=$APPS_IDENTITY_SP_ID"
echo "ACR_ID=$ACR_ID"
} >> $AZURE_CONFIG_FILE
63 changes: 63 additions & 0 deletions tools/azd-extension/lab-2/create-java-components.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash
#
# Configure the config, discovery, and admin applications. These are available as built-in components of Azure Container Apps.

AZURE_CONFIG_FILE="../config/azure-resource.profile"
source $AZURE_CONFIG_FILE

# Check if ACA environment name exists
if [ -z "$ACA_ENVIRONMENT" ]; then
echo "Error: ACA environment not found."
exit 1
fi

JAVA_CONFIG_COMP_NAME=configserver
az containerapp env java-component config-server-for-spring create \
--environment $ACA_ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--name $JAVA_CONFIG_COMP_NAME \
--set-configuration spring.cloud.config.server.git.uri=$GIT_URI spring.cloud.config.server.git.search-paths=$SEARCH_PATH spring.cloud.config.server.git.default-label=$LABEL

# Check the Spring Cloud Config Server Java component to confirm that it was successfully created.
CONFIG_SERVER_EXISTS=$(az containerapp env java-component config-server-for-spring show \
--environment $ACA_ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--name $JAVA_CONFIG_COMP_NAME --query "name" -o tsv)

if [ -z "$CONFIG_SERVER_EXISTS" ]; then
echo "Error: Config server was not successfully created."
exit 1
fi

# Create the Spring Cloud Eureka Server Java component. This will create a standard Eureka endpoint within
# the Container Apps environment. The Spring Petclinic workload will use this for discovery services.
JAVA_EUREKA_COMP_NAME=eureka
az containerapp env java-component eureka-server-for-spring create \
--environment $ACA_ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--name $JAVA_EUREKA_COMP_NAME \
--set-configuration eureka.server.response-cache-update-interval-ms=10000

# Create a new Spring Boot Admin application and bind it to the Eureka Server
JAVA_SBA_COMP_NAME=springbootadmin
az containerapp env java-component admin-for-spring create \
--environment $ACA_ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--name $JAVA_SBA_COMP_NAME \
--bind $JAVA_EUREKA_COMP_NAME \
--min-replicas 1 \
--max-replicas 1

# Append the JAVA_EUREKA_COMP_NAME and JAVA_SBA_COMP_NAME to the AZURE_CONFIG_FILE
{
echo "JAVA_EUREKA_COMP_NAME=$JAVA_EUREKA_COMP_NAME"
echo "JAVA_SBA_COMP_NAME=$JAVA_SBA_COMP_NAME"
} >> $AZURE_CONFIG_FILE

# Verify that the variables are appended to the azure-resource.profile file
if grep -q "JAVA_EUREKA_COMP_NAME" $AZURE_CONFIG_FILE && grep -q "JAVA_SBA_COMP_NAME" $AZURE_CONFIG_FILE; then
echo "Variables appended to azure-resource.profile file successfully."
else
echo "Error: Variables JAVA_EUREKA_COMP_NAME JAVA_SBA_COMP_NAME not appended to azure-resource.profile file."
exit 1
fi
58 changes: 58 additions & 0 deletions tools/azd-extension/lab-2/create-mysql.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

AZURE_CONFIG_FILE="../config/azure-resource.profile"
source $AZURE_CONFIG_FILE

APPLICATION_CONFIG_FILE="../config/application-mysql.yml"

# This script creates an Azure MySQL server and an Azure Container Registry (ACR) in a specified resource group.
MYSQL_SERVER_NAME=mysql-$APPNAME-$UNIQUEID
MYSQL_ADMIN_USERNAME=sqladmin
MYSQL_ADMIN_PASSWORD=$(openssl rand -hex 12)
DATABASE_NAME=petclinic

az mysql flexible-server create \
--admin-user "$MYSQL_ADMIN_USERNAME" \
--admin-password "$MYSQL_ADMIN_PASSWORD" \
--name "$MYSQL_SERVER_NAME" \
--resource-group "$RESOURCE_GROUP" \
--public-access none \
--yes
az mysql flexible-server db create \
--server-name $MYSQL_SERVER_NAME \
--resource-group $RESOURCE_GROUP \
-d $DATABASE_NAME

#
# Allow public access to the MySQL server
#
az mysql flexible-server firewall-rule create \
--rule-name allAzureIPs \
--name $MYSQL_SERVER_NAME \
--resource-group $RESOURCE_GROUP \
--start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0

# Set up a configuration repository
# set up the application configuration settings that allow Spring Boot applications to connect with the database.
echo "
spring:
datasource:
url: jdbc:mysql://${MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/petclinic?useSSL=true
username: ${MYSQL_ADMIN_USERNAME}
password: ${MYSQL_ADMIN_PASSWORD}
sql:
init:
schema-locations: classpath*:db/mysql/schema.sql
data-locations: classpath*:db/mysql/data.sql
mode: ALWAYS
" > $APPLICATION_CONFIG_FILE

export GIT_URI="https://github.com/Azure-Samples/java-on-aca.git"
export SEARCH_PATH="config"
export LABEL=main

{
echo "GIT_URI=https://github.com/Azure-Samples/java-on-aca.git"
echo "SEARCH_PATH=config"
echo "LABEL=main"
} >> $AZURE_CONFIG_FILE
55 changes: 55 additions & 0 deletions tools/azd-extension/lab-2/deploy-component-apps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

AZURE_CONFIG_FILE="../config/azure-resource.profile"
source $AZURE_CONFIG_FILE

# Get the application code from public upstream repo, and then build the applications.
cd ../../../spring-petclinic-microservices
git submodule update --init
mvn clean package -DskipTests

# Build the Docker image using the Dockerfile
DOCKERFILE="../tools/Dockerfile"
if [ ! -f $DOCKERFILE ]; then
echo "$DOCKERFILE not found "
exit 1
fi

# if ACA environment does not exist, exit
if [ -z "$ACA_ENVIRONMENT" ]; then
echo "Error: ACA environment [$ACA_ENVIRONMENT] not found."
exit 1
fi

APP_NAME="api-gateway"
cp -f ../tools/Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile

# Disable path conversion for MSYS (Git Bash)
export MSYS_NO_PATHCONV=1

echo "az containerapp create \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--environment $ACA_ENVIRONMENT \
--source ./spring-petclinic-$APP_NAME \
--registry-server $MYACR.azurecr.io \
--registry-identity $APPS_IDENTITY_ID \
--ingress external \
--target-port 8080 \
--min-replicas 1 \
--bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \
--runtime java"

az containerapp create \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--environment $ACA_ENVIRONMENT \
--source ./spring-petclinic-$APP_NAME \
--registry-server $MYACR.azurecr.io \
--registry-identity $APPS_IDENTITY_ID \
--ingress external \
--target-port 8080 \
--min-replicas 1 \
--bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \
--runtime java

Loading