Introduction
AI-native software development — where coding, testing, and app building are increasingly AI-led — tops Gartner's 2026 trends. This shifts infrastructure needs: teams need ML CI/CD pipelines, model registries, experiment tracking, feature stores, and LLM evaluation frameworks. Ansible automates the entire MLOps platform stack.
MLOps Platform Stack
| Component | Tool | Purpose |
|---|---|---|
| Experiment Tracking | MLflow, W&B | Track runs, metrics, artifacts |
| Model Registry | MLflow, DVC | Version and stage models |
| Feature Store | Feast, Hopsworks | Serve ML features |
| Pipeline Orchestration | Airflow, Prefect | Schedule training jobs |
| Model Serving | Triton, BentoML | Serve predictions |
| Monitoring | Evidently, Whylogs | Detect data/model drift |
Deploy MLflow (Experiment Tracking + Registry)
---
- name: Deploy MLflow platform
hosts: mlops_servers
become: true
vars:
mlflow_port: 5000
artifact_store: /opt/mlflow/artifacts
db_uri: "postgresql://mlflow:{{ vault_db_password }}@localhost:5432/mlflow"
tasks:
- name: Install MLflow
ansible.builtin.pip:
name:
- mlflow[extras]
- psycopg2-binary
- boto3
virtualenv: /opt/mlflow/venv
- name: Create artifact store
ansible.builtin.file:
path: "{{ artifact_store }}"
state: directory
owner: mlflow
mode: "0755"
- name: Create MLflow database
community.postgresql.postgresql_db:
name: mlflow
state: present
- name: Create MLflow database user
community.postgresql.postgresql_user:
name: mlflow
password: "{{ vault_db_password }}"
db: mlflow
priv: ALL
no_log: true
- name: Deploy MLflow systemd service
ansible.builtin.copy:
content: |
[Unit]
Description=MLflow Tracking Server
After=network.target postgresql.service
[Service]
Type=simple
User=mlflow
ExecStart=/opt/mlflow/venv/bin/mlflow server \
--backend-store-uri {{ db_uri }} \
--default-artifact-root {{ artifact_store }} \
--host 0.0.0.0 \
--port {{ mlflow_port }}
Restart=always
Environment=MLFLOW_TRACKING_URI=http://0.0.0.0:{{ mlflow_port }}
[Install]
WantedBy=multi-user.target
dest: /etc/systemd/system/mlflow.service
notify:
- Reload systemd
- Restart MLflow
- name: Start MLflow
ansible.builtin.service:
name: mlflow
state: started
enabled: true
- name: Verify MLflow is running
ansible.builtin.uri:
url: "http://localhost:{{ mlflow_port }}/api/2.0/mlflow/experiments/search"
method: POST
body_format: json
body: {}
register: mlflow_check
handlers:
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Restart MLflow
ansible.builtin.service:
name: mlflow
state: restarted
Deploy Feature Store (Feast)
- name: Deploy Feast feature store
hosts: feature_store
become: true
tasks:
- name: Install Feast
ansible.builtin.pip:
name:
- feast[redis,postgres]
virtualenv: /opt/feast/venv
- name: Deploy feature repository
ansible.builtin.git:
repo: "{{ feature_repo_url }}"
dest: /opt/feast/repo
version: main
- name: Deploy Redis for online store
community.docker.docker_container:
name: feast-redis
image: redis:7-alpine
state: started
restart_policy: unless-stopped
ports: ["6379:6379"]
- name: Configure feature store
ansible.builtin.template:
src: feature_store.yaml.j2
dest: /opt/feast/repo/feature_store.yaml
- name: Apply feature definitions
ansible.builtin.command:
cmd: /opt/feast/venv/bin/feast apply
chdir: /opt/feast/repo
register: feast_apply
changed_when: "'Created' in feast_apply.stdout or 'Updated' in feast_apply.stdout"
- name: Deploy feature serving service
ansible.builtin.copy:
content: |
[Unit]
Description=Feast Feature Server
After=network.target redis.service
[Service]
Type=simple
User=feast
WorkingDirectory=/opt/feast/repo
ExecStart=/opt/feast/venv/bin/feast serve --host 0.0.0.0 --port 6566
Restart=always
[Install]
WantedBy=multi-user.target
dest: /etc/systemd/system/feast-server.service
notify: Restart Feast
ML CI/CD Pipeline
- name: Deploy ML CI/CD infrastructure
hosts: cicd_servers
become: true
tasks:
- name: Deploy Airflow for pipeline orchestration
community.docker.docker_compose_v2:
project_src: /opt/airflow
state: present
vars:
compose_file: |
services:
webserver:
image: apache/airflow:2.9.0
ports: ["8080:8080"]
volumes:
- /opt/airflow/dags:/opt/airflow/dags
environment:
AIRFLOW__CORE__EXECUTOR: LocalExecutor
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: "{{ vault_airflow_db }}"
- name: Deploy ML pipeline DAGs
ansible.builtin.template:
src: "dags/{{ item }}.py.j2"
dest: "/opt/airflow/dags/{{ item }}.py"
loop:
- training_pipeline
- evaluation_pipeline
- deployment_pipeline
- data_validation
- name: Deploy model evaluation framework
ansible.builtin.pip:
name:
- deepeval
- ragas
- promptfoo
virtualenv: /opt/ml-eval/venv
- name: Deploy LLM evaluation config
ansible.builtin.template:
src: eval-config.yml.j2
dest: /opt/ml-eval/config.yml
- name: Schedule automated model evaluation
ansible.builtin.cron:
name: "Daily model evaluation"
hour: "6"
minute: "0"
job: >
cd /opt/ml-eval &&
venv/bin/python run_eval.py --config config.yml
>> /var/log/ml-eval.log 2>&1
Model Drift Monitoring
- name: Deploy model drift monitoring
hosts: monitoring
become: true
tasks:
- name: Deploy Evidently for drift detection
community.docker.docker_container:
name: evidently
image: evidentlyai/evidently-service:latest
state: started
ports: ["8085:8080"]
volumes:
- /opt/evidently/config:/config
- name: Configure drift monitoring
ansible.builtin.template:
src: drift-config.yml.j2
dest: /opt/evidently/config/monitoring.yml
- name: Deploy drift alert rules
ansible.builtin.template:
src: drift-alerts.yml.j2
dest: /etc/prometheus/rules/drift-alerts.yml
notify: Reload Prometheus
{# templates/drift-alerts.yml.j2 #}
groups:
- name: model_drift
rules:
- alert: DataDriftDetected
expr: evidently_data_drift_score > 0.3
for: 1h
labels: { severity: warning }
annotations:
summary: "Data drift detected in {{ $labels.model }} (score: {{ $value }})"
- alert: PredictionDriftDetected
expr: evidently_prediction_drift_score > 0.2
for: 30m
labels: { severity: critical }
annotations:
summary: "Prediction drift in {{ $labels.model }} — retrain needed"
Complete MLOps Playbook
---
# site.yml — Full MLOps platform
- import_playbook: playbooks/mlflow.yml # Experiment tracking
- import_playbook: playbooks/feature-store.yml # Feature serving
- import_playbook: playbooks/pipelines.yml # CI/CD orchestration
- import_playbook: playbooks/model-serving.yml # Inference
- import_playbook: playbooks/monitoring.yml # Drift detection
# Deploy full MLOps stack
ansible-playbook site.yml -e @vars/production.yml
# Update just pipelines
ansible-playbook playbooks/pipelines.yml --tags dags
# Deploy new model version
ansible-playbook playbooks/model-serving.yml -e "model_version=v2.3.0"
Related Articles
Conclusion
AI-native development in 2026 requires MLOps infrastructure that's as mature as traditional DevOps. Ansible automates the entire platform: MLflow for experiment tracking and model registry, Feast for feature stores, Airflow for pipeline orchestration, Evidently for drift monitoring, and evaluation frameworks for LLM quality. The pattern: each MLOps component is a deployable service managed by Ansible roles, composed into a full platform with a single site.yml. As AI becomes the default way to build software, this infrastructure automation is table stakes.