Function Calling an Ansible Playbook with OpenAI
Learn how to use OpenAI function calling to trigger Ansible playbooks with natural language. Build a simple AI-powered DevOps automation workflow using Python, OpenAI, and Ansible.
By Network Nuts Team · Published 2026-08-10
Large Language Models become much more useful when they can do more than simply generate text.
Imagine asking an AI assistant:
Restart Nginx on my web servers.
Instead of returning a list of Linux commands, the AI can identify the requested operation and trigger an Ansible playbook that performs the change.
This can be implemented using OpenAI function calling.
The basic architecture looks like this:
User
|
| "Restart Nginx"
v
Python Application
|
v
OpenAI API
|
| Function Call
v
Python Function
|
v
ansible-playbook
|
v
Managed Servers
In this article, we'll build a small example showing how OpenAI can function-call an Ansible playbook.
Why Combine OpenAI with Ansible?
Ansible already provides an excellent automation engine for infrastructure.
It can:
- Configure Linux servers
- Install packages
- Manage services
- Configure networking
- Deploy applications
- Manage cloud infrastructure
- Configure Kubernetes and other platforms
The problem is that users normally need to know which playbook to execute and what parameters to provide.
An AI layer can provide a natural-language interface.
Instead of:
ansible-playbook restart-nginx.yml
someone could request:
Restart nginx on the web servers.
The LLM determines what operation the user wants, while Ansible remains responsible for actually executing the infrastructure change.
This distinction is important.
The LLM is the decision/interface layer.
Ansible is the automation/execution layer.
What is OpenAI Function Calling?
Function calling allows an OpenAI model to request the execution of functions that your application makes available to it.
For example, we can define a function called:
run_ansible_playbook()
and describe what it does.
The model can then determine when that function should be used.
Importantly, OpenAI does not directly execute the Ansible playbook.
The flow is:
User request
|
v
OpenAI model
|
| decides a function is required
v
Function call returned to Python
|
v
Python executes the function
|
v
Ansible playbook runs
Your application remains in control of what actually gets executed.
Lab Setup
For this example, assume we have:
AI Server
192.168.1.10
Web Server
192.168.1.20
The AI server has:
- Python
- Ansible
- OpenAI Python SDK
installed.
Install the required Python package:
pip install openai
Install Ansible if required:
sudo dnf install ansible-core
For Ubuntu:
sudo apt install ansible
Step 1: Create the Ansible Inventory
Create:
inventory
Add:
[webservers]
192.168.1.20
You can test connectivity using:
ansible all -i inventory -m ping
You should receive a successful response from the managed server.
Step 2: Create a Simple Ansible Playbook
Create:
restart-nginx.yml
Add:
---
- name: Restart Nginx
hosts: webservers
become: true
tasks:
- name: Restart nginx service
ansible.builtin.service:
name: nginx
state: restarted
Test the playbook before integrating it with AI:
ansible-playbook -i inventory restart-nginx.yml
If this works, our Ansible automation is ready.
Step 3: Create the Python Function
Now we need Python to execute our playbook.
Python's subprocess module can launch the ansible-playbook command.
import subprocess
def run_ansible_playbook():
result = subprocess.run(
[
"ansible-playbook",
"-i",
"inventory",
"restart-nginx.yml"
],
capture_output=True,
text=True
)
return result.stdout
If we call:
run_ansible_playbook()
Python effectively executes:
ansible-playbook -i inventory restart-nginx.yml
At this point we have connected:
Python
|
v
Ansible
|
v
Server
The next step is letting the LLM decide when this function should be called.
Step 4: Define the Function for OpenAI
Create:
app.py
First import the required modules:
from openai import OpenAI
import subprocess
import json
client = OpenAI()
Make sure your OpenAI API key is configured:
export OPENAI_API_KEY="your-api-key"
Now define our Python function:
def run_ansible_playbook():
result = subprocess.run(
[
"ansible-playbook",
"-i",
"inventory",
"restart-nginx.yml"
],
capture_output=True,
text=True
)
return result.stdout
Next, describe the function to the model:
tools = [
{
"type": "function",
"name": "run_ansible_playbook",
"description": "Restart nginx on the web servers using Ansible",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
]
Notice that the model only receives a description of the function.
It does not need to understand the internal Ansible implementation.
Step 5: Send the User Request to OpenAI
Now we can ask the model what action should be performed.
response = client.responses.create(
model="gpt-5-mini",
input="Restart nginx on my web servers",
tools=tools
)
The model examines the request:
Restart nginx on my web servers
It also sees that our application provides:
run_ansible_playbook
with the description:
Restart nginx on the web servers using Ansible
The model can therefore determine that this function should be called.
Step 6: Execute the Function Call
We can check the model's output for a function call.
for item in response.output:
if item.type == "function_call":
if item.name == "run_ansible_playbook":
result = run_ansible_playbook()
print(result)
That's the core of the integration.
The user says:
Restart nginx on my web servers
OpenAI selects:
run_ansible_playbook()
Python then executes:
ansible-playbook -i inventory restart-nginx.yml
And Ansible performs the infrastructure change.
Complete Python Program
Our entire application can remain very small:
from openai import OpenAI
import subprocess
client = OpenAI()
def run_ansible_playbook():
result = subprocess.run(
[
"ansible-playbook",
"-i",
"inventory",
"restart-nginx.yml"
],
capture_output=True,
text=True
)
return result.stdout
tools = [
{
"type": "function",
"name": "run_ansible_playbook",
"description": "Restart nginx on the web servers using Ansible",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
]
user_request = input("What would you like me to do? ")
response = client.responses.create(
model="gpt-5-mini",
input=user_request,
tools=tools
)
for item in response.output:
if item.type == "function_call":
if item.name == "run_ansible_playbook":
result = run_ansible_playbook()
print("\nAnsible Output:\n")
print(result)
Run it:
python app.py
The application asks:
What would you like me to do?
Enter:
Restart nginx on my web servers
The flow becomes:
User
|
| Natural language
v
OpenAI
|
| run_ansible_playbook()
v
Python
|
| subprocess
v
ansible-playbook
|
v
Web Servers
Why Not Let the AI Generate Shell Commands?
You might wonder why we shouldn't simply ask the LLM to generate something like:
systemctl restart nginx
and execute it.
That would be significantly more dangerous.
You don't want arbitrary LLM-generated shell commands being executed on infrastructure.
A safer architecture is to expose a controlled set of operations:
AI
|
+---- restart_web_server()
|
+---- deploy_application()
|
+---- update_packages()
|
+---- collect_server_information()
Each function maps to a predefined Ansible playbook.
For example:
restart_web_server()
|
v
restart-nginx.yml
deploy_application()
|
v
deploy-app.yml
update_packages()
|
v
update-packages.yml
The model chooses from approved automation workflows instead of generating arbitrary infrastructure commands.
Adding Function Parameters
Our first example doesn't require any parameters.
But function calling becomes much more useful when the model can extract information from the user's request.
Suppose the user says:
Restart nginx on server1.
We could expose a function such as:
def restart_service(server, service):
...
The model could extract:
{
"server": "server1",
"service": "nginx"
}
These values could then be passed to Ansible as extra variables:
ansible-playbook restart-service.yml \
-e "target=server1 service=nginx"
The playbook could use:
---
- name: Restart service
hosts: "{{ target }}"
become: true
tasks:
- name: Restart requested service
ansible.builtin.service:
name: "{{ service }}"
state: restarted
This allows one automation workflow to handle multiple requests.
Where This Architecture Becomes Useful
Once the basic pattern works, you can expose multiple Ansible workflows to an AI assistant.
For example:
| User Request | Function | Ansible Playbook |
|---|---|---|
| Restart nginx | restart_nginx() | restart-nginx.yml |
| Update servers | update_servers() | update.yml |
| Deploy application | deploy_app() | deploy.yml |
| Check disk usage | check_disk() | disk-check.yml |
| Create user | create_user() | create-user.yml |
The user doesn't necessarily need to know the playbook names or Ansible syntax.
They simply describe the desired operation.
Read Operations vs Write Operations
When building an AI infrastructure assistant, it is useful to separate operations into two categories.
Read-only operations
Examples:
Check disk usage
Check memory
Check service status
List installed packages
Check uptime
These generally present lower operational risk.
Write operations
Examples:
Restart server
Install package
Delete user
Modify firewall
Deploy application
Reboot server
These modify infrastructure and therefore require stronger controls.
A production implementation might require confirmation:
User:
Restart nginx on all production servers.
AI:
This operation will restart nginx on 12 production servers.
Proceed?
Only after confirmation should the Ansible playbook execute.
Security Considerations
Connecting an LLM to Ansible effectively gives an AI-controlled application access to infrastructure automation.
That means security boundaries are critical.
Avoid architectures where the model can execute arbitrary commands such as:
subprocess.run(ai_generated_command, shell=True)
Instead, expose a small allowlist of predefined functions.
For example:
Allowed:
restart_nginx()
check_disk_usage()
deploy_application()
Rather than:
execute_any_shell_command(command)
You should also consider:
- Ansible Vault for secrets
- Dedicated automation service accounts
- SSH key restrictions
- Least-privilege
sudo - Execution logging
- User authentication
- Approval workflows
- Audit trails
The LLM should decide which approved automation workflow is appropriate, not receive unrestricted access to your infrastructure.
Taking This Further
This simple example can eventually evolve into a complete AI infrastructure operations assistant.
For example:
User
|
v
AI Assistant
|
OpenAI Function Calling
|
+------------+-------------+
| | |
v v v
Ansible Kubernetes Cloud API
| | |
v v v
Servers Clusters AWS
The same function-calling architecture can expose tools for:
- Ansible
- Kubernetes
- AWS
- Terraform
- Git
- Jenkins
- Prometheus
- Grafana
Ansible is particularly useful because many infrastructure operations can already be represented as reusable and auditable playbooks.
Conclusion
OpenAI function calling and Ansible solve two different problems.
OpenAI understands intent.
Ansible performs infrastructure automation.
Combining them creates a simple but powerful architecture:
Natural Language
|
v
LLM
|
v
Function Calling
|
v
Python Function
|
v
Ansible Playbook
|
v
Infrastructure
Instead of giving an LLM unrestricted shell access, we can expose carefully controlled Ansible workflows as functions.
This allows users to interact with infrastructure using natural language while keeping the actual automation deterministic, reusable, and governed by Ansible.
The result is one of the simplest ways to start building an Agentic AI interface for DevOps automation.