AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Can AI Generate Safe Ansible Playbooks? Risks, Limits, and Best Practices

By Luca Berton · Published 2024-01-01 · Category: installation

Can AI generate safe Ansible playbooks? Analysis of real AI-generated playbook failures, security risks, idempotency gaps, and a practical review checklist.

AI can generate Ansible playbooks that look correct, pass syntax checks, and still break your infrastructure. This article shows real examples of what AI gets wrong and how to catch it before production.

The Short Answer

AI generates structurally valid playbooks that are functionally incomplete. They'll parse, they'll run, and they'll miss the edge cases that matter.

See also: How AI Is Changing Ansible Automation in 2026

What AI Gets Right (80%)

AI models are trained on thousands of Ansible examples. They excel at:

# ✅ Standard install + configure patterns
- name: Install and configure nginx
  hosts: webservers
  become: true
  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true

- name: Deploy nginx config ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: reload nginx

- name: Ensure nginx is running ansible.builtin.systemd: name: nginx state: started enabled: true

handlers: - name: reload nginx ansible.builtin.systemd: name: nginx state: reloaded

This is fine. Standard pattern, correct modules, proper handler usage.

What AI Gets Wrong (The Dangerous 20%)

Problem 1: Missing no_log for Secrets

# AI generates:
- name: Set database password
  ansible.builtin.shell: |
    mysql -u root -p{{ db_root_password }} -e "ALTER USER 'app'@'%' IDENTIFIED BY '{{ db_app_password }}';"

# ❌ Issues: # 1. Password visible in logs (no no_log: true) # 2. Password in command line (visible in ps) # 3. shell module instead of mysql_user module # 4. Not idempotent

# ✅ What a human writes: - name: Set database password community.mysql.mysql_user: name: app host: '%' password: "{{ db_app_password }}" state: present login_unix_socket: /var/run/mysqld/mysqld.sock no_log: true

Problem 2: Non-Idempotent Operations

# AI generates:
- name: Add repository
  ansible.builtin.shell: |
    echo "deb https://repo.example.com stable main" >> /etc/apt/sources.list

# ❌ Appends duplicate lines every run

# ✅ Fix: - name: Add repository ansible.builtin.apt_repository: repo: "deb https://repo.example.com stable main" state: present

Problem 3: Privilege Escalation Oversights

# AI generates:
- name: Secure SSH config
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    line: 'PermitRootLogin no'
  # ❌ Missing become: true — will fail with permission denied

# AI also sometimes generates: - name: Install packages ansible.builtin.apt: name: "{{ packages }}" become: true # Then later: - name: Deploy user config ansible.builtin.copy: src: config dest: /home/deploy/.config become: true # ❌ Creates file owned by root in user's home directory # Need: become_user: deploy, or don't use become

Problem 4: Shell Injection Vulnerabilities

# AI generates:
- name: Create backup
  ansible.builtin.shell: "tar czf /backups/{{ backup_name }}.tar.gz {{ backup_path }}"
  # ❌ If backup_name or backup_path contain shell metacharacters → injection

# ✅ Fix: Use command module or validate input - name: Create backup ansible.builtin.command: cmd: "tar czf /backups/{{ backup_name }}.tar.gz {{ backup_path }}" args: creates: "/backups/{{ backup_name }}.tar.gz" # command module doesn't interpret shell metacharacters

Problem 5: Missing Error Handling

# AI generates a deploy playbook:
- name: Stop application
  ansible.builtin.systemd:
    name: myapp
    state: stopped

- name: Deploy new version ansible.builtin.copy: src: "{{ new_version }}.tar.gz" dest: /opt/myapp/

- name: Start application ansible.builtin.systemd: name: myapp state: started

# ❌ If deploy fails, app stays stopped forever

# ✅ Fix: Use block/rescue/always - name: Deploy with rollback block: - name: Stop application ansible.builtin.systemd: name: myapp state: stopped

- name: Deploy new version ansible.builtin.copy: src: "{{ new_version }}.tar.gz" dest: /opt/myapp/ rescue: - name: Deploy failed — restore previous version ansible.builtin.copy: src: /opt/myapp/backup/ dest: /opt/myapp/current/ always: - name: Ensure application is running ansible.builtin.systemd: name: myapp state: started

Problem 6: Deprecated Patterns

# AI generates (from training data):
- name: Install packages
  apt: name={{ item }} state=present
  with_items:
    - nginx
    - postgresql

# ❌ Uses: # - short module name (not FQCN) # - free-form syntax # - deprecated with_items

# ✅ Modern equivalent: - name: Install packages ansible.builtin.apt: name: - nginx - postgresql state: present

See also: Ansible for AI Security: Protect Models, APIs & Data Pipelines (2026 Guide)

The AI Playbook Review Checklist

Run through this for every AI-generated playbook:

## Security
- [ ] All tasks with passwords/tokens have `no_log: true`
- [ ] No credentials in shell/command arguments
- [ ] File permissions are restrictive (not 777/666)
- [ ] `become: true` only where needed, not globally
- [ ] No unnecessary shell modules (use purpose-built modules)

## Idempotency - [ ] Run playbook twice — second run shows changed=0 - [ ] No raw `echo >>` or `cat >>` (use lineinfile/blockinfile) - [ ] shell/command tasks have creates/changed_when - [ ] No `state: latest` without good reason

## Error Handling - [ ] Critical operations wrapped in block/rescue - [ ] Services restarted in `always:` block after changes - [ ] `failed_when` set for commands with non-standard exit codes

## Best Practices - [ ] FQCNs used (ansible.builtin.*, community.*) - [ ] `loop:` instead of `with_items:` - [ ] YAML syntax (not free-form `key=value`) - [ ] Handlers for service restarts (not direct restart tasks) - [ ] ansible-lint passes with no errors

AI Tool Comparison for Ansible

| Tool | Quality | Context | Best For | |------|---------|---------|----------| | Ansible Lightspeed | High | Ansible-specific | Task generation, role scaffolding | | GitHub Copilot | Medium-High | File context | Completing patterns in existing code | | ChatGPT/Claude | Medium | Conversation | Explaining concepts, troubleshooting | | Cursor/Windsurf | Medium-High | Project context | Multi-file role development |

See also: Ansible for Digital Provenance: Content Authenticity & AI Watermarking (2026 Guide)

FAQ

Should I trust AI-generated playbooks for production?

Never without review. AI-generated playbooks should go through the same review process as human-written code: code review, ansible-lint, Molecule testing, and staging deployment before production.

Which AI tool is best for Ansible?

Ansible Lightspeed for inline generation (trained specifically on Ansible). GitHub Copilot for general completion. ChatGPT/Claude for explaining errors and learning. Use them in combination.

How do I improve AI output quality?

Write clear task names (AI uses them as context), use FQCN module names, maintain consistent style in your codebase (AI learns from nearby code), and always specify the Ansible version you're targeting.

Will AI-generated playbooks pass ansible-lint?

Usually not on the first try. Common failures: missing FQCNs, deprecated syntax, unnecessary shell usage, missing changed_when. Always run ansible-lint as a post-generation step.

Conclusion

AI generates the 80% of playbook code that's tedious but straightforward. The 20% it misses — security, idempotency, error handling, edge cases — is exactly the 20% that breaks production. Use AI for first drafts, your expertise for the review, and the checklist above to bridge the gap.

Related Articles

How AI Is Changing Ansible Automation in 2026Ansible MCP Integration GuideHow to Make Playbooks IdempotentAnsible Lint: Analyze & Fix Playbooks

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home