Task 02 - Automate deployment of Microsoft Foundry agents

Introduction

So far in this training, you have manually deployed the agents to Microsoft Foundry using the Azure portal one time. In reality, you will likely need to make changes to the agents over time, such as updating the prompts or adding new tools. For this reason, it can be important to automate this deployment process so that you can easily make changes and redeploy the agents as needed.

Description

In this task, you will create a GitHub Actions workflow that automates the deployment of your Microsoft Foundry agents. The workflow will be triggered on changes to the agent configuration files in your repository. It will use the Azure CLI to check if the agent already exists, and if it does, it will update the existing agent instead of creating a new one. The workflow will also read the necessary secrets from the GitHub repository to authenticate with Azure.

Success Criteria

  • You have updated the agent initializers to check if the agent exists before creating it.
  • You have created a GitHub Actions workflow that deploys or updates the agents based on changes to prompts, initializers, or tool files.
  • You have successfully deployed an agent change using the GitHub Actions workflow.

Learning Resources

Key Tasks

01: Update initializers

The agent initializers that you created in Exercise 02 were written in such a way that they would always create a new agent when run. This is not ideal for a CI/CD pipeline, as you would end up with multiple agents if you made changes and redeployed. Instead, you need to update the initializers to check if the agent already exists, and if it does, update the existing agent instead of creating a new one.

Expand this section to view the solution

Each of the initializers you created in Exercise 02 made a call to a function named initialize_agent(), located in src/app/agents/agent_initializer.py. This function is responsible for creating the agent in Microsoft Foundry. By modifying this function, you can implement the logic to check if the agent exists and update it if it does.

Begin by opening the agent_initializer.py file. The relevant section of the file is shown below:

def initialize_agent(project_client : AIProjectClient, model : str, env_var_name : str, name : str, instructions : str, toolset : ToolSet):
    with project_client:
        agent = project_client.agents.create_agent(
            model=model,
            name=name,
            instructions=instructions,
            toolset=toolset
        )
        print(f"Created {name} agent, ID: {agent.id}")

This code calls project_client.agents.create_agent, which will always create a new agent with a new Agent ID. Instead, you will retrieve the appropriate agent ID from the .env file. Replace the function definition with the following:

def initialize_agent(project_client : AIProjectClient, model : str, env_var_name : str, name : str, instructions : str, toolset : ToolSet):
    agent_id = os.environ[env_var_name]
    with project_client:
        agent_exists = False
        if agent_id:
            # Check if agent exists.
            agent = project_client.agents.get_agent(agent_id)
            print(f"Retrieved existing agent, ID: {agent.id}")
            agent_exists = True
        
        if agent_exists:
            agent = project_client.agents.update_agent(
                agent_id=agent.id,
                model=model,
                name=name,
                instructions=instructions,
                toolset=toolset
            )
            print(f"Updated {env_var_name} agent, ID: {agent.id}")
        else:
            agent = project_client.agents.create_agent(
            model=model,
            name=name,
            instructions=instructions,
            toolset=toolset
            )
            print(f"Created {env_var_name} agent, ID: {agent.id}")

This updated function first retrieves the agent ID from the environment variable specified by env_var_name. If the agent ID is set, it attempts to retrieve the existing agent using project_client.agents.get_agent(). If the agent exists, it updates the agent using project_client.agents.update_agent(). If the agent does not exist (i.e., the agent ID is not set), it creates a new agent as before.

This change will allow your GitHub Actions workflow to update existing agents instead of creating new ones each time you make a change.

02: Create a service principal

Create a new service principal named TechWorkshopL300AzureAI using the following command in the az CLI, being sure to replace {SUB_ID} and {RG} with your subscription ID and resource group, respectively:

az ad sp create-for-rbac --name "TechWorkshopL300AzureAI" --json-auth --role contributor --scopes /subscriptions/{SUB_ID}/resourceGroups/{RG}

03: Create GitHub Actions secret

Create the following GitHub Actions secret:

  1. AZURE_CREDENTIALS – Paste in the entirety of the JSON output from running az ad sp create-for-rbac.
Expand this section to view the solution

To create a GitHub Actions secret, navigate to your forked GitHub repository and select the Settings menu. From there, navigate to Secrets and variables and select the Actions menu. You can then create new repository secrets.

Create new repository secrets.

04: Grant the service principal access to Microsoft Foundry

Next, you will need to grant the service principal access to your Microsoft Foundry instance. Specifically, the TechWorkshopL300AzureAI service principal will need to be assigned the Azure AI User role for your Microsoft Foundry resource. This will allow your GitHub Actions workflow to use the service principal to create and manage agents within Microsoft Foundry.

Expand this section to view the solution

Navigate to the Azure portal and open your Microsoft Foundry resource.

Select the Microsoft Foundry resource.

From there, navigate to Access control (IAM) from the left-hand menu. Select the + Add button and then choose the Add role assignment option.

Add a new role assignment.

In the Role dropdown, select the Azure AI User role. Then, select the Members tab.

Assign the Azure AI User role to the service principal.

On the Add role assignment page, select the User, group, or service principal radio button and then select + Select members. In the Select members pane, search for TechWorkshopL300AzureAI and select it from the list. After that, select the Select button at the bottom of the pane.

Select the TechWorkshopL300AzureAI service principal.

Finally, select Review + assign twice to grant the Azure AI User role to your service principal.

05: Create workflow for each agent

The next step is to create a workflow for each agent. This workflow will check if the prompt file, initializer, or tool file(s) have changed, and if they have, it will trigger the execution of the initializer in the workflow. You will create a separate workflow file for each agent in the .github/workflows directory of your repository because each agent has its own initializer and prompt file, and you want to be able to deploy them independently.

Use GitHub Copilot to assist you in writing the GitHub Actions workflow files. The workflow should be triggered on changes to the relevant files for each agent. It should use the Azure CLI to authenticate with Azure and run the initializer script for the agent.

You might wish to use a prompt such as the following as a starting point for GitHub Copilot:

Please generate a GitHub Actions workflow that executes the python code in src/app/agents/customerLoyaltyAgent_initializer.py if that file changes or if the src/prompts/CustomerLoyaltyAgentPrompt.txt file changes. It also makes use of a tool located in src/app/tools/discountLogic.py, so any changes there must also trigger the workflow. The Python script needs to be able to connect to Azure using the azure.ai.projects package.

If you are unable to get a satisfactory response from GitHub Copilot or wish to compare your results to a working example, you can use the following example workflow as a starting point. Make sure to adjust the values for your specific environment.

Expand this section to view the solution if you are not able to get a satisfactory response from GitHub Copilot

This example workflow is for the Customer Loyalty agent. You will need to create similar workflows for the other agents, adjusting the file paths and environment variables as needed.

A sample workflow is available for the Customer Loyalty agent in the src/workflows/0502_sample_agent_deployment.yml file. This YAML file can be copied to the .github/workflows/ folder in your repository and it requires the following secrets to be set up in your GitHub repository:

  • AZURE_CREDENTIALS: The Azure service principal credentials you created earlier in Step 03 of this task.
  • ENV: The contents of your local .env file.

The other agent workflows will be similar, but should reference their respective initializer files, prompt files, and any tool files they use.

Repeat this process for the other four workflows, including details on their initializers, prompts, and (when applicable) tools.

06: Perform and verify the deployment

Once the workflows are in place, you can trigger them (assuming you have a workflow_dispatch trigger) or make a small change to one of the relevant files to trigger the workflow. You can then monitor the progress of the workflow in the Actions tab of your GitHub repository.

Review a successful deployment.