Files
gh-phaezer-claude-mkt-plugi…/commands/ansible-project-init.md
2025-11-30 08:47:10 +08:00

18 KiB

description, argument-hint
description argument-hint
Initialize new Ansible project structure Optional project requirements

Ansible Project Initialization

You are setting up a new Ansible project with proper structure, configuration, and best practices using the ansible-developer agent.

Workflow

1. Gather Project Requirements

If not specified, ask for:

  • Project information:
    • Project name and purpose
    • Team or organization name
    • Git repository location
  • Target infrastructure:
    • Target platforms (Linux, Windows, network devices)
    • Number of environments (dev, staging, production)
    • Approximate number of hosts per environment
  • Initial roles needed:
    • Application roles (web server, database, app)
    • Infrastructure roles (common, security, monitoring)
    • Third-party roles to include
  • Security setup:
    • Ansible Vault for secrets (yes/no)
    • Vault password file location or method
    • Separate vaults per environment
  • Testing setup:
    • Include Molecule testing (yes/no)
    • Testing platforms (Docker, Vagrant, cloud)
    • CI/CD integration planned
  • Standards and requirements:
    • ansible-lint configuration
    • Pre-commit hooks
    • Documentation requirements

2. Create Directory Structure

Launch ansible-developer to create standard Ansible project structure:

project-name/
├── ansible.cfg                 # Ansible configuration
├── .gitignore                  # Git ignore patterns
├── .ansible-lint              # Lint configuration
├── README.md                   # Project documentation
├── requirements.yml            # Galaxy role dependencies
├── requirements.txt            # Python dependencies
│
├── inventory/
│   ├── production/
│   │   ├── hosts.yml          # Production inventory
│   │   └── group_vars/
│   │       └── all/
│   │           ├── vars.yml   # Production variables
│   │           └── vault.yml  # Encrypted secrets
│   ├── staging/
│   │   ├── hosts.yml
│   │   └── group_vars/
│   └── development/
│       ├── hosts.yml
│       └── group_vars/
│
├── roles/
│   ├── common/                # Common role
│   │   ├── README.md
│   │   ├── defaults/main.yml
│   │   ├── handlers/main.yml
│   │   ├── tasks/main.yml
│   │   ├── templates/
│   │   ├── files/
│   │   └── vars/main.yml
│   └── .gitkeep
│
├── playbooks/
│   ├── site.yml               # Master playbook
│   ├── provision.yml          # Provisioning playbook
│   ├── deploy.yml             # Deployment playbook
│   └── maintenance.yml        # Maintenance playbook
│
├── group_vars/
│   └── all.yml                # Global variables
│
├── host_vars/                 # Host-specific variables
│   └── .gitkeep
│
├── files/                     # Static files
│   └── .gitkeep
│
├── templates/                 # Global templates
│   └── .gitkeep
│
├── filter_plugins/            # Custom filters
│   └── .gitkeep
│
├── library/                   # Custom modules
│   └── .gitkeep
│
└── molecule/                  # Testing (optional)
    └── default/
        ├── molecule.yml
        ├── converge.yml
        └── verify.yml

3. Configure ansible.cfg

Create optimized ansible.cfg:

[defaults]
# Inventory
inventory = ./inventory/development

# Connection
host_key_checking = False
timeout = 30
forks = 20

# Output
stdout_callback = yaml
callbacks_enabled = profile_tasks, timer
display_skipped_hosts = False

# Roles
roles_path = ./roles:~/.ansible/roles:/usr/share/ansible/roles

# Collections
collections_paths = ./collections:~/.ansible/collections:/usr/share/ansible/collections

# Logs
log_path = ./ansible.log

# Vault
vault_password_file = ./.vault-pass  # Do not commit this file!

# Retry
retry_files_enabled = False

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False

[ssh_connection]
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
ssh_args = -o ControlMaster=auto -o ControlPersist=60s

[inventory]
enable_plugins = yaml, ini, script

4. Create .gitignore

Protect sensitive files:

# Ansible
*.retry
.ansible/
.vault-pass
vault-pass.txt
*.secret
*.key

# Logs
*.log
ansible.log

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
venv/
env/
ENV/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Molecule
.molecule/
.cache/

# Terraform (if using)
*.tfstate
*.tfstate.backup
.terraform/

5. Setup Ansible Vault

If vault enabled:

# Create vault password file (DO NOT COMMIT)
echo "your-secure-password" > .vault-pass
chmod 600 .vault-pass

# Create encrypted vault files for each environment
ansible-vault create inventory/production/group_vars/all/vault.yml
ansible-vault create inventory/staging/group_vars/all/vault.yml
ansible-vault create inventory/development/group_vars/all/vault.yml

Vault file template:

---
# Encrypted secrets for [environment]

# Database credentials
vault_db_root_password: "changeme"
vault_db_user_password: "changeme"

# API keys
vault_api_key: "changeme"

# SSH keys
vault_deploy_key: |
  -----BEGIN OPENSSH PRIVATE KEY-----
  ...
  -----END OPENSSH PRIVATE KEY-----

# SSL certificates
vault_ssl_key: |
  -----BEGIN PRIVATE KEY-----
  ...
  -----END PRIVATE KEY-----

6. Create requirements.yml

Define Galaxy role dependencies:

---
# Ansible Galaxy roles

roles:
  # Community roles
  - name: geerlingguy.docker
    version: "6.1.0"

  - name: geerlingguy.nginx
    version: "3.1.4"

collections:
  # Community collections
  - name: community.general
    version: ">=7.0.0"

  - name: ansible.posix
    version: ">=1.5.0"

  - name: community.postgresql
    version: ">=3.0.0"

Install dependencies:

ansible-galaxy install -r requirements.yml

7. Create Example Inventory

inventory/development/hosts.yml:

---
all:
  children:
    webservers:
      hosts:
        web01:
          ansible_host: 192.168.1.10
          ansible_user: ansible
        web02:
          ansible_host: 192.168.1.11
          ansible_user: ansible
      vars:
        nginx_port: 80
        app_environment: development

    databases:
      hosts:
        db01:
          ansible_host: 192.168.1.20
          ansible_user: ansible
      vars:
        postgresql_version: "15"
        db_environment: development

    loadbalancers:
      hosts:
        lb01:
          ansible_host: 192.168.1.30
          ansible_user: ansible

  vars:
    ansible_python_interpreter: /usr/bin/python3
    ansible_become: yes

8. Create Master Playbook

playbooks/site.yml:

---
- name: Configure all servers
  hosts: all
  gather_facts: yes
  become: yes

  pre_tasks:
    - name: Update apt cache (Debian/Ubuntu)
      ansible.builtin.apt:
        update_cache: yes
        cache_valid_time: 3600
      when: ansible_os_family == "Debian"
      tags: always

    - name: Display environment
      ansible.builtin.debug:
        msg: "Configuring {{ inventory_hostname }} in {{ app_environment | default('unknown') }} environment"
      tags: always

  roles:
    - role: common
      tags: common

- name: Configure web servers
  hosts: webservers
  become: yes

  roles:
    - role: nginx
      tags: nginx
    - role: application
      tags: app

- name: Configure database servers
  hosts: databases
  become: yes

  roles:
    - role: postgresql
      tags: database

- name: Configure load balancers
  hosts: loadbalancers
  become: yes

  roles:
    - role: haproxy
      tags: loadbalancer

9. Create Example Role

Create a common role:

ansible-galaxy role init roles/common

roles/common/tasks/main.yml:

---
- name: Ensure common packages are installed
  ansible.builtin.package:
    name:
      - curl
      - wget
      - git
      - vim
      - htop
      - net-tools
    state: present
  tags: packages

- name: Configure timezone
  community.general.timezone:
    name: "{{ timezone | default('UTC') }}"
  tags: timezone

- name: Configure NTP
  ansible.builtin.include_tasks: ntp.yml
  when: configure_ntp | default(true)
  tags: ntp

- name: Harden SSH configuration
  ansible.builtin.include_tasks: ssh.yml
  tags: ssh

- name: Configure firewall
  ansible.builtin.include_tasks: firewall.yml
  when: configure_firewall | default(true)
  tags: firewall

10. Setup Molecule Testing (Optional)

If testing enabled:

# Install molecule
pip install molecule molecule-plugins[docker] ansible-lint

# Initialize molecule for a role
cd roles/common
molecule init scenario default --driver-name docker

molecule/default/molecule.yml:

---
dependency:
  name: galaxy
  options:
    requirements-file: requirements.yml

driver:
  name: docker

platforms:
  - name: ubuntu-20.04
    image: geerlingguy/docker-ubuntu2004-ansible
    privileged: true
    pre_build_image: true

  - name: ubuntu-22.04
    image: geerlingguy/docker-ubuntu2204-ansible
    privileged: true
    pre_build_image: true

provisioner:
  name: ansible
  config_options:
    defaults:
      callbacks_enabled: profile_tasks
  inventory:
    host_vars:
      ubuntu-20.04:
        ansible_python_interpreter: /usr/bin/python3
      ubuntu-22.04:
        ansible_python_interpreter: /usr/bin/python3

verifier:
  name: ansible

lint: |
  set -e
  ansible-lint
  yamllint .

11. Create ansible-lint Configuration

.ansible-lint:

---
# Ansible-lint configuration

# Exclude paths
exclude_paths:
  - .github/
  - molecule/
  - .molecule/
  - venv/

# Enable specific rules
enable_list:
  - yaml
  - no-changed-when
  - no-handler

# Skip specific rules for entire project
skip_list:
  - experimental
  - role-name  # If using non-standard role names

# Profile to use (min, basic, moderate, safety, shared, production)
profile: production

# Offline mode (no internet required)
offline: false

# Use colors in output
use_color: true

12. Create README.md

README.md:

# Project Name

Brief description of the Ansible project and its purpose.

## Requirements

- Ansible 2.9 or higher
- Python 3.8 or higher
- Target systems: Ubuntu 20.04+, Debian 11+

## Project Structure

- `inventory/` - Inventory files per environment
- `roles/` - Custom Ansible roles
- `playbooks/` - Ansible playbooks
- `group_vars/` - Group variables
- `host_vars/` - Host-specific variables

## Quick Start

### 1. Install Dependencies

\`\`\`bash
# Install Python dependencies
pip install -r requirements.txt

# Install Ansible Galaxy roles
ansible-galaxy install -r requirements.yml
\`\`\`

### 2. Configure Vault

\`\`\`bash
# Create vault password file (DO NOT COMMIT)
echo "your-secure-password" > .vault-pass
chmod 600 .vault-pass

# Create vault files
ansible-vault create inventory/development/group_vars/all/vault.yml
\`\`\`

### 3. Test Connection

\`\`\`bash
# Ping all hosts
ansible all -i inventory/development -m ping

# Gather facts
ansible all -i inventory/development -m setup
\`\`\`

### 4. Run Playbooks

\`\`\`bash
# Dry run (check mode)
ansible-playbook playbooks/site.yml -i inventory/development --check

# Run playbook
ansible-playbook playbooks/site.yml -i inventory/development

# Run specific tags
ansible-playbook playbooks/site.yml -i inventory/development --tags "common,nginx"

# Limit to specific hosts
ansible-playbook playbooks/site.yml -i inventory/development --limit "webservers"
\`\`\`

## Environments

- **development**: `inventory/development/`
- **staging**: `inventory/staging/`
- **production**: `inventory/production/`

Switch environments by changing the inventory path:
\`\`\`bash
ansible-playbook playbooks/site.yml -i inventory/production
\`\`\`

## Ansible Vault

### Encrypt/Decrypt Files

\`\`\`bash
# Encrypt a file
ansible-vault encrypt inventory/production/group_vars/all/vault.yml

# Decrypt a file (temporary)
ansible-vault decrypt inventory/production/group_vars/all/vault.yml

# Edit encrypted file
ansible-vault edit inventory/production/group_vars/all/vault.yml

# View encrypted file
ansible-vault view inventory/production/group_vars/all/vault.yml

# Change vault password
ansible-vault rekey inventory/production/group_vars/all/vault.yml
\`\`\`

### Encrypt Variables

\`\`\`bash
# Encrypt a string
ansible-vault encrypt_string 'secret_password' --name 'db_password'
\`\`\`

## Testing

### Syntax Check

\`\`\`bash
ansible-playbook playbooks/site.yml --syntax-check
\`\`\`

### Lint

\`\`\`bash
ansible-lint roles/
ansible-lint playbooks/
\`\`\`

### Molecule (Role Testing)

\`\`\`bash
cd roles/common

# Run all tests
molecule test

# Create test instance
molecule create

# Run playbook
molecule converge

# Verify tests
molecule verify

# Destroy test instance
molecule destroy
\`\`\`

## Development Workflow

1. Create/modify roles in `roles/`
2. Update playbooks in `playbooks/`
3. Test with ansible-lint
4. Run in check mode first
5. Test in development environment
6. Review and approve changes
7. Deploy to staging
8. Deploy to production

## Common Tasks

### Add New Server

1. Add host to inventory: `inventory/<env>/hosts.yml`
2. Configure host variables if needed: `host_vars/<hostname>.yml`
3. Run provisioning: `ansible-playbook playbooks/provision.yml -i inventory/<env> --limit <hostname>`

### Add New Role

\`\`\`bash
# Create role structure
ansible-galaxy role init roles/<role-name>

# Add role to requirements.yml if third-party
# Include role in appropriate playbook
\`\`\`

### Deploy Application

\`\`\`bash
ansible-playbook playbooks/deploy.yml -i inventory/<env> \
  --extra-vars "app_version=v1.2.3"
\`\`\`

## Troubleshooting

### Connection Issues

\`\`\`bash
# Test SSH connectivity
ansible all -i inventory/development -m ping -vvv

# Check inventory
ansible-inventory -i inventory/development --list
ansible-inventory -i inventory/development --graph
\`\`\`

### Playbook Failures

\`\`\`bash
# Run with increased verbosity
ansible-playbook playbooks/site.yml -vvv

# Check specific host
ansible-playbook playbooks/site.yml --limit <hostname> -vv
\`\`\`

### Vault Issues

\`\`\`bash
# Verify vault password
ansible-vault view inventory/development/group_vars/all/vault.yml

# Check vault password file permissions
ls -la .vault-pass  # Should be 600
\`\`\`

## Contributing

1. Follow Ansible best practices
2. Test changes with ansible-lint
3. Test in development environment first
4. Document changes in playbook/role README
5. Use meaningful commit messages

## License

[Your License]

## Author

[Your Name/Team]

13. Verify Project Setup

Run validation commands:

# Check ansible.cfg syntax
ansible-config dump

# Verify inventory structure
ansible-inventory -i inventory/development --graph
ansible-inventory -i inventory/development --list

# Test connection to hosts
ansible all -i inventory/development -m ping

# Syntax check playbooks
ansible-playbook playbooks/site.yml --syntax-check

# Lint the project
ansible-lint roles/
ansible-lint playbooks/

# Dry run
ansible-playbook playbooks/site.yml -i inventory/development --check

Output Format

Project Initialization Summary

Project: [project-name] Location: [path] Environments: [dev, staging, production] Initial Roles: [list of roles created]

Directory Structure Created:

✓ ansible.cfg - Ansible configuration
✓ inventory/ - Multi-environment inventory
✓ roles/ - Custom roles
✓ playbooks/ - Master and environment playbooks
✓ group_vars/ - Global variables
✓ vault setup - Encrypted secrets per environment
✓ requirements.yml - Galaxy dependencies
✓ .gitignore - Git exclusions
✓ README.md - Project documentation
✓ .ansible-lint - Lint configuration
✓ molecule/ - Testing framework (optional)

Next Steps

1. Configure Inventory:

# Edit inventory file
vi inventory/development/hosts.yml

# Add your hosts and variables

2. Setup Vault:

# Create vault password
echo "your-password" > .vault-pass
chmod 600 .vault-pass

# Create encrypted secrets
ansible-vault create inventory/development/group_vars/all/vault.yml

3. Install Dependencies:

ansible-galaxy install -r requirements.yml
pip install -r requirements.txt

4. Test Connection:

ansible all -i inventory/development -m ping

5. Develop Roles:

# Create new role
ansible-galaxy role init roles/myapp

# Edit role tasks
vi roles/myapp/tasks/main.yml

6. Run Playbooks:

# Check mode first
ansible-playbook playbooks/site.yml -i inventory/development --check

# Execute
ansible-playbook playbooks/site.yml -i inventory/development

Best Practices

Security:

  • Never commit .vault-pass or unencrypted secrets
  • Use Ansible Vault for all sensitive data
  • Separate vault files per environment
  • Rotate vault passwords regularly
  • Use SSH keys, not passwords

Organization:

  • One role per purpose (single responsibility)
  • Keep playbooks simple, logic in roles
  • Use tags for selective execution
  • Group related tasks in separate files
  • Follow ansible-galaxy role structure

Testing:

  • Always run in check mode first (--check)
  • Test in development before production
  • Use ansible-lint for code quality
  • Implement Molecule tests for roles
  • Use CI/CD for automated testing

Version Control:

  • Commit early and often
  • Use meaningful commit messages
  • Tag releases (v1.0.0, v1.1.0, etc.)
  • Branch for features/fixes
  • Review changes before production

Documentation:

  • README in every role
  • Document all variables
  • Include example playbooks
  • Keep documentation up to date
  • Explain non-obvious decisions