# Configuration Editor

Source: https://docs.ops0.com/docs/configurations/editor

Create and edit Ansible playbooks or Kubernetes manifests with AI assistance.

## Editor Panels

File Explorer

Left - Browse files

Code Editor

Center - Edit code

AI Chat

Right - Create configs

## Toolbar Actions

| Button | Description |
|--------|-------------|
| **Send to Chat** | Send selected code to AI |
| **Validate** | Check syntax |
| **Deploy** | Deploy to target |
| **History** | View past deployments |
| **GitHub** | Sync with repository |

## File Structures

Ansible

site.yml

inventory/hosts.ini

roles/webserver/tasks/

vars/main.yml

Kubernetes

namespace.yml

deployment.yml

service.yml

configmap.yml

## Example Playbook

```yaml
- name: Configure web server
  hosts: webservers
  become: yes

  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present

    - name: Start nginx
      service:
        name: nginx
        state: started
        enabled: yes
```

## Example Manifest

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    spec:
      containers:
        - name: app
          image: my-app:latest
          ports:
            - containerPort: 8080
```

## Using AI Chat

Ansible Example

"Install and configure PostgreSQL 15 with a database called myapp"

Kubernetes Example

"Create a deployment for Node.js with 3 replicas, service on port 80, and HPA"

## AI Chat History

The AI chat panel preserves the full conversation history for each project. This means you can:

- Continue a conversation from a previous session — the AI remembers the context of what was already built
- Ask follow-up questions referencing earlier decisions ("change the nginx port from 8080 to 80")
- Review the history of what the AI generated and why

Each message is stored as part of the project's configuration messages, separate from the file contents.

### Incremental Edits

When you ask the AI to modify existing files, it sends targeted patches rather than rewriting the full file. This keeps changes reviewable and avoids accidentally overwriting unrelated sections. The patch format shows exactly which lines are being changed before the edit is applied to the editor.

---

## Variables

Regular Variables

Define in `vars/main.yml`, use as `{{ var_name }}`

Sensitive Variables

Add in project Settings, mark as Sensitive

## Validation

| Type | What It Checks |
|------|----------------|
| **Ansible** | ansible-lint, syntax check |
| **Kubernetes** | YAML syntax, K8s API compatibility |

Tips

• Changes auto-save after 2 seconds

• Press `Ctrl/Cmd + S` to save immediately

• Use Jinja2 templates (`.j2`) for dynamic configs

• ops0 auto-creates inventory from your target selection

---

## Example: Building an Ansible Playbook with AI

### Conversation

**You:** Install and configure nginx with SSL using Let's Encrypt, enable gzip compression, and add basic security headers

**AI:** I'll create a complete nginx setup with SSL, compression, and security. Here's what I'm setting up:

- Nginx installation via apt
- Let's Encrypt certificate using certbot
- Gzip compression for common file types
- Security headers (X-Frame-Options, X-Content-Type-Options, etc.)
- Auto-renewal cron job

### Produced Files

**site.yml**
```yaml
---
- name: Configure secure nginx web server
  hosts: webservers
  become: yes
  vars_files:
    - vars/main.yml

  roles:
    - nginx
    - certbot
```

**roles/nginx/tasks/main.yml**
```yaml
---
- name: Install nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: Copy nginx configuration
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    validate: nginx -t -c %s
  notify: Reload nginx

- name: Copy site configuration
  template:
    src: site.conf.j2
    dest: /etc/nginx/sites-available/{{ domain }}
  notify: Reload nginx

- name: Enable site
  file:
    src: /etc/nginx/sites-available/{{ domain }}
    dest: /etc/nginx/sites-enabled/{{ domain }}
    state: link
  notify: Reload nginx

- name: Start nginx
  service:
    name: nginx
    state: started
    enabled: yes
```

**roles/nginx/templates/site.conf.j2**
```nginx
server {
    listen 443 ssl http2;
    server_name {{ domain }};

    ssl_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000" always;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    gzip_min_length 1000;

    location / {
        root /var/www/{{ domain }};
        index index.html;
    }
}

server {
    listen 80;
    server_name {{ domain }};
    return 301 https://$server_name$request_uri;
}
```

**vars/main.yml**
```yaml
---
domain: example.com
letsencrypt_email: admin@example.com
```

---

## Example: Building Kubernetes Manifests with AI

### Conversation

**You:** Create a Node.js deployment with 3 replicas, service on port 80, HPA scaling 3-10 based on CPU, and readiness/liveness probes

**AI:** I'll create a production-ready Node.js deployment with autoscaling and health checks.

### Produced Files

**deployment.yml**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-app
  labels:
    app: nodejs-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nodejs-app
  template:
    metadata:
      labels:
        app: nodejs-app
    spec:
      containers:
        - name: nodejs
          image: nodejs-app:1.0.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 15
            periodSeconds: 20
          env:
            - name: NODE_ENV
              value: "production"
```

**service.yml**
```yaml
apiVersion: v1
kind: Service
metadata:
  name: nodejs-app
spec:
  selector:
    app: nodejs-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: ClusterIP
```

**hpa.yml**
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nodejs-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nodejs-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
```
