Skip to main content Link Menu Expand (external link) Document Search Copy Copied

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

  1. 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
    
  2. 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
           
    
  3. 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 
    
  4. 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
    
  5. 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
    
  6. Assign user identity to container apps environment

    az containerapp env identity assign -g $RESOURCE_GROUP -n $ACA_ENVIRONMENT --user-assigned $USER_ID
    
  7. 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
    
  8. You will also need to recreate the service connections from each of the customers-service, visits-service and vets-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)
    
  9. 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
    
  10. 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.

  11. In the same way create the service connections for the vets-service and visits-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
    
  12. 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
    
  13. 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
    
  14. 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
    
  15. 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