question

jbx999 avatar image
0 Votes"
jbx999 asked jbx999 answered

How to expose an ACI instance publicly while in a vnet?

I have an ACI that is running a REST API that needs to be exposed publicly, but needs to access resources inside a vnet.

For some reason, unlike normal VMs, if an ACI is inside a vnet, it cannot have a public IP address. If you try to give it a DNS name it fails.

The only option seems to be to use an Application Gateway as described here:
https://docs.microsoft.com/en-us/azure/container-instances/container-instances-application-gateway

But this approach has a fatal flaw, as indicated in the documentation itself: "If the container group is stopped, started, or restarted, the container group's private IP is subject to change. If this happens, you will need to update the application gateway configuration."

The Application Gateway has the option to select a backend pool by resource name, but this is only for normal VMs. The other option is to put in the IP address directly.

An ACI can easily get restarted without knowing. From experience, it happens relatively often that the host kills it and restarts it, possibly taking a different IP.

What is the right approach to expose a service running on an ACI instance on the internet, and at the same time have it access resources behind a vnet? The Application Gateway approach is evidently not the right approach.






azure-container-instancesazure-webapps-vnet
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

jbx999 avatar image
0 Votes"
jbx999 answered

Turns out ACI are a half baked solution and there are no simple ways to expose a container instance while part of a vnet. The only practical solution is to use an Application Gateway, but ACIs resource IDs are not even available for backend pools, so you have to specify the IP address directly. So you need to somehow make sure that the IP address is updated each time the container is restarted, which happens a lot. One alternative one could explore is to use init containers to do this, which obviously makes something which is supposed to be simple, much more complicated and pointless.

Furthermore, after using ACI with an Application Gateway, it turns out that the cost to operate the Application Gateway is much higher than the Container Instance itself! Might as well use a normal VM and do away with ACI and Application Gateway.

Bottom line, do not use ACI for exposing a public service, unless you want to fight with all these issues.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

amon-2590 avatar image
0 Votes"
amon-2590 answered amon-2590 edited

Hi @jbx999

My approach to solve this would be to use init containers.
Any container group can have up to 59 init container that act the same as k8s init containers
Once in the init container, you can pull the updated container instance private ip:

ipAddress=$(az container show --resource-group "MyResourceGroup" --name "MyContainer" -o json --query ipAddress.ip)

Then update the application gateway backend pool ip:

az network application-gateway address-pool update -g MyResourceGroup --gateway-name MyAppGateway -n MyAddressPool --servers $ipAddress

Note: every init container must exit successfully beforeyour application begins, so make sure you have a restart policy for the init containers in case it fails.
Note 2: To give the container instance correct permissions in your Azure portal you can use managed identity and IAM.
Note 3: A container with Azure cli: mcr.microsoft.com/azure-cli

Here is a reference on init containers


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

From where do I get this init container? I need to be able to run this with Azure CLI from bitbucket.

Also, how will my container instance have a got its private IP but not have started my application? If my container starts my application will start.

0 Votes 0 ·

Hi @jbx999

Init containers run as part of your ACI container group and are used to perform environmental tasks before your app starts. You can use them to perform initialization logic for your app, such as setting accounts, running setup scripts, or configuring databases. Read more about them here.

The way it would work is you would add the init container as part of your deploy, it would run before every time your application starts (or restarts) and check that the back-end pool of your application gateway is up to date. Once this is complete, the init container will exit and your application will start.


0 Votes 0 ·