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 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 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 a new Azure Container Apps environment into the container apps subnet and make it internal-only.
ACA_ENVIRONMENT=aca-$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
-
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 | tr -d '"') 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 | tr -d '"') 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