../../_images/azure_aci.png

Azure Container Instances

Prerequisites

Azure Container Instances is a quick way to deploy your container into Docker host within Azure, without having to provision the underlying servers first (VM + OS).

  • Azure Subscription

  • Azure Service Principal Account

CLI tools

The az command line tool will be used to programmatically access your Azure subscription. To install the CLI tool, follow the link below and choose the correct operating sytem:

Obtain the latest ARM template

The latest ARM template is as follows:

@description('Name (default: l7esp-example)')
param containerName string = 'l7esp-example'

@description('Azure location to deploy containers (default: Azure Resource Group location)')
param azureLocation string = resourceGroup().location

@description('L7|ESP software license (optional; JSON string)')
param appLicense string = ''

@description('L7|ESP admin password (required; initial password)')
param appPassword string = 'changeme'

@description('L7|ESP web UI port (default: 8002)')
param appPortHTTP int = 8002

@description('Container Image (e.g. acme/l7esp:3.0.0)')
param containerImage string = ''

@description('Container CPU cores (default: 2 vCPU)')
param containerCPU int = 2

@description('Container Memory (default: 6GB RAM)')
param containerMemory int = 6

@description('Container Restart Policy (default: Never)')
@allowed([
  'Always'
  'Never'
  'OnFailure'
])
param containerRestartPolicy string = 'Never'

@description('Container Registry URL (default: docker.io)')
param registryURL string = ''

@description('Container Registry Username (e.g. Docker Hub user)')
param registryUsername string = ''

@description('Container Registry Password (e.g. Docker Hub app password)')
param registryPassword string = ''

resource container_instance 'Microsoft.ContainerInstance/containerGroups@2021-09-01' = {
  name: containerName
  location: azureLocation
  properties: {
    containers: [
      {
        name: containerName
        properties: {
          image: containerImage
          ports: [
            {
              port: appPortHTTP
              protocol: 'TCP'
            }
          ]
          environmentVariables: [
            {
              secureValue: appPassword
              name: 'L7ESP_PASSWORD'
            }
            {
              secureValue: appLicense
              name: 'L7ESP_LICENSE'
            }
          ]
          resources: {
            requests: {
              cpu: containerCPU
              memoryInGB: containerMemory
            }
          }
        }
      }
    ]
    osType: 'Linux'
    restartPolicy: containerRestartPolicy
    ipAddress: {
      type: 'Public'
      ports: [
        {
          port: appPortHTTP
          protocol: 'TCP'
        }
      ]
    }
    imageRegistryCredentials: [
      {
        password: registryPassword
        server: registryURL
        username: registryUsername
      }
    ]
  }
}

output containerIPv4Address string = container_instance.properties.ipAddress.ip
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.6.18.56646",
      "templateHash": "17739852969827724894"
    }
  },
  "parameters": {
    "containerName": {
      "type": "string",
      "defaultValue": "l7esp-example",
      "metadata": {
        "description": "Name (default: l7esp-example)"
      }
    },
    "azureLocation": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Azure location to deploy containers (default: Azure Resource Group location)"
      }
    },
    "appLicense": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "L7|ESP software license (optional; JSON string)"
      }
    },
    "appPassword": {
      "type": "string",
      "defaultValue": "changeme",
      "metadata": {
        "description": "L7|ESP admin password (required; initial password)"
      }
    },
    "appPortHTTP": {
      "type": "int",
      "defaultValue": 8002,
      "metadata": {
        "description": "L7|ESP web UI port (default: 8002)"
      }
    },
    "containerImage": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "Container Image (e.g. acme/l7esp:3.0.0)"
      }
    },
    "containerCPU": {
      "type": "int",
      "defaultValue": 2,
      "metadata": {
        "description": "Container CPU cores (default: 2 vCPU)"
      }
    },
    "containerMemory": {
      "type": "int",
      "defaultValue": 6,
      "metadata": {
        "description": "Container Memory (default: 6GB RAM)"
      }
    },
    "containerRestartPolicy": {
      "type": "string",
      "defaultValue": "Never",
      "allowedValues": [
        "Always",
        "Never",
        "OnFailure"
      ],
      "metadata": {
        "description": "Container Restart Policy (default: Never)"
      }
    },
    "registryURL": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "Container Registry URL (default: docker.io)"
      }
    },
    "registryUsername": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "Container Registry Username (e.g. Docker Hub user)"
      }
    },
    "registryPassword": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "Container Registry Password (e.g. Docker Hub app password)"
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.ContainerInstance/containerGroups",
      "apiVersion": "2021-09-01",
      "name": "[parameters('containerName')]",
      "location": "[parameters('azureLocation')]",
      "properties": {
        "containers": [
          {
            "name": "[parameters('containerName')]",
            "properties": {
              "image": "[parameters('containerImage')]",
              "ports": [
                {
                  "port": "[parameters('appPortHTTP')]",
                  "protocol": "TCP"
                }
              ],
              "environmentVariables": [
                {
                  "secureValue": "[parameters('appPassword')]",
                  "name": "L7ESP_PASSWORD"
                },
                {
                  "secureValue": "[parameters('appLicense')]",
                  "name": "L7ESP_LICENSE"
                }
              ],
              "resources": {
                "requests": {
                  "cpu": "[parameters('containerCPU')]",
                  "memoryInGB": "[parameters('containerMemory')]"
                }
              }
            }
          }
        ],
        "osType": "Linux",
        "restartPolicy": "[parameters('containerRestartPolicy')]",
        "ipAddress": {
          "type": "Public",
          "ports": [
            {
              "port": "[parameters('appPortHTTP')]",
              "protocol": "TCP"
            }
          ]
        },
        "imageRegistryCredentials": [
          {
            "password": "[parameters('registryPassword')]",
            "server": "[parameters('registryURL')]",
            "username": "[parameters('registryUsername')]"
          }
        ]
      }
    }
  ],
  "outputs": {
    "containerIPv4Address": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups', parameters('containerName'))).ipAddress.ip]"
    }
  }
}

Deploy ARM template with desired parameters

When deploying the ARM template, you can override parameters like so:

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {        
    "software_license": {
      "value": ""
    },
    "container_group_name": {
      "value": "espacicontainergroup"
    },
    "admin_password": {
      "value": ""
    },
    "image": {
      "value": "docker.io/l7esp/server:3.0.0-sdk.1"
    },
    "port": {
      "value": 8002
    },
    "cpuCores": {
      "value": 2
    },
    "server": {
      "value": "docker.io"
    },
    "credUsername": {
      "value": ""
    },
    "credPassword": {
      "value": ""
    },
    "memoryInGb": {
      "value": 6
    }
  }
}
  • containerName - Name (default: l7esp-example)

  • azureLocation - Azure location to deploy containers (default: Azure Resource Group location)

  • appLicense : L7|ESP software license (optional; JSON string)

  • appPassword - L7|ESP admin password (required; initial password)

  • appPortHTTP : L7|ESP web UI port (default: 8002)

  • containerImage: Container Image (e.g. docker.io/acme/l7esp:3.0.0)

  • containerCPU : Container CPU cores (default: 2 vCPU)

  • containerMemory : Container Memory (default: 6GB RAM)

  • containerRestartPolicy - Container Restart Policy (default: Never)

  • registryURL : Container Registry URL (default: docker.io)

  • registryUsername : Container Registry Username (e.g. Docker Hub user)

  • registryPassword : Container Registry Password (e.g. Docker Hub app password)

Run ARM template pipeline to create AKS

Login to Azure. For example, if you are using a service principle account that has Contributor role, you can login to Azure using the following command:

$ az login \
      --service-principal \
      --username <service-principal-id> \
      --password <service-principal-password> \
      --tenant <tenant-id>

Create a resource group to deploy into, if you haven’t already:

$ az group create \
      --name <resource-group-name> \
      --location <resource-group-location>

Create ARM deployment in the resource group:

$ az group deployment create \
      --resource-group l7esp-example-rg \
      --name l7esp-example \
      --template-file ./aci.template.json \
      --parameters ./aci.parameters.json \
      --rollback-on-error \
      --verbose

Validate Resource Creation

In the Azure portal, navigate to Container Instances and verify that the L7|ESP container instance was created and that it ends up in the Running state:

../../_images/acicontainergroup.png