7.8 KiB
7.8 KiB
description, argument-hint
| description | argument-hint |
|---|---|
| Develop Ansible roles and playbooks | Optional role or playbook requirements |
Ansible Development
You are developing Ansible automation (roles, playbooks, tasks, handlers) using the ansible-developer agent.
Workflow
1. Identify Development Type
Determine what to develop:
- New role: Complete role with tasks, handlers, defaults
- New playbook: Standalone playbook or site playbook
- Task enhancement: Add/modify tasks in existing role
- Handler creation: Create service handlers
- Variable management: Define defaults and vars
- Module development: Custom Ansible modules
2. Gather Requirements
If not specified, ask for:
For Roles:
- Role name and purpose
- Target systems (OS, distributions)
- Dependencies (packages, services, other roles)
- Configuration files needed
- Variables and their defaults
- Handlers required (restarts, reloads)
- Tags for selective execution
For Playbooks:
- Playbook purpose (deploy, configure, maintain)
- Target host groups
- Roles to include
- Pre-tasks and post-tasks
- Variables needed
- Execution order
For Tasks:
- What the task should accomplish
- Modules to use (package, service, template, etc.)
- Idempotency requirements
- Error handling needs
- Conditionals (OS-specific, etc.)
3. Launch Development Agent
Launch ansible-developer with complete requirements:
"Create Ansible role named [role-name] that [purpose].
Target systems: [OS/distro]
Requirements:
- Install and configure [software]
- Manage [service] with handlers
- Template [config-files]
- Variables: [list with defaults]
- Support check mode
- Include example playbook"
4. Review Generated Code
Check the developed automation for:
- Idempotency: All tasks can run multiple times safely
- Module usage: Proper Ansible modules (not shell when module exists)
- Task naming: Descriptive names starting with verbs
- Variables: Proper namespacing (role_name_variable)
- Handlers: Appropriate handler usage
- Error handling: Block/rescue where needed
- Check mode: Support for
--checkflag - Tags: Meaningful tags for selective execution
5. Test Development
Run validation commands:
# Syntax check
ansible-playbook playbooks/test.yml --syntax-check
# Lint check
ansible-lint roles/[role-name]/
# Check mode (dry run)
ansible-playbook playbooks/test.yml --check
# Run on test environment
ansible-playbook playbooks/test.yml -i inventory/development
# Run specific tags
ansible-playbook playbooks/test.yml --tags "install,config"
# Verbose output for debugging
ansible-playbook playbooks/test.yml -vv
6. Iterate if Needed
If issues found:
- Launch ansible-code-reviewer to identify problems
- Fix issues with ansible-developer
- Re-test until all checks pass
Common Development Patterns
Creating a Role
Example: Web Server Role
# roles/nginx/tasks/main.yml
---
- name: Ensure Nginx is installed
ansible.builtin.package:
name: nginx
state: present
tags: install
- name: Ensure Nginx configuration directory exists
ansible.builtin.file:
path: /etc/nginx/sites-available
state: directory
owner: root
group: root
mode: '0755'
tags: config
- name: Template Nginx main configuration
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
validate: nginx -t -c %s
backup: yes
notify: Reload nginx
tags: config
- name: Ensure Nginx is started and enabled
ansible.builtin.service:
name: nginx
state: started
enabled: yes
tags: service
Handlers:
# roles/nginx/handlers/main.yml
---
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Defaults:
# roles/nginx/defaults/main.yml
---
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_user: www-data
nginx_keepalive_timeout: 65
nginx_server_names_hash_bucket_size: 64
Creating a Playbook
Example: Site Deployment Playbook
---
- name: Deploy web application
hosts: webservers
become: yes
gather_facts: yes
vars:
app_version: "1.0.0"
deployment_user: deploy
pre_tasks:
- name: Update package cache
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
tags: always
- name: Verify deployment user exists
ansible.builtin.user:
name: "{{ deployment_user }}"
state: present
tags: always
roles:
- role: common
tags: common
- role: nginx
tags: nginx
- role: application
tags: app
tasks:
- name: Deploy application version {{ app_version }}
ansible.builtin.copy:
src: "app-{{ app_version }}.tar.gz"
dest: "/opt/app/"
owner: "{{ deployment_user }}"
group: "{{ deployment_user }}"
mode: '0644'
tags: deploy
- name: Extract application
ansible.builtin.unarchive:
src: "/opt/app/app-{{ app_version }}.tar.gz"
dest: "/opt/app/"
remote_src: yes
owner: "{{ deployment_user }}"
group: "{{ deployment_user }}"
tags: deploy
post_tasks:
- name: Verify application is accessible
ansible.builtin.uri:
url: "http://{{ ansible_default_ipv4.address }}/"
status_code: 200
tags: verify
- name: Log deployment
ansible.builtin.lineinfile:
path: /var/log/deployments.log
line: "{{ ansible_date_time.iso8601 }} - Deployed {{ app_version }}"
create: yes
tags: always
Output Format
Development Summary
Created: [role-name / playbook-name] Purpose: [description] Files Generated:
✓ tasks/main.yml - Main task list
✓ handlers/main.yml - Service handlers
✓ defaults/main.yml - Default variables
✓ templates/ - Configuration templates
✓ README.md - Role documentation
Usage Instructions
Install role:
# If using Galaxy
ansible-galaxy install [role-name]
# Local role (no action needed)
Run playbook:
# Syntax check
ansible-playbook playbook.yml --syntax-check
# Dry run
ansible-playbook playbook.yml --check
# Execute
ansible-playbook playbook.yml -i inventory/production
# Specific tags
ansible-playbook playbook.yml --tags "install,config"
# Limit to hosts
ansible-playbook playbook.yml --limit "web01,web02"
Testing Commands
# Lint check
ansible-lint roles/[role-name]/
# Test with Molecule
cd roles/[role-name]
molecule test
# Manual test
ansible-playbook tests/test.yml -i tests/inventory
Best Practices
Idempotency:
- Use proper Ansible modules (not shell/command when module exists)
- Always set
changed_whenfor command/shell tasks - Use state management (present/absent, started/stopped)
Task Naming:
- Start with verb (Ensure, Configure, Install, Copy, etc.)
- Be specific about what task does
- Use sentence case consistently
Variables:
- Namespace with role name:
nginx_port,app_user - Provide sensible defaults in
defaults/main.yml - Document all variables in README
Error Handling:
- Use
failed_whento define failure conditions - Use
block/rescuefor rollback capability - Validate before destructive operations
Templates:
- Add
{{ ansible_managed }}header - Use validate parameter when possible
- Always backup with
backup: yes
Handlers:
- One handler per service action
- Use notify instead of direct service restarts
- Name handlers clearly (Restart nginx, Reload postgresql)
Tags:
- Add meaningful tags to tasks
- Use common tags (install, config, service)
- Allow selective execution
Testing:
- Always support check mode
- Test on multiple OS if targeting multiple platforms
- Use Molecule for automated testing
- Include example playbook in role