Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- .woodpecker.yaml: image paths -> library/autojanet-{agent,dispatcher}
- .woodpecker.yaml: secret names RS_HARBOR_USER / RS_HARBOR_PASS (global)
- container/Dockerfile: restore COPY skills/, skills/ populated from opencode config
- skills/: 84 opencode skills bundled into image
- k8s/manifests: update image refs to library/
4.8 KiB
4.8 KiB
| name | description |
|---|---|
| azure-pipeline-ansible | Extends azure-devops-pipeline for Ansible playbook runs. Handles syntax check, galaxy install, vault passwords, SSH key injection, check mode on nonprod, and dynamic AWS EC2 inventory. Always load azure-devops-pipeline first. |
What I add
Type-specific steps for Ansible pipelines. Merge these into the skeleton from azure-devops-pipeline.
Additional required inputs — ask the user
- Playbook path — e.g.
playbooks/site.yml - Inventory source —
static|dynamic-aws-ec2 - Ansible Vault in use —
yes|no - ADO secret variable name for vault password — if vault in use, e.g.
ANSIBLE_VAULT_PASSWORD - ADO secret variable name for SSH private key — e.g.
ANSIBLE_SSH_KEY - Ansible version to pin — e.g.
9.2.0 - Run --check mode on nonprod before real apply —
yes(default) |no
Lint stage steps
- script: |
pip install "ansible==$(ANSIBLE_VERSION)" ansible-lint
ansible-lint <playbook-path> --profile production
displayName: "Lint — ansible-lint"
env:
ANSIBLE_VERSION: <ansible-version>
Security scan stage steps
- script: |
pip install "ansible==$(ANSIBLE_VERSION)" ansible-lint
ansible-lint <playbook-path> --profile security \
--sarif-file ansible-lint-security.sarif || true
ansible-galaxy install -r requirements.yml --force
displayName: "Security scan — ansible-lint security profile"
env:
ANSIBLE_VERSION: <ansible-version>
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: ansible-lint-security.sarif
artifactName: security-scan
displayName: "Publish scan results"
Build stage steps
- script: |
pip install "ansible==$(ANSIBLE_VERSION)"
[ -f requirements.yml ] && ansible-galaxy install -r requirements.yml || true
ansible-playbook <playbook-path> --syntax-check -i <inventory-file>
displayName: "Validate — syntax check and galaxy install"
env:
ANSIBLE_VERSION: <ansible-version>
Note: for dynamic-aws-ec2 inventory, replace -i <inventory-file> with -i aws_ec2.yml and ensure aws_ec2.yml exists in the repo with the amazon.aws.aws_ec2 plugin configured.
Deploy stage steps
Step order — always emit in this order
- Write SSH key to temp file
- Write vault password to temp file (if vault in use)
- Check mode run (nonprod only, if enabled)
- Real playbook run
- Clean up SSH key (condition: always)
- Clean up vault password (condition: always)
SSH key injection (always include)
- script: |
echo "$(ANSIBLE_SSH_KEY)" > /tmp/ansible_ssh_key
chmod 600 /tmp/ansible_ssh_key
displayName: "Inject SSH key"
env:
ANSIBLE_SSH_KEY: $(ANSIBLE_SSH_KEY)
Vault password file (include only if vault in use)
- script: |
echo "$(ANSIBLE_VAULT_PASSWORD)" > /tmp/vault_pass
chmod 600 /tmp/vault_pass
displayName: "Write vault password file"
env:
ANSIBLE_VAULT_PASSWORD: $(ANSIBLE_VAULT_PASSWORD)
Check mode run (nonprod only, if enabled)
- script: |
VAULT_ARGS=""
[ -f /tmp/vault_pass ] && VAULT_ARGS="--vault-password-file /tmp/vault_pass"
ansible-playbook <playbook-path> \
-i <inventory> \
--check \
--diff \
--private-key /tmp/ansible_ssh_key \
$VAULT_ARGS
displayName: "Dry run — check mode"
Real run
- script: |
VAULT_ARGS=""
[ -f /tmp/vault_pass ] && VAULT_ARGS="--vault-password-file /tmp/vault_pass"
ansible-playbook <playbook-path> \
-i <inventory> \
--diff \
--private-key /tmp/ansible_ssh_key \
$VAULT_ARGS
displayName: "Apply playbook"
Cleanup (always at end of deploy steps — condition: always())
- script: rm -f /tmp/ansible_ssh_key
displayName: "Clean up SSH key"
condition: always()
- script: rm -f /tmp/vault_pass
displayName: "Clean up vault password file"
condition: always()
Hard rules for Ansible
- Always pin Ansible version with quoted pip specifier
"ansible==$(ANSIBLE_VERSION)"— never uselatest, unquoted==may fail in some shells - Always clean up SSH key and vault password files with
condition: always()— they must be removed even if the playbook fails - Always include
--diffon real runs so changes are visible in pipeline logs - SSH key file permissions must be
600— Ansible refuses keys with broader permissions - Use shell variable expansion (
VAULT_ARGS="") rather than subshell substitution in the step script to avoid bash syntax issues in ADO agents - For dynamic inventory, AWS credentials come from the OIDC service connection environment — same pattern as Lambda
requirements.ymlmust exist in the repo if galaxy install step is included; if uncertain, wrap with[ -f requirements.yml ] && ansible-galaxy install -r requirements.yml || true