Review Azure Container Instances network exposure

Keep internal workloads within approved virtual networks and required communication paths.

Description

Consider a private IP and virtual network for internal-only Azure Container Instances workloads. Public IPs can serve public applications; actual exposure depends on ports and access controls. None mode assigns no IP address, so absence of a Private setting does not always mean public exposure.

Potential impact

  • Unnecessarily public service ports can expose workloads to external access and attack attempts.
  • Missing private-network routes or DNS can interrupt application communication.

Remediation

  • For internal container groups, configure ip_address_type = "Private" and subnet_ids for a dedicated subnet delegated to ACI. Prepare required NSGs, routes, DNS and supported outbound connectivity.
  • Allow only required ports and sources, and configure application authentication and TLS separately. For public services, define the intended public scope and close unnecessary ports.

Examples

These examples compare only IP type and subnet attachment. Listening ports, DNS and outbound routes are omitted. A private IP does not automatically provide application authentication or control access through other paths.

Before

hcl
resource "azurerm_container_group" "example" {
  name                = "example-container-group"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  os_type             = "Linux"
  ip_address_type     = "Public"

  container {
    name   = "app"
    image  = "nginx:stable"
    cpu    = 1
    memory = 1
  }
}

After

hcl
resource "azurerm_container_group" "example" {
  name                = "example-container-group"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  os_type             = "Linux"
  ip_address_type     = "Private"
  subnet_ids          = [azurerm_subnet.aci.id]

  container {
    name   = "app"
    image  = "nginx:stable"
    cpu    = 1
    memory = 1
  }
}

Explanation:

  • Before: Public IP addressing is selected. Actual service exposure depends on separate port and access settings.
  • After: A private IP and subnet are specified. Prepare delegation and communication paths separately.

References