Skip to main content
In this lesson we use ChatGPT as a co-pilot to rapidly scaffold, validate, and iterate an idempotent Ansible playbook. The goal: produce a reusable playbook that installs Apache (httpd) on RHEL hosts, deploys a Jinja2 template for the site, and restarts httpd only when changes occur. Scenario: your DevOps team repeatedly performs manual steps on demo RHEL machines—installing httpd, starting the service, and copying a static test page. We’ll automate that workflow by generating a baseline playbook and template with ChatGPT, validating them in VS Code, iterating on lint/validation feedback, and finally running the playbook on the target host.
The slide titled "Manual Web Demo Setup" shows a DevOps Engineer icon on the left, a central graphic labeled "RHEL machines," and three right-side steps: "Install Apache," "Start service," and "Copy Test Page." It outlines the manual steps for setting up a web demo on RHEL servers.
Overview — workflow
  • Ask ChatGPT to create a playbook (site.yml) that installs httpd and deploys a Jinja2 template.
  • Paste the playbook into VS Code.
  • Ask ChatGPT to generate the Jinja2 template file (index.html.j2).
  • Validate files in VS Code using the Ansible extension and ansible-lint.
  • If there are lint or validation issues, iterate by giving the errors back to ChatGPT.
  • Once the base version is working, extend the playbook (for example, add an idempotent footer append).
  • Run the playbook and confirm the results on the demo server.
A dark-themed presentation slide titled "Demo" showing six numbered steps. The steps describe using ChatGPT and VS Code to generate site.yml and an index.html.j2 template, validate and fix files, extend a playbook to append a line to the HTML, and test the playbook.
Step-by-step walkthrough
  1. Environment setup
  • Create a working directory and change into it:
  • Create a simple inventory file named inventory with a group webservers:
  • Create ansible.cfg that points to the local inventory and configures privilege escalation:
  1. Generate the initial playbook with ChatGPT
  • Prompt example used:
    “As a DevOps engineer, create an Ansible playbook called site.yml for RHEL-based hosts in the group webservers that installs httpd, deploys a Jinja2 template named index.html.j2 to /var/www/html/index.html, enables and starts the httpd service, uses handlers, and keeps tasks idempotent.”
  • After getting the reply, paste it into VS Code and make lint-friendly corrections:
    • Use fully-qualified collection names (ansible.builtin.<module>) to satisfy ansible-lint fqcn checks.
    • Use lowercase true/false YAML booleans for compatibility with YAML linters.
    • Ensure gather_facts: true when the template uses facts like ansible_fqdn.
Clean, lint-friendly playbook:
Tips:
  • Always prefer FQCNs like ansible.builtin.template to avoid collection ambiguity and satisfy ansible-lint rules.
  • Keep gather_facts: true when templates reference facts such as ansible_fqdn.
  1. Create the Jinja2 template
  • Request ChatGPT to create index.html.j2 with a friendly message. Example template:
Ensure the file ends with a newline to avoid subtle template issues.
  1. Validate and run the playbook
Some lint messages are recommendations (deprecations, style). Address critical errors first; non-blocking warnings can be deferred while iterating with ChatGPT.
  • Run the playbook:
Expected behavior:
  • Install/template/start tasks report changed/ok as appropriate.
  • Handlers run only when a task notifies them (i.e., only on change).
Example abbreviated output:
  1. Verify on the target
  • SSH to the target and curl the local site:
  1. Extend the playbook — append a footer line idempotently
  • To demonstrate iterative improvements, add a lineinfile task that appends one footer line to /var/www/html/index.html only if it does not already exist. Place this task after the template task so it operates on the deployed file.
Suggested task:
Concise full playbook including the appended task:
  1. Re-run the playbook and confirm idempotence
  • Run again:
Expected pattern:
  • First run: template and lineinfile may be “changed” and will trigger the handler.
  • Subsequent runs: lineinfile reports ok (no change) if the footer already exists, and the handler will not run because no task reported changed.
Final verification:
Quick reference — mapping tasks to modules Wrapping up — best practices
  • Use ChatGPT to scaffold and iterate quickly; always validate generated content with linters and human review before running in production.
  • Keep tasks idempotent (use modules like template and lineinfile rather than raw shell append).
  • Use handlers to restart services only when necessary, preventing needless restarts.
  • Fix lint errors progressively—feed the specific messages back to ChatGPT for faster iteration.
Links and references You now have a repeatable pattern: generate → validate → iterate → run — using ChatGPT and VS Code to produce predictable, idempotent Ansible automation.

Watch Video