Initial commit
This commit is contained in:
348
commands/develop-ansible.md
Normal file
348
commands/develop-ansible.md
Normal file
@@ -0,0 +1,348 @@
|
||||
---
|
||||
description: Develop Ansible roles and playbooks
|
||||
argument-hint: 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 `--check` flag
|
||||
- **Tags**: Meaningful tags for selective execution
|
||||
|
||||
### 5. Test Development
|
||||
|
||||
Run validation commands:
|
||||
|
||||
```bash
|
||||
# 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**
|
||||
|
||||
```yaml
|
||||
# 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**:
|
||||
```yaml
|
||||
# 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**:
|
||||
```yaml
|
||||
# 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**
|
||||
|
||||
```yaml
|
||||
---
|
||||
- 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**:
|
||||
```bash
|
||||
# If using Galaxy
|
||||
ansible-galaxy install [role-name]
|
||||
|
||||
# Local role (no action needed)
|
||||
```
|
||||
|
||||
**Run playbook**:
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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_when` for 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_when` to define failure conditions
|
||||
- Use `block/rescue` for 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
|
||||
Reference in New Issue
Block a user