Redeploy your Azure Container Apps environment with internal networking
For making use of internal networking and getting a private inbound IP address for your Azure Container Apps environment, you will need to recreate it to use internal networking. You can use the following guidance to perform this task:
Step by step guidance
Delete old Azure Container environment
-
Delete your existing container apps and Azure Container Apps environment as we will be recreating these resources. You will also need to delete the builder service of your Azure Container Apps environment.
az containerapp delete -g $RESOURCE_GROUP -n api-gateway -y az containerapp delete -g $RESOURCE_GROUP -n admin-server -y az containerapp delete -g $RESOURCE_GROUP -n vets-service -y az containerapp delete -g $RESOURCE_GROUP -n visits-service -y az containerapp delete -g $RESOURCE_GROUP -n customers-service -y az containerapp delete -g $RESOURCE_GROUP -n chat-agent -y builder=$(az resource list --namespace Microsoft.App --resource-type builders --resource-group $RESOURCE_GROUP --query "[].id" -o tsv) az rest --method delete --url $builder?api-version=2023-08-01-preview az containerapp env delete -n $ACA_ENVIRONMENT -g $RESOURCE_GROUP -y
Create new internal Azure Container Apps environment
- If you have an existing lab environment created by the step by step operations, please re-create with internal ACA flag enabled follow the guide Rebuild with manual steps.
- If you have an existing lab environment generated by automation steps in Lab 6, please follow the guide Rebuild with azd automation.
Rebuild with manual steps
-
Create a new Azure Container Apps environment into the container apps subnet and make it internal-only.
ACA_ENVIRONMENT=acalab-env-$APPNAME-$UNIQUEID az containerapp env create \ -n $ACA_ENVIRONMENT \ -g $RESOURCE_GROUP \ --location $LOCATION \ --internal-only true \ --enable-workload-profiles true \ --infrastructure-subnet-resource-id $SUBNET_ID \ --logs-destination log-analytics \ --logs-workspace-id $WORKSPACECID \ --logs-workspace-key $WORKSPACEKEY
-
Once the creation is done, recreate the Spring Cloud Config Server Java component.
az containerapp env java-component config-server-for-spring create \ --environment $ACA_ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --name $JAVA_CONFIG_COMP_NAME \ --configuration spring.cloud.config.server.git.uri=$URI spring.cloud.config.server.git.username=$USERNAME spring.cloud.config.server.git.password=$PASSWORD spring.cloud.config.server.git.default-label=main
-
You can double check whether the Spring Cloud Config Server Java component got created properly.
az containerapp env java-component config-server-for-spring show \ --environment $ACA_ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --name $JAVA_CONFIG_COMP_NAME
-
Now yo can recreate the Spring Eureka Server Java component:
az containerapp env java-component eureka-server-for-spring create \ --environment $ACA_ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --name $JAVA_EUREKA_COMP_NAME
-
Assign user identity to container apps environment
az containerapp env identity assign -g $RESOURCE_GROUP -n $ACA_ENVIRONMENT --user-assigned $USER_ID
-
Recreate and rebuild all of the containers, using the docker file and push them to your Azure Container Registry. This will create the apps in your Azure Container Apps environment, build their images and pull each image to each of the apps. These images will include the Application Insights jar file for application monitoring. Run the commands from your staging-acr folder.
cd /workspaces/java-microservices-aca-lab/src/staging-acr export APP_NAME="api-gateway" cp ../spring-petclinic-$APP_NAME/target/spring-petclinic-$APP_NAME-$VERSION.jar spring-petclinic-$APP_NAME-$VERSION.jar sed -i "s|my-service|$APP_NAME|g" Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --source . \ --env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "api-gateway"}}' InstrumentationKey=$AI_CONNECTIONSTRING \ --ingress external \ --target-port 8080 \ --environment $ACA_ENVIRONMENT \ --user-assigned $USER_ID \ --min-replicas 1 \ --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ --runtime java \ --registry-server $MYACR.azurecr.io \ --registry-identity $USER_ID sed -i "s|$APP_NAME|my-service|g" Dockerfile rm spring-petclinic-$APP_NAME-$VERSION.jar export APP_NAME="customers-service" cp ../spring-petclinic-$APP_NAME/target/spring-petclinic-$APP_NAME-$VERSION.jar spring-petclinic-$APP_NAME-$VERSION.jar sed -i "s|my-service|$APP_NAME|g" Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --source . \ --env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "customers-service"}}' InstrumentationKey=$AI_CONNECTIONSTRING \ --environment $ACA_ENVIRONMENT \ --user-assigned $USER_ID \ --min-replicas 1 \ --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ --runtime java \ --ingress internal \ --target-port 8080 \ --registry-server $MYACR.azurecr.io \ --registry-identity $USER_ID sed -i "s|$APP_NAME|my-service|g" Dockerfile rm spring-petclinic-$APP_NAME-$VERSION.jar export APP_NAME="vets-service" cp ../spring-petclinic-$APP_NAME/target/spring-petclinic-$APP_NAME-$VERSION.jar spring-petclinic-$APP_NAME-$VERSION.jar sed -i "s|my-service|$APP_NAME|g" Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --source . \ --env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "vets-service"}}' InstrumentationKey=$AI_CONNECTIONSTRING \ --environment $ACA_ENVIRONMENT \ --user-assigned $USER_ID \ --min-replicas 1 \ --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ --runtime java \ --ingress internal \ --target-port 8080 \ --registry-server $MYACR.azurecr.io \ --registry-identity $USER_ID sed -i "s|$APP_NAME|my-service|g" Dockerfile rm spring-petclinic-$APP_NAME-$VERSION.jar export APP_NAME="visits-service" cp ../spring-petclinic-$APP_NAME/target/spring-petclinic-$APP_NAME-$VERSION.jar spring-petclinic-$APP_NAME-$VERSION.jar sed -i "s|my-service|$APP_NAME|g" Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --source . \ --env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "visits-service"}}' InstrumentationKey=$AI_CONNECTIONSTRING \ --environment $ACA_ENVIRONMENT \ --user-assigned $USER_ID \ --min-replicas 1 \ --cpu 2 --memory 4Gi \ --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ --runtime java \ --ingress internal \ --target-port 8080 \ --registry-server $MYACR.azurecr.io \ --registry-identity $USER_ID sed -i "s|$APP_NAME|my-service|g" Dockerfile rm spring-petclinic-$APP_NAME-$VERSION.jar export APP_NAME="admin-server" cp ../spring-petclinic-$APP_NAME/target/spring-petclinic-$APP_NAME-$VERSION.jar spring-petclinic-$APP_NAME-$VERSION.jar sed -i "s|my-service|$APP_NAME|g" Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --source . \ --env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "admin-server"}}' InstrumentationKey=$AI_CONNECTIONSTRING \ --ingress external \ --target-port 8080 \ --environment $ACA_ENVIRONMENT \ --min-replicas 1 \ --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ --runtime java \ --registry-server $MYACR.azurecr.io \ --registry-identity $USER_ID sed -i "s|$APP_NAME|my-service|g" Dockerfile rm spring-petclinic-$APP_NAME-$VERSION.jar
-
You will also need to recreate the service connections from each of the
customers-service
,visits-service
andvets-service
services to the database. For this, you need the resource ID of each of the apps:CUSTOMERS_ID=$(az containerapp show \ --resource-group $RESOURCE_GROUP \ --name customers-service \ --query id \ -o tsv) VISITS_ID=$(az containerapp show \ --resource-group $RESOURCE_GROUP \ --name visits-service \ --query id \ -o tsv) VETS_ID=$(az containerapp show \ --resource-group $RESOURCE_GROUP \ --name vets-service \ --query id \ -o tsv)
-
Recreate now the service connection for the
customers-service
.az containerapp connection create mysql-flexible \ --connection mysql_conn \ --source-id $CUSTOMERS_ID \ --target-id $DB_ID \ --client-type SpringBoot \ --user-identity client-id=$CLIENT_ID subs-id=$SUBID mysql-identity-id=$ADMIN_IDENTITY_RESOURCE_ID \ -c customers-service
-
You can test the validity of this new connection with the
validate
command:CUSTOMERS_CONN_ID=$(az containerapp connection list \ --resource-group $RESOURCE_GROUP \ --name customers-service \ --query [].id -o tsv) az containerapp connection validate \ --id $CUSTOMERS_CONN_ID
The output of this command should show that the connection was made successful.
-
In the same way create the service connections for the
vets-service
andvisits-service
:az containerapp connection create mysql-flexible \ --connection mysql_conn \ --source-id $VETS_ID \ --target-id $DB_ID \ --client-type SpringBoot \ --user-identity client-id=$CLIENT_ID subs-id=$SUBID mysql-identity-id=$ADMIN_IDENTITY_RESOURCE_ID \ -c vets-service az containerapp connection create mysql-flexible \ --connection mysql_conn \ --source-id $VISITS_ID \ --target-id $DB_ID \ --client-type SpringBoot \ --user-identity client-id=$CLIENT_ID subs-id=$SUBID mysql-identity-id=$ADMIN_IDENTITY_RESOURCE_ID \ -c visits-service
-
You can test the validity of this new connection with the
validate
command:VETS_CONN_ID=$(az containerapp connection list \ --resource-group $RESOURCE_GROUP \ --name vets-service \ --query [].id -o tsv) az containerapp connection validate \ --id $VETS_CONN_ID VISITS_CONN_ID=$(az containerapp connection list \ --resource-group $RESOURCE_GROUP \ --name visits-service \ --query [].id -o tsv) az containerapp connection validate \ --id $VISITS_CONN_ID
Rebuild with azd automation
-
edit parameter file
infra/bicep/main.parameters.json
, add new parameter"vnetEndpointInternal": { "value": true }
-
Run your environment again
azd env list azd up -e <env-name>
This command will recreate the Container Apps environment with internal endpoint, and reuse the existing resources.
Prepare new resource
-
For linking the Application Gateway in the later modules to your applications, you will do this by DNS name. For this, create a private dns zone, linking to your Azure Container Apps private IP address.
ENV_FQDN=$(az containerapp env show \ --name $ACA_ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --query properties.defaultDomain -o tsv) echo $ENV_FQDN az network private-dns zone create \ --resource-group $RESOURCE_GROUP \ --name $ENV_FQDN
-
Link this private dns zone to your virtual network
az network private-dns link vnet create \ --resource-group $RESOURCE_GROUP \ --name MyDNSLink \ --zone-name $ENV_FQDN \ -v $VIRTUAL_NETWORK_NAME -e true
-
Create a dns record for the private IP address of your Container Apps environment.
staticIP=$(az containerapp env show \ --name $ACA_ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --query properties.staticIp -o tsv) az network private-dns record-set a add-record --resource-group $RESOURCE_GROUP -z $ENV_FQDN --record-set-name "*" --ipv4-address $staticIP az network private-dns record-set a add-record --resource-group $RESOURCE_GROUP -z $ENV_FQDN --record-set-name "@" --ipv4-address $staticIP