Ansible Playbook Dry Run: How to Run Playbook in “Check Mode”

Ansible Playbook Dry Run and Check Mode

Check mode (–check) is a feature in Ansible that allows you to run playbooks without making any changes to the target systems. This mode is also known as a “dry run” and is particularly useful for testing and verifying playbooks.

This guide will explore the concept of a dry run in Ansible, its importance, and how to use it effectively with practical examples.

Introduction to Ansible Dry Run

In Ansible, a dry run is called a “check mode“. When you run a playbook in check mode, Ansible executes the tasks but does not make any actual changes. It will report what changes would have been made if the playbook was run in normal mode. This helps you identify potential issues and ensure the playbook works as intended.

Importance of Dry Run

Dry runs are crucial for several reasons:

  • Safety: Ensure that your playbook does not inadvertently disrupt services or configurations.
  • Validation: Verify that your tasks will execute as expected.
  • Debugging: Identify issues in your playbook logic or syntax without affecting the target systems.
  • Compliance: Ensure changes meet organizational policies and standards before implementation.

How to Perform a Dry Run

To perform a dry run in Ansible, you can use the –check flag when running your playbook. This flag tells Ansible to go through the series of tasks without actually applying any changes. Additionally, you can use the –diff flag to see the differences between the current and desired states as defined in your playbook.

Let’s perform a dry run with the ansible-playbook command.

 # ansible-playbook playbook.yml --check

Including Check Mode in Playbook

You can also specify check mode within your playbook by using the check_mode directive at the task level.

Here is an example playbook for the dry run.

- name: Update web server configuration
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure Apache is installed
      apt:
        name: apache2
        state: present
      check_mode: yes

Using the Diff Option

The –diff option shows you the differences that would be made to the files on the target systems.

 # ansible-playbook playbook.yml --diff

Using Both Diff and Check Mode

Combining –diff and –check gives you a comprehensive view of what changes would be made and how the files would be modified.

 # ansible-playbook playbook.yml --check --diff

Ansible Dry Run: Practical Examples

Let’s explore some practical scenarios where performing a dry run can be beneficial.

Example 1: Verifying Configuration Changes

Suppose you have a playbook that updates the configuration of a web server. Before applying these changes in a live environment, ensure they will not cause any issues.

Let’s create a playbook named webserver_config.yml.

---
- name: Update web server configuration
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure Apache is installed
      apt:
        name: apache2
        state: present
    
    - name: Update the Apache configuration file
      template:
        src: /templates/apache2.conf.j2
        dest: /etc/apache2/apache2.conf
      notify: Restart Apache

  handlers:
    - name: Restart Apache
      service:
        name: apache2
        state: restarted

Now, run the above playbook with check mode.

 # ansible-playbook webserver_config.yml --check --diff

The above command will simulate the configuration changes, allowing you to verify that the template file will be correctly applied.

Example 2: Testing Playbook Syntax and Logic

Dry runs are also helpful for testing the syntax and logic of your playbooks. For example, if you have a playbook that deploys a multi-tier application, you can use check mode to ensure all tasks are correctly defined.

Create a playbook named deploy_application.yml.

---
- name: Deploy multi-tier application
  hosts: app_servers
  become: yes
  tasks:
    - name: Install necessary packages
      apt:
        name: "{{ item }}"
        state: present
      loop:
        - nginx
        - postgresql
        - python3-venv

    - name: Deploy application code
      git:
        repo: 'https://github.com/example/app.git'
        dest: /var/www/app

    - name: Start application services
      service:
        name: "{{ item }}"
        state: started
      loop:
        - nginx
        - postgresql

Now, perform a dry run or check mode.

 # ansible-playbook deploy_application.yml --check --diff

This will help you ensure that all tasks are syntactically correct and logically sound before changing your servers.

Real-World Use Case: Upgrading a Web Application

Consider a scenario where you need to upgrade a web application across multiple servers. This upgrade involves updating the application code, database schema, and configuration files. A dry run can help ensure that the upgrade process will proceed smoothly without causing downtime or data loss.

Create a playbook named upgrade_webapp.yml.

---
- name: Upgrade web application
  hosts: web_servers
  become: yes
  vars:
    app_version: "2.0"
  tasks:
    - name: Pull latest application code
      git:
        repo: 'https://github.com/example/webapp.git'
        dest: /var/www/webapp
        version: "{{ app_version }}"
      check_mode: yes

    - name: Apply database migrations
      command: /var/www/webapp/manage.py migrate
      args:
        creates: /var/www/webapp/db/migrations/applied
      check_mode: yes

    - name: Update application configuration
      template:
        src: /templates/webapp.conf.j2
        dest: /etc/webapp/webapp.conf
      notify: Restart webapp
      check_mode: yes

  handlers:
    - name: Restart webapp
      service:
        name: webapp
        state: restarted
      check_mode: yes

Now, perform a dry run.

 # ansible-playbook upgrade_webapp.yml --check --diff

In the above playbook:

  • Pull latest application code: This task fetches the latest code from the repository without applying changes to the file system.
  • Apply database migrations: This task simulates the application of database migrations, ensuring that no errors occur.
  • Update application configuration: This task verifies that the configuration file will be correctly templated and deployed.
  • Handlers: Even handlers can be run in check mode to ensure they will trigger correctly without restarting the service.

Running this dry run will allow you to identify potential issues in the upgrade process, such as missing dependencies, syntax errors, or incorrect configurations, without making any changes to the production environment.

Conclusion

Performing a dry run in Ansible is a powerful way to ensure your playbooks are correct and safe before applying system changes. By using the –check and –diff flags, you can validate configurations, test syntax and logic, and simulate complex deployment scenarios with confidence.

FAQs

1. Is there a way to skip Check Mode for specific tasks?

Yes, you can use check_mode: no within a task to make sure it runs even in Check Mode.

2. Does Check Mode detect syntax errors in the playbook?

Yes, Check Mode helps in detecting syntax errors, variable issues, and logical errors in tasks.

3. Can I perform a dry run with a specific tag in a playbook?

Yes, you can use --tags to specify which tagged tasks to test in Check Mode.

About Hitesh Jethva

I am Hitesh Jethva, Founder and Author at Code2DevOps.com. With over 15 years of experience in DevOps and open source technologies, I am passionate about empowering teams through automation, continuous integration, and scalable solutions.

View all posts by Hitesh Jethva