I am using ansible
to deploy my django App
using
- name: Upgrade the virtualenv.
pip: requirements={{project_root}}/www/requirements.txt virtualenv={{project_root}}/www/virtualenv
But i only want to run that if requirements.txt changed since last run
The easiest way to run only one task in Ansible Playbook is using the tags statement parameter of the “ansible-playbook” command. The default behavior is to execute all the tags in your Playbook with --tags all .
When a module think that it's action changed something (e.g. a state of a subject before module execution and a state after are different), it need to report 'changed' to Ansible.
If a task notifies a handler but another task fails later in the play, by default the handler does not run on that host, which may leave the host in an unexpected state. For example, a task could update a configuration file and notify a handler to restart some service.
You can achieve similar effect by just using the --step flag e.g: ansible-playbook playbook. yml --step . The step asks you on before executing each task and you could choose (N)o/(y)es/(c)ontinue . With this approach you selectively execute tasks when needed and also continue from point where it failed, after fixes.
We need to determine if any of the requirement files have changed. The steps are as follows:
Here's my playbook, {{virtualenv.requirements}} is a list of requirement files, eg: ['/work/project/requirements.txt', '/work/project/requirements-prod.txt']
:
- name: Assures temp requirements directory exists
file: path="/tmp{{ virtualenv.path }}" state=directory
sudo: yes
when: install_pip_packages
- name: Assures temp requirements files exists
file: path="/tmp{{ item }}" state=touch
sudo: yes
with_items: virtualenv.requirements_files
when: install_pip_packages
- name: Calculate md5 of temp requirements
stat: path="/tmp{{ item }}"
with_items: virtualenv.requirements_files
register: temp_requirements_stat
when: install_pip_packages
- name: Calculate md5 of current requirements
stat: path="{{ item }}"
with_items: virtualenv.requirements_files
register: current_requirements_stat
when: install_pip_packages
- name: Check requirement files for changes
command: test {{ temp_requirements_stat.results[item.0].stat.md5 }} = {{ current_requirements_stat.results[item.0].stat.md5 }}
changed_when: "requirements_check.rc != 0"
failed_when: requirements_check.stderr
with_indexed_items: virtualenv.requirements_files
register: requirements_check
when: install_pip_packages
- name: Install packages required by the Django app inside virtualenv
pip: virtualenv={{ virtualenv.path }} extra_args='-U' requirements="{{ virtualenv.requirements_files | join(' -r ') }}"
when: install_pip_packages and requirements_check.changed
- name: Copy requirements to /tmp
command: cp "{{ item }}" "/tmp{{ item }}"
sudo: yes
with_items: virtualenv.requirements_files
when: install_pip_packages
Here are two options:
put your requirements.txt under Ansible control and use 'copy' or 'template' module, then invoke 'pip' module with 'notify:' statement
second way is more complex:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With