I want to create and Azure Container Instance (ACI) from azure functions app in python

Viewed 446

I'm trying to replicate my deployment I had on AWS on azure. I had an entirely serverless based architecture on aws which consisted of aws lambda with s3 trigger, aws sagemaker processing job and aws ecr. The lambda would trigger the sagemaker processing job (using the python BOTO3 library) only if FILE A and FILE B are present. In the sense that I mention an if condition in my lambda function which says that only trigger the job if these 2 files are present. The lambda is triggered when I upload these 2 files. The aws has very extensive documentation about this and it has a specific path that I can mention that would then copy these files into sagemaker processing job container (opt/ml/processing). It also has a parameter to specify the algorithm or the docker image which can instruct the job what to do with the 2 files. Now I want to achieve the same on azure but having difficulty finding something similar here. I did however find something very similar which is the azure container instance which I can provision within the azure function which has a blob trigger. Now what I'm having difficulty is with how do I push these FILE A and FILE B inside the container? Also once the container is done doing whatever it's supposed to do, it generates a bunch of output files that need to stored somewhere. I need them to stored in a blob storage if possible.

What I want is to trigger the creation of an azure container instance when the function app is trigger. The function app will be triggered (blob trigger) when say FILE A and FILE B are uploaded. These files should then make their way inside the container. I've found a script :

def create_container_group(aci_client, resource_group,
                       container_group_name, container_image_name):
"""Creates a container group with a single container.

Arguments:
    aci_client {azure.mgmt.containerinstance.ContainerInstanceManagementClient}
                -- An authenticated container instance management client.
    resource_group {azure.mgmt.resource.resources.models.ResourceGroup}
                -- The resource group in which to create the container group.
    container_group_name {str}
                -- The name of the container group to create.
    container_image_name {str}
                -- The container image name and tag, for example:
                   microsoft\aci-helloworld:latest
"""
print("Creating container group '{0}'...".format(container_group_name))

# Configure the container
container_resource_requests = ResourceRequests(memory_in_gb=1, cpu=1.0)
container_resource_requirements = ResourceRequirements(
    requests=container_resource_requests)
container = Container(name=container_group_name,
                      image=container_image_name,
                      resources=container_resource_requirements,
                      ports=[ContainerPort(port=80)])

# Configure the container group
ports = [Port(protocol=ContainerGroupNetworkProtocol.tcp, port=80)]
group_ip_address = IpAddress(ports=ports,
                             dns_name_label=container_group_name,
                             type="Public")
group = ContainerGroup(location=resource_group.location,
                       containers=[container],
                       os_type=OperatingSystemTypes.linux,
                       ip_address=group_ip_address)

But I have trouble on how I can transfer these files inside the container.

1 Answers

For an Azure Container Instance you have to upload your image into an Azure Container Registry: https://azure.microsoft.com/en-gb/services/container-registry/#features

Then when the Azure Container Initialises it will try and pull what ever is in that registry down.

As by default container instances do not have an OS on them.

I use Azure CLI to create my container instances and docker to build my images.

This medium artcile sort of has the steps but when I did this, it required some playing about: https://medium.com/kocsistem/creating-azure-container-registry-using-the-azure-cli-769138d9d804

If I was you I would use the following docker image:

FROM mcr.microsoft.com/windows/servercore:ltsc2022

Here is its github image file: https://github.com/docker-library/python/blob/3d43bcf8ddd26ae85fd6a63a7e1d502b445c9cce/3.9/windows/windowsservercore-ltsc2022/Dockerfile

UPDATE:

I was going to share my whole, docker file but then when looking at it I have some company settings all over it. So will just explain what I did.

In my image setup I have a file called finalruncommands.bat within that code it can call a bunch of things but one of them is vsts powershell script that I have made so a .ps1 file. (Similar to what you are trying to achieve here)

Here is the folder structure that I have which may make more sense to you.

enter image description here

Here is a picture of the final runs commands .bat file that I call at the end.

enter image description here

Then at the very end of my docker file I have a an entrypoint allowing the image to wait for the commands. In your case your image is waiting on a file or command to get to that file, or your calling a script, by your comments I think that's what you are doing.

# Define the entry point for the docker container.
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT "C:\azp\Finalruncommands.bat"

So in your case you do an ENTRYPOINT with it pointing at your script.

UPDATE:

I re-read through my answer and it all doesn't quite click unless I share my code so here it is without personal settings.

# escape=`

FROM mcr.microsoft.com/windows/servercore:ltsc2019


ENV chocolateyUseWindowsCompression=false

SHELL ["powershell", "-Command"]


RUN Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

RUN choco config set cachelocation C:\chococache

RUN choco feature enable --name allowGlobalConfirmation

#Install Required Software
RUN choco install git --confirm --timeout 216000; 
RUN choco install nodejs-lts --version=14.16.1 --confirm --timeout 216000;
RUN choco install openjdk --confirm --timeout 216000;
RUN choco install curl --confirm --timeout 216000;
RUN choco install terraform --confirm --timeout 216000;
RUN npm install -g npm@6.14.12

#Configure npm
WORKDIR /usr/src/app
COPY package*.json ./
COPY . .
COPY npm.cmd C:\Users\ContainerAdministrator\AppData\Roaming\npm\

# Install .Net Core SDK Used for Building Web Apps
#RUN choco install dotnet-sdk --confirm --limit-output --timeout 216000;
RUN choco install dotnet-5.0-sdk --version=5.0.301 --confirm --limit-output --timeout 216000;

# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]

# Destroy Choclotatey cache
RUN rmdir /S /Q C:\chococache

# Set Path Variable for dotnet

RUN setx /M PATH "%PATH%;%ProgramFiles%\dotnet"

# Trigger the population of the local package cache
ENV NUGET_XMLDOC_MODE skip
#USER ContainerAdministrator
#RUN mkdir warmup 
WORKDIR /warmup
RUN dotnet new
WORKDIR /azp
RUN rmdir /S /Q C:\warmup 

#Expose Ports for Azure Container Instance

EXPOSE 80/udp 
EXPOSE 80/tcp 
EXPOSE 5000/udp
EXPOSE 5000/tcp
EXPOSE 8080/udp 
EXPOSE 8080/tcp

#Install DevOps Agents
COPY start.ps1 .

#Configure DevOps Agent and prep Image for run.
ADD Finalruncommands.bat C:\azp\

# Define the entry point for the docker container.
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT "C:\azp\Finalruncommands.bat"

Related