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

Delete old Azure Container environment

  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
    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

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

    az containerapp env identity assign -g $RESOURCE_GROUP -n $ACA_ENVIRONMENT --user-assigned $USER_ID
    
  6. 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
    
  7. 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)
    
  8. 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
    
  9. 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.

  10. 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
    
  11. 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

  1. edit parameter file infra/bicep/main.parameters.json, add new parameter

    "vnetEndpointInternal": {
       "value": true
    }   
    
  2. 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

  1. 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
    
  2. 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
    
  3. 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