Files
michaelschiemer/deployment/ansible/playbooks/deploy-update.yml
Michael Schiemer 2a7b90312f chore(deploy): add prod env template, improve ansible deploy, prune old workflows
- Add deployment/ansible/templates/.env.production.j2 used by secrets playbook
- Enhance deploy-update.yml to read registry creds from vault or CI
- Update production-deploy workflow to pass registry credentials to Ansible
- Remove obsolete GitHub-style workflows under .gitea (conflicted naming)

Why: make the production pipeline executable end-to-end with Ansible and
consistent secrets handling; avoid legacy CI configs interfering.
2025-10-30 21:38:28 +01:00

138 lines
4.7 KiB
YAML

---
- name: Deploy Application Update
hosts: production
gather_facts: yes
become: yes
vars:
# These should be passed via -e from CI/CD
image_tag: "{{ image_tag | default('latest') }}"
git_commit_sha: "{{ git_commit_sha | default('unknown') }}"
deployment_timestamp: "{{ deployment_timestamp | default(ansible_date_time.iso8601) }}"
pre_tasks:
- name: Optionally load registry credentials from encrypted vault
include_vars:
file: "{{ playbook_dir }}/../secrets/production.vault.yml"
no_log: yes
ignore_errors: yes
delegate_to: localhost
become: no
- name: Derive docker registry credentials from vault when not provided
set_fact:
docker_registry_username: "{{ docker_registry_username | default(vault_docker_registry_username | default(omit)) }}"
docker_registry_password: "{{ docker_registry_password | default(vault_docker_registry_password | default(omit)) }}"
- name: Verify Docker is running
systemd:
name: docker
state: started
register: docker_service
- name: Fail if Docker is not running
fail:
msg: "Docker service is not running"
when: docker_service.status.ActiveState != 'active'
- name: Create backup directory
file:
path: "{{ backups_path }}/{{ deployment_timestamp | regex_replace(':', '-') }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
tasks:
- name: Backup current deployment metadata
shell: |
docker service inspect {{ stack_name }}_app --format '{{ "{{" }}.Spec.TaskTemplate.ContainerSpec.Image{{ "}}" }}' \
> {{ backups_path }}/{{ deployment_timestamp | regex_replace(':', '-') }}/current_image.txt || true
docker stack ps {{ stack_name }} --format 'table {{ "{{" }}.Name{{ "}}" }}\t{{ "{{" }}.Image{{ "}}" }}\t{{ "{{" }}.CurrentState{{ "}}" }}' \
> {{ backups_path }}/{{ deployment_timestamp | regex_replace(':', '-') }}/stack_status.txt || true
args:
executable: /bin/bash
changed_when: false
- name: Login to Docker registry (if credentials provided)
docker_login:
registry_url: "{{ docker_registry_url }}"
username: "{{ docker_registry_username }}"
password: "{{ docker_registry_password }}"
no_log: yes
when:
- docker_registry_username is defined
- docker_registry_password is defined
- name: Pull new Docker image
docker_image:
name: "{{ app_image }}"
tag: "{{ image_tag }}"
source: pull
force_source: yes
register: image_pull
- name: Update docker-compose.prod.yml with new image tag
lineinfile:
path: "{{ compose_file }}"
regexp: '^(\s+image:\s+){{ app_image }}:.*$'
line: '\1{{ app_image }}:{{ image_tag }}'
backrefs: yes
when: compose_file is file
- name: Deploy stack update
docker_stack:
name: "{{ stack_name }}"
compose:
- "{{ compose_file }}"
state: present
prune: yes
register: stack_deploy
- name: Wait for service to be updated
command: >
docker service ps {{ stack_name }}_app
--filter "desired-state=running"
--format '{{ "{{" }}.CurrentState{{ "}}" }}'
register: service_status
until: "'Running' in service_status.stdout"
retries: 30
delay: 10
changed_when: false
- name: Get updated service info
command: docker service inspect {{ stack_name }}_app --format '{{ "{{" }}.Spec.TaskTemplate.ContainerSpec.Image{{ "}}" }}'
register: deployed_image
changed_when: false
- name: Record deployment metadata
copy:
content: |
Deployment Timestamp: {{ deployment_timestamp }}
Git Commit: {{ git_commit_sha }}
Image Tag: {{ image_tag }}
Deployed Image: {{ deployed_image.stdout }}
Stack Deploy Output: {{ stack_deploy }}
dest: "{{ backups_path }}/{{ deployment_timestamp | regex_replace(':', '-') }}/deployment_metadata.txt"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
- name: Cleanup old backups (keep last {{ max_rollback_versions }})
shell: |
cd {{ backups_path }}
ls -t | tail -n +{{ max_rollback_versions + 1 }} | xargs -r rm -rf
args:
executable: /bin/bash
changed_when: false
post_tasks:
- name: Display deployment summary
debug:
msg:
- "Deployment completed successfully!"
- "Image: {{ app_image }}:{{ image_tag }}"
- "Commit: {{ git_commit_sha }}"
- "Timestamp: {{ deployment_timestamp }}"
- "Health check URL: {{ health_check_url }}"