Ansible Playbook 執行管線

DevOps
8 個節點 · 8 條連接devops
ex-ansible-playbook.osop.yaml
# Ansible Playbook Execution Pipeline
# Inventory validation, lint, dry-run, execute, and verify configuration
osop_version: "2.0"
id: ansible-playbook
name: "Ansible Playbook 執行管線"

nodes:
  - id: load_inventory
    type: cli
    purpose: Parse and validate Ansible inventory for target host reachability
    runtime:
      command: "ansible-inventory -i inventory/${ENVIRONMENT}.yml --list --output inventory.json && ansible all -i inventory/${ENVIRONMENT}.yml -m ping"
    outputs: [inventory_hosts, reachable_count]
    timeout_sec: 120
    security:
      credentials: [ANSIBLE_SSH_PRIVATE_KEY, ANSIBLE_VAULT_PASSWORD]
    explain: |
      Validates inventory structure and confirms SSH connectivity to all
      target hosts before proceeding. Unreachable hosts abort the pipeline.

  - id: lint_playbook
    type: cli
    purpose: Run ansible-lint and yamllint for syntax and best practice violations
    runtime:
      command: "ansible-lint playbooks/${PLAYBOOK}.yml --format json && yamllint playbooks/"
    inputs: [inventory_hosts]
    outputs: [lint_result, warning_count]
    timeout_sec: 60

  - id: syntax_check
    type: cli
    purpose: Perform Ansible syntax check to catch undefined variables and module errors
    runtime:
      command: "ansible-playbook playbooks/${PLAYBOOK}.yml -i inventory/${ENVIRONMENT}.yml --syntax-check"
    inputs: [lint_result]
    outputs: [syntax_valid]
    timeout_sec: 30

  - id: dry_run
    type: cli
    purpose: Execute playbook in check mode to preview changes without applying them
    runtime:
      command: "ansible-playbook playbooks/${PLAYBOOK}.yml -i inventory/${ENVIRONMENT}.yml --check --diff"
    inputs: [syntax_valid]
    outputs: [change_preview, tasks_changed, tasks_ok]
    timeout_sec: 300
    explain: |
      Check mode simulates execution and reports what would change.
      The diff output shows exact file modifications for review.

  - id: approval
    type: human
    purpose: Operations engineer reviews dry-run output and approves execution
    role: ops_engineer
    inputs: [change_preview, tasks_changed, warning_count]
    approval_gate:
      required_approvers: 1
      timeout_min: 60

  - id: execute_playbook
    type: cli
    purpose: Execute the playbook against target hosts with full logging
    runtime:
      command: |
        ANSIBLE_LOG_PATH=./logs/ansible-$(date +%Y%m%d-%H%M%S).log \
        ansible-playbook playbooks/${PLAYBOOK}.yml \
          -i inventory/${ENVIRONMENT}.yml \
          --diff \
          --forks 10
    inputs: [inventory_hosts]
    outputs: [execution_result, hosts_changed, hosts_failed]
    timeout_sec: 1800
    retry_policy:
      max_retries: 1
      backoff_sec: 30
    security:
      credentials: [ANSIBLE_SSH_PRIVATE_KEY, ANSIBLE_VAULT_PASSWORD, ANSIBLE_BECOME_PASS]

  - id: verify_state
    type: cli
    purpose: Run verification playbook to confirm desired state was achieved
    runtime:
      command: "ansible-playbook playbooks/verify-${PLAYBOOK}.yml -i inventory/${ENVIRONMENT}.yml"
    inputs: [execution_result]
    outputs: [verification_passed, failed_assertions]
    timeout_sec: 300

  - id: notify
    type: api
    purpose: Post execution summary to Slack with host counts and any failures
    runtime:
      endpoint: /api/chat.postMessage
      method: POST
      url: https://slack.com
    inputs: [execution_result, verification_passed, hosts_changed, hosts_failed]
    security:
      auth: bearer_token
      secret_ref: SLACK_BOT_TOKEN

edges:
  - from: load_inventory
    to: lint_playbook
    mode: sequential

  - from: lint_playbook
    to: syntax_check
    mode: sequential

  - from: syntax_check
    to: dry_run
    mode: sequential

  - from: dry_run
    to: approval
    mode: sequential

  - from: approval
    to: execute_playbook
    mode: sequential

  - from: execute_playbook
    to: verify_state
    mode: sequential

  - from: verify_state
    to: notify
    mode: sequential

  - from: verify_state
    to: execute_playbook
    mode: fallback
    label: "Verification failed, retry execution"