Closed cosminstirbu closed 1 year ago
I would recommend creating the Container Environment internal only and then connecting APIM to a different subnet. That will guarantee that your env is locked down without public IPs. https://docs.microsoft.com/en-us/azure/container-apps/vnet-custom-internal?tabs=bash&pivots=azure-portal Something like this: https://techcommunity.microsoft.com/t5/apps-on-azure-blog/connected-microservices-with-azure-container-apps/ba-p/3072158
Your recommendation would work.
In our organization however we have a central API Management instance where different teams plug in their APIs (I agree that it can be argued it's a single point of failure, but that's a different conversation).
The existing API Management instance doesn't use a VNET and at this point, integrating it with one would require coordination with multiple teams (since there's a change it will also involve some downtime).
Ideally we'd like something as simple as the Networking section on the App Service.
Hi @cosminstirbu,
there are three options available when comes network in Container Apps:
According to your information, you want to limit the access to your Container Apps by only allowing access to your API Management and routing the traffic from Azure API Management into Container Apps.
The best option and the only one that I am seeing is to have a shared subnet between API Management and Container App. Since you have multiple teams using API management, why you don't setup your own API Gateway instead of using a shared instance?
Diagram using VNET
Hi @JoaoBrandao
The reason why we use a central API Management gateway is to have a single "landing-page" for all APIs exposed by our organization to the outside world.
This allows us to provide a smoother developer experience in terms of discoverability of our APIs, rather than having multiple instances of API Management and therefore also multiple developer portals.
You can try to use this approach:
But since you have this limitation of VNET, I would suggest checking API Management options but looks like it is mostly impossible to make what you want in terms of network.
I've also been looking for a way to whitelist IP-addresses into container apps. I did find a possible solution:
Deploy the container environment into a VNet with external LB. Then use a Network Security Group on the subnet where the environment lives to lock down incoming traffic. In my case this was a specific IP-cidr, but it looks like this could also be done using service tags (ApiManagement). Combining this with the header solution mentioned above (to lock it down further to your ApiManagement specifically) might work.
I wonder what experts think about this?
Another thing worth mentioning is that in order to use a VNET on API Management you need to be on the Premium tier, which costs $2,795.17 vs $686.71 (Standard tier).
One of the appeals of using container apps is that we don't have to manage all these resources (internal vnets, subnets, gateways) so it would be nice if we could just restrict access to APIM IP. For the moment we went with the secret key in header approach, although it is a security concern since container apps are still exposed to public network traffic.
I second @NullQubit on his concerns. Adding a lot more complexity and moving parts just to restrict source IP access is not ideal and may hinder adoption in favor of raw AKS. I am working on a project as we speak that stays on AKS for this simple reason, adding Application Gateway + internal managed environment is too much unnecessary added complexity for basic IP filtering.
If you could expose a property to filter in traffic at the ingress point, it would be enough for most scenarios.
E.g. -
"ingress": {
"traffic": [
{
"allowedSourceIp": [
"21.19.4.0/24",
"91.4.0.0/16"
]
}
]
}
I'm sure Envoy already supports this so it's just a matter of passing the right config snippet. 401
or 403
HTTP responses are both perfectly acceptable.
Additionally, exposing Azure Portal blade UI for this property under Ingress will significantly raise the production value of the service.
Think of all the gov agencies that are mandated to restrict source IP traffic, on top of authentication. I don't know if this is a thing in US as well, but it's everywhere in Europe.
Thank you all for this thoughtful feedback and discussion. I have taken note on the feature request and we will be working to document the various networking approaches. I've change the name to narrow the scope of this issue for now as we have multiple on a similar topic
This can be done using api 2022-06-01-preview
{
"properties": {
"configuration": {
"ingress": {
"ipSecurityRestrictions": [
{
"ipAddressRange": "21.19.4.0/24",
"action": "Allow"
},
{
"ipAddressRange": "91.4.0.0/16",
"action": "Allow"
}
]
}
}
}
}
That's awesome 😎
Does this work with front door FDID headers and service tags?
It doesn't, xff headers are not trusted either. This is strictly CIDR for the IP address of the client atm.
I created azure container apps using az cli as follows
az containerapp create --resource-group $RESOURCE_GROUP --yaml deploy.yml \
--name $CONTAINER_APPS_NAME
And here is snippet of yaml file.
configuration:
activeRevisionsMode: Multiple
ingress:
allowInsecure: false
ipSecurityRestrictions:
- action: "Allow"
name: "Allow office"
ipAddressRange: "[myip]/32"
external: true
targetPort: 5011
But it doesn't work, I don't know how to force to use API Version 2022-06-01-preview
or later.
I am new to azure and azure cli.
I created azure container apps using az cli as follows
az containerapp create --resource-group $RESOURCE_GROUP --yaml deploy.yml \ --name $CONTAINER_APPS_NAME
And here is snippet of yaml file.
configuration: activeRevisionsMode: Multiple ingress: allowInsecure: false ipSecurityRestrictions: - action: "Allow" name: "Allow office" ipAddressRange: "[myip]/32" external: true targetPort: 5011
But it doesn't work, I don't know how to force to use API Version
2022-06-01-preview
or later. I am new to azure and azure cli.
I think you can force the api version using either bicep or ARM temaplates, with the azure cli it's a bit more complicated since the cli is a wrapper around the azure apis. If you don't really want to use any of the aforementioned options, you can still somehow use the azure cli but it requires a bit more effort. First you have to turn debug logging on using the --debug
flag and copy and the request body and add the additional parameters and then use the az rest
(see here) command to hit the api version you want.
Hope this helps
If I put the IP restriction, like an API Management IP to our container apps it works as expected, except for one thing. A Dapr Service Invoke is blocked from the IP Restriction. I think this shouldn't be the case. And I have no IP range to put in there. I've tested the outbound IP address of the source ACA, but it doesn't work. Any ideas?
@christle - thanks for letting us know. Will notify the team and keep you posted. Do you mind creating a separate issue for this?
Done, #527
Closing as complete
It would be nice if this worked with ipv6 as well. For a use case, we use Cloudflare, and as such we want to limit incoming traffic to the IP ranges provided by CF, which includes ipv6. There are workarounds, but it's unfortunate to have to do so when this feature ALMOST satisfies that need.
Hello,
We're looking at moving away from App Services and using Container Apps.
One feature that we're currently using from App Services is to only allow inbound traffic from the IP address of our API Management instance.
How would we achieve this with Container Apps?
Can it be done on an app by app basis? Or will the rules be applicable at the environment level?
Thank you, Cosmin