Skip to content

Container Instances

See below for an example of an Azure Container Instance deployment using the container_group variable. The subnet used for the container group must be delegated to Microsoft.ContainerInstance/containerGroups.

Basic Example

The example includes some additional optional configuration including a user assigned managed identity that can be used to grant the container access to other Azure resources and some Azure File Shares that are mounted as volumes within the container for persistent storage.

See the azurerm_container_group for more information.

storage_accounts = {
    "diagsaphdev" = {
        resource_group = "hsw"
        public_network_access_enabled = true
        shares = {
            "ansible-files" = {
                quota = "10"
            }
        }
    }   
}

networks = {
    "hsw" = {
        resource_group = "hsw"
        address_space = ["10.40.44.0/22"]
        subnets = {
            hsw = {
                network_security_group = "hsw"
                address_prefixes = ["10.40.44.0/25"]
                nat_gateway = "hsw"
            }
            container = {
                network_security_group = "hsw"
                address_prefixes = ["10.40.44.128/25"]
                nat_gateway = "hsw"
                delegation = {
                    name = "Microsoft.ContainerInstance/containerGroups"
                    service_delegation = {
                        name = "Microsoft.ContainerInstance/containerGroups"
                        actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
                    }
                }
            }
            bastion = {
                name = "AzureBastionSubnet"
                network_security_group = "bastion"
                address_prefixes = ["10.40.45.0/24"]
            }
        }
    }
}

user_assigned_identity = {
    ansible_container = {
        resource_group = "hsw"
    }
}

container_group = {
    ansible = {
        resource_group = "hsw"
        ip_address_type = "Private"
        subnets = ["hsw.container"]
        container = {
            ansible = {
                image = "ghcr.io/sapphire-health/ansible-epic:azure"
                cpu = 2
                memory = 4
                ports = [
                    {
                        port = 22
                        protocol = "TCP"
                    }
                ]
                volume = {
                    ansible-files = {
                        mount_path = "/files"
                        storage_account = "diagsaphdev"
                        share = "ansible-files"
                    }
                }
                environment_variables = {
                    TUNNEL_NAME = "ansible-az-container"
                }
            }
        }
        identity = {
            type = "UserAssigned"
            user_assigned_identities = ["ansible_container"]
        }
    }
}

Advanced Example

The next example shows how to deploy a Caddy reverse proxy in front of a container to separate

storage_accounts = {
    "diagsaphdev" = {
        resource_group = "hsw"
        public_network_access_enabled = true
        shares = {
            "iot-hsm-softhsm2" = {
                quota = "10"
            }
            "iot-hsm-state" = {
                quota = "10"
            }
        }
    }   
}

container_group = {
    iothsm = {
        resource_group = "hsw"
        ip_address_type = "Private"
        subnets = ["hsw.container"]
        container = {
            caddy = {
                image = "ghcr.io/caddybuilds/caddy-cloudflare:latest"
                cpu = 0.5
                memory = 1
                ports = [
                    {
                        port = 80
                        protocol = "TCP"
                    },
                    {
                        port = 443
                        protocol = "TCP"
                    }
                ]
                environment_variables = {
                    CADDY_EMAIL = "lspiehler@gmail.com"
                    CADDY_ADDITIONAL_OPTIONS = "-agree=true"
                    CADDY_LOG_LEVEL = "ERROR"
                    CADDY_CERT = <<-EOT
                    -----BEGIN CERTIFICATE-----
                    MIICEjCCAbmgAwIBAgIUSW8QDVQ7oo4AT+5ois8pYd9OBQgwCgYIKoZIzj0EAwIw
                    RDEPMA0GA1UEAwwGaW90aHNtMQswCQYDVQQGEwJVUzESMBAGA1UECAwJTG91aXNp
                    YW5hMRAwDgYDVQQHDAdTbGlkZWxsMB4XDTI1MTIyNjE4NTQ0OVoXDTQ1MTIyMTE4
                    NTQ0OVowRDEPMA0GA1UEAwwGaW90aHNtMQswCQYDVQQGEwJVUzESMBAGA1UECAwJ
                    TG91aXNpYW5hMRAwDgYDVQQHDAdTbGlkZWxsMFkwEwYHKoZIzj0CAQYIKoZIzj0D
                    AQcDQgAEwOKCDmllUpTLI495CTKCDTVPxGYWJqEATRZ03LZ0LIgGG7gDydNk0ImH
                    SDwG5EMw4hJzu0BruNfsNx0iI4NFKqOBiDCBhTAdBgNVHQ4EFgQUNCEeULIG017r
                    CReJL/xca7hVdQcwHwYDVR0jBBgwFoAUNCEeULIG017rCReJL/xca7hVdQcwDgYD
                    VR0PAQH/BAQDAgWgMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAR
                    BgNVHREECjAIggZpb3Roc20wCgYIKoZIzj0EAwIDRwAwRAIgNEV9aY7KKf+ZbuM3
                    I008Q6+GZ+ammyYS83y/GMp6z2ACIAX561haog+Sj0zdusnzC0M58D7XJgnYnO1/
                    A+ReZvz0
                    -----END CERTIFICATE-----
                    EOT
                    CADDY_KEY = <<-EOT
                    -----BEGIN PRIVATE KEY-----
                    MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgDO1DXcPFVxoH/5qx
                    9l2RAfGt4cg13Yxf+rfUyCj7sryhRANCAATA4oIOaWVSlMsjj3kJMoINNU/EZhYm
                    oQBNFnTctnQsiAYbuAPJ02TQiYdIPAbkQzDiEnO7QGu41+w3HSIjg0Uq
                    -----END PRIVATE KEY-----
                    EOT
                    CADDY_CONFIG = <<-EOT
                    :443 {
                        bind 0.0.0.0
                        tls /tmp/cert.pem /tmp/cert.key
                        basic_auth /* {
                            admin $2a$14$6Nv.IUjjsUcXXL62kuHvaezp7A2zWguxY4DwI7DVrMtHY6jAdMKIK
                        }
                        reverse_proxy http://localhost:3000
                    }
                    EOT
                }
                commands = [
                    "/bin/sh",
                    "-c",
                    "printf \"%s\" \"$CADDY_CERT\" > /tmp/cert.pem && printf \"%s\" \"$CADDY_KEY\" > /tmp/cert.key && printf \"%s\" \"$CADDY_CONFIG\" > Caddyfile && caddy run --config Caddyfile --adapter caddyfile"
                ]
            }
            iothsm = {
                image = "ghcr.io/lspiehler/iot-hsm:latest"
                cpu = 1
                memory = 2
                environment_variables = {
                    LISTENIP = "0.0.0.0"
                }
                volume = {
                    iot-hsm-softhsm2 = {
                        mount_path = "/var/lib/softhsm/tokens"
                        storage_account = "diagsaphdev"
                        share = "iot-hsm-softhsm2"
                    }
                    iot-hsm-state = {
                        mount_path = "/var/node/iot-hsm/state"
                        storage_account = "diagsaphdev"
                        share = "iot-hsm-state"
                    }
                }
            }
        }
        exposed_port = [
            {
                port = 80
                protocol = "TCP"
            },
            {
                port = 443
                protocol = "TCP"
            }
        ]
        identity = {
            type = "UserAssigned"
            user_assigned_identities = ["ansible_container"]
        }
    }
}