Automated deployment of Microsoft AutoGen applications using Ansible.
This playbook installs Python, creates a virtual environment, and deploys an AutoGen application.
Create inventory.ini:
[autogen_servers]
autogen-prod-01 ansible_host=192.168.1.100
autogen-prod-02 ansible_host=192.168.1.101
[autogen_servers:vars]
ansible_user=ubuntu
ansible_python_interpreter=/usr/bin/python3
Create autogen.yml:
---
- name: Deploy Microsoft AutoGen Application
hosts: autogen_servers
become: true
vars:
app_name: autogen
app_dir: /opt/autogen
python_version: "3.11"
openai_api_key: "{{ vault_openai_api_key }}"
tasks:
- name: Install system dependencies
apt:
name:
- python3
- python3-pip
- python3-venv
- python3-dev
- git
- build-essential
state: present
update_cache: yes
- name: Create application directory
file:
path: "{{ app_dir }}"
state: directory
mode: '0755'
- name: Create subdirectories
file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ app_dir }}/src"
- "{{ app_dir }}/output"
- "{{ app_dir }}/coding"
- "{{ app_dir }}/logs"
- name: Create Python virtual environment
command: python3 -m venv {{ app_dir }}/venv
args:
creates: {{ app_dir }}/venv/bin/activate
- name: Upgrade pip
pip:
name: pip
state: latest
virtualenv: "{{ app_dir }}/venv"
- name: Install AutoGen
pip:
name:
- autogen-agentchat
- autogen-ext[openai]
- python-dotenv
virtualenv: "{{ app_dir }}/venv"
- name: Create .env file
copy:
dest: "{{ app_dir }}/.env"
content: |
OPENAI_API_KEY={{ openai_api_key }}
mode: '0600'
- name: Create main application script
copy:
dest: "{{ app_dir }}/src/main.py"
content: |
#!/usr/bin/env python3
import asyncio
import os
from dotenv import load_dotenv
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
load_dotenv()
async def main():
model_client = OpenAIChatCompletionClient(model="gpt-4o")
agent = AssistantAgent(
"assistant",
model_client=model_client,
system_message="You are a helpful assistant."
)
result = await agent.run(task="Say hello!")
print(result)
await model_client.close()
if __name__ == "__main__":
asyncio.run(main())
mode: '0755'
- name: Create systemd service
copy:
dest: /etc/systemd/system/autogen.service
content: |
[Unit]
Description=Microsoft AutoGen Application
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory={{ app_dir }}
Environment="PATH={{ app_dir }}/venv/bin"
EnvironmentFile={{ app_dir }}/.env
ExecStart={{ app_dir }}/venv/bin/python {{ app_dir }}/src/main.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
notify:
- Restart AutoGen
- name: Enable and start service
systemd:
name: autogen
enabled: yes
state: started
daemon_reload: yes
handlers:
- name: Restart AutoGen
systemd:
name: autogen
state: restarted
daemon_reload: yes
# Basic run
ansible-playbook -i inventory.ini autogen.yml
# With vault secrets
ansible-playbook -i inventory.ini autogen.yml --ask-vault-pass
# Limit to specific host
ansible-playbook -i inventory.ini autogen.yml --limit autogen-prod-01
# Dry run (check mode)
ansible-playbook -i inventory.ini autogen.yml --check
Create secrets file:
ansible-vault create group_vars/all/vault.yml
Add your secrets:
vault_openai_api_key: "sk-your-openai-api-key"
# Check service status
ansible -i inventory.ini autogen_servers -m systemd -a "name=autogen state=started"
# View logs
ansible -i inventory.ini autogen_servers -m shell -a "journalctl -u autogen -n 20"
# Test execution
ansible -i inventory.ini autogen_servers -m shell -a "{{ app_dir }}/venv/bin/python {{ app_dir }}/src/main.py"
- name: Rolling update AutoGen
hosts: autogen_servers
become: true
serial: 1 # Update one server at a time
tasks:
- name: Stop service
systemd:
name: autogen
state: stopped
- name: Update pip packages
pip:
name:
- autogen-agentchat
- autogen-ext[openai]
state: latest
virtualenv: "{{ app_dir }}/venv"
- name: Start service
systemd:
name: autogen
state: started
- name: Verify service
systemd:
name: autogen
state: started
register: result
retries: 3
delay: 10
until: result.status.ActiveState == "active"
- name: Deploy AutoGen Studio
hosts: autogen_servers
become: true
vars:
studio_port: 8080
tasks:
- name: Install AutoGen Studio
pip:
name: autogenstudio
virtualenv: "{{ app_dir }}/venv"
- name: Create AutoGen Studio service
copy:
dest: /etc/systemd/system/autogen-studio.service
content: |
[Unit]
Description=AutoGen Studio
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory={{ app_dir }}
Environment="PATH={{ app_dir }}/venv/bin"
EnvironmentFile={{ app_dir }}/.env
ExecStart={{ app_dir }}/venv/bin/autogenstudio ui --port {{ studio_port }} --host 0.0.0.0
Restart=always
[Install]
WantedBy=multi-user.target
notify:
- Restart AutoGen Studio
- name: Enable and start Studio service
systemd:
name: autogen-studio
enabled: yes
state: started
daemon_reload: yes
handlers:
- name: Restart AutoGen Studio
systemd:
name: autogen-studio
state: restarted
daemon_reload: yes
- name: Deploy AutoGen FastAPI service
hosts: autogen_servers
become: true
vars:
api_port: 8000
tasks:
- name: Install FastAPI dependencies
pip:
name:
- fastapi
- uvicorn
virtualenv: "{{ app_dir }}/venv"
- name: Create API application
copy:
dest: "{{ app_dir }}/src/api.py"
content: |
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
app = FastAPI()
class TaskRequest(BaseModel):
task: str
model: str = "gpt-4o"
class TaskResponse(BaseModel):
result: str
@app.post("/run", response_model=TaskResponse)
async def run_task(request: TaskRequest) -> TaskResponse:
try:
model_client = OpenAIChatCompletionClient(model=request.model)
agent = AssistantAgent("assistant", model_client=model_client)
result = await agent.run(task=request.task)
await model_client.close()
return TaskResponse(result=str(result))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health():
return {"status": "healthy"}
mode: '0644'
- name: Create API systemd service
copy:
dest: /etc/systemd/system/autogen-api.service
content: |
[Unit]
Description=AutoGen FastAPI Service
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory={{ app_dir }}
Environment="PATH={{ app_dir }}/venv/bin"
EnvironmentFile={{ app_dir }}/.env
ExecStart={{ app_dir }}/venv/bin/uvicorn src.api:app --host 0.0.0.0 --port {{ api_port }}
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
notify:
- Restart AutoGen API
- name: Enable and start API service
systemd:
name: autogen-api
enabled: yes
state: started
daemon_reload: yes
handlers:
- name: Restart AutoGen API
systemd:
name: autogen-api
state: restarted
daemon_reload: yes
- name: Backup AutoGen configuration
hosts: autogen_servers
become: true
tasks:
- name: Create backup directory
file:
path: "{{ app_dir }}/backups"
state: directory
- name: Backup config files
archive:
path:
- "{{ app_dir }}/.env"
- "{{ app_dir }}/src"
dest: "{{ app_dir }}/backups/config-{{ ansible_date_time.date }}.tar.gz"
ansible -i inventory.ini autogen_servers \
-m systemd -a "name=autogen"
ansible -i inventory.ini autogen_servers \
-m shell -a "journalctl -u autogen --since '1 hour ago'"
ansible -i inventory.ini autogen_servers \
-m systemd -a "name=autogen state=restarted"
ansible -i inventory.ini autogen_servers \
-m shell -a "{{ app_dir }}/venv/bin/pip list | grep autogen"
ansible -i inventory.ini autogen_servers \
-m uri -a "url=http://localhost:8000/health method=GET return_content=yes"
See the main AutoGen Setup guide for more details.