skip to Main Content

I have an Azure container group that is part of a virtual network. So it will have a private IP by default. But that one container group should also be reachable via a public IP. I cannot for the life of me figure out how to do this.

Can I just create a azurerm_public_ip and somehow associate this with the container group? Or will I need a NAT rule or something?

Some example terraform code would be appreciated.

I tried looking at a load balancer and application gateways. But I have to be honest, my knowledge in networking is still somewhat limited. I would appreciate any explenation on where my thinking is completely wrong.

2

Answers


  1. I tried to provision an Azure container group on a vnet that is also reachable via a public IP using Terraform and I was able to provision the requirement successfully.

    To expose a container group in an Azure Virtual Network to the public internet, let’s focus on a solution that fits within that framework.

    One common approach is to use an Azure Load Balancer. The load balancer can have a public IP address associated with it, and it can forward traffic to your container group’s private IP address within the virtual network. This way, your container group remains secure within the virtual network, but it’s also accessible from the internet through the load balancer.

    Tried a demo configuration that matches with requirements you are looking for.

    My Terraform configuration:

    provider "azurerm" {
        features {}
    }
    
    resource "azurerm_resource_group" "example" {
      name     = "demo-vksb"
      location = "West US"
    }
    
    resource "azurerm_virtual_network" "example" {
      name                = "vksb-network"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    }
    
    resource "azurerm_subnet" "example" {
      name                 = "internal"
      resource_group_name  = azurerm_resource_group.example.name
      virtual_network_name = azurerm_virtual_network.example.name
      address_prefixes     = ["10.0.2.0/24"]
    
      delegation {
        name = "aciDelegation"
    
        service_delegation {
          name    = "Microsoft.ContainerInstance/containerGroups"
          actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"]
        }
      }
    }
    
    
    resource "azurerm_public_ip" "example" {
      name                = "vksb-publicip"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
      allocation_method   = "Static"
    }
    
    resource "azurerm_lb" "example" {
      name                = "vksb-example-lb"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    
      frontend_ip_configuration {
        name                 = "publicIPAddress"
        public_ip_address_id = azurerm_public_ip.example.id
      }
    }
    
    resource "azurerm_lb_backend_address_pool" "example" {
      loadbalancer_id = azurerm_lb.example.id
      name            = "vksb-backend"
    }
    
    resource "azurerm_lb_rule" "example" {
      loadbalancer_id                = azurerm_lb.example.id
      name                           = "HTTP"
      protocol                       = "Tcp"
      frontend_port                  = 80
      backend_port                   = 80
      frontend_ip_configuration_name = "publicIPAddress"
      
    }
    
    resource "azurerm_container_group" "example" {
      name                = "vksb-containergroup"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
      os_type             = "Linux"
    
      container {
        name   = "example-container"
        image  = "hello-world"  # Updated image
        cpu    = "0.5"
        memory = "1.5"
    
        ports {
          port     = 80
          protocol = "TCP"
        }
      }
    
      ip_address_type = "Private"
      subnet_ids = [azurerm_subnet.example.id]
    
    }
    
    output "public_ip_address" {
      value = azurerm_public_ip.example.ip_address
    }
    

    Output:

    enter image description here

    enter image description here

    enter image description here

    Login or Signup to reply.
  2. You need a Load Balancer SKU Standard and a Public IP SKU Standard. Then, when the Container Group is created you can fetch the Container Group IP address and associate it with the load balancer (Standard LB can use IPs in the address pool, Basic LB cannot).
    Security wise you buy yourself a safer environment as well. Standard SKUs in this case are closed by default and you have to open up ports you want to access.

    I’ve simplified a working example here, deploying a Hello Nginx container. It might not be fully complete but should be very close to working (just deployed the same config).

    https://gist.github.com/svenakela/481b7c41e1f9f238b8558f5749c75b82

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search