How to Create a Directory in Ansible

Creating directories in Ansible is useful for setting up a structured server environment, such as hosting a web app. For example, an app might need folders for logs, configuration files, and data. Ansible ensures these directories are created consistently across servers and only if they don’t already exist (idempotency), preventing duplicates or manual checks. Ansible also lets you set permissions and ownership during directory creation, ensuring the right users or services have access and enhancing security. This article focuses on creating directories in Ansible using various methods, including the file and—optionally—the command modules. We’ll also discuss some techniques for managing these directories, such as setting up permissions and removing directories. Prerequisites Here are some of the things you need so you can follow the examples in this article: An Ansible installation on your local machine or control node  A basic understanding of Ansible's playbook structure  Access to a target server where Ansible can connect to execute these commands - this could be a local VM or a remote server Demo description: organizing application logs For the examples below, let's assume you're setting up a server to host a web application that generates logs for monitoring and debugging. To keep these logs organized, you want to create a directory structure on the server where logs for each day can be stored separately. This setup will help you and other team members quickly find logs from a specific day or track patterns over time. Creating a directory with Ansible In this section, we'll review several methods for creating directories in Ansible. Each method has strengths and appropriate conditions for use. 1. Using the file module for directory creation The file module is Ansible's main tool for creating, modifying, or deleting files and directories. It's designed to be idempotent, meaning it only takes action if necessary. Using the file module for directory creation is efficient and straightforward. It ensures the directory exists and applies the permissions in one go. For instance, if you want to create a directory for storing daily logs, your Ansible playbook will look like this: --- - hosts: all become: true tasks: - name: Create directory for daily logs ansible.builtin.file: path: /var/logs/app/daily_logs state: directory mode: '0755' Here's a breakdown of this playbook: path specifies the location where you want the directory to be created. state: directory tells Ansible to ensure this path is a directory. If it doesn't exist, Ansible will create it; if it does, Ansible will move on without errors. mode: '0755' sets the directory's permissions. The "0755" code makes the directory readable and executable by others but writable only by the owner.  To learn more about the "0755" code and file permissions, check out this article. Once you run this playbook, you should see the following output: 2. Using the command module for directory creation Although the file module is ideal for creating directories in Ansible, you can also use the command module if you need more control or flexibility. This module allows you to run shell commands directly, such as using mkdir. If you  create another directory for storing daily logs using the command module, your playbook will look like this: --- - hosts: all become: true tasks: - name: Create directory for daily logs with command module ansible.builtin.command: cmd: "mkdir -p /var/logs/app/daily_logs" Below is a breakdown of this playbook: cmd: "mkdir -p /var/logs/app/daily_logs"  runs the mkdir -p command, which creates the directory if it doesn't exist. The -p option ensures that Ansible doesn't throw an error if parts of the directory structure don't already exist. The command module isn't idempotent on its own, but mkdir -p makes it safe by preventing errors if the directory already exists. NOTE: This module is more convenient if you need greater control over the shell environment or want to combine commands. However, it's not typically idempotent, so it's best used when a file doesn't meet your needs. Once you run this playbook, you should see the following output: 3. Conditional directory creation Sometimes you might want to create a directory only under specific conditions. For instance, you might want to create the log directory only if another directory, /var/logs/app, exists already. This is how to structure your playbook: --- - hosts: all become: true tasks: - name: Check if the app directory exists ansible.builtin.stat: path: /var/logs/app register: app_dir - name: Conditionally create directory for daily logs ansible.builtin.file: path: /var/logs/app/daily_logs state: directory when: app_dir.stat.exists F

May 2, 2025 - 08:41
 0
How to Create a Directory in Ansible

Creating directories in Ansible is useful for setting up a structured server environment, such as hosting a web app.

For example, an app might need folders for logs, configuration files, and data. Ansible ensures these directories are created consistently across servers and only if they don’t already exist (idempotency), preventing duplicates or manual checks.

Ansible also lets you set permissions and ownership during directory creation, ensuring the right users or services have access and enhancing security.

This article focuses on creating directories in Ansible using various methods, including the file and—optionally—the command modules. We’ll also discuss some techniques for managing these directories, such as setting up permissions and removing directories.

Prerequisites

Here are some of the things you need so you can follow the examples in this article:

  • An Ansible installation on your local machine or control node 
  • A basic understanding of Ansible's playbook structure 
  • Access to a target server where Ansible can connect to execute these commands - this could be a local VM or a remote server

Demo description: organizing application logs

For the examples below, let's assume you're setting up a server to host a web application that generates logs for monitoring and debugging.

To keep these logs organized, you want to create a directory structure on the server where logs for each day can be stored separately.

This setup will help you and other team members quickly find logs from a specific day or track patterns over time.

Creating a directory with Ansible

In this section, we'll review several methods for creating directories in Ansible. Each method has strengths and appropriate conditions for use.

1. Using the file module for directory creation

The file module is Ansible's main tool for creating, modifying, or deleting files and directories. It's designed to be idempotent, meaning it only takes action if necessary.

Using the file module for directory creation is efficient and straightforward. It ensures the directory exists and applies the permissions in one go. For instance, if you want to create a directory for storing daily logs, your Ansible playbook will look like this:

---
- hosts: all
  become: true
  tasks:
    - name: Create directory for daily logs
      ansible.builtin.file:
        path: /var/logs/app/daily_logs
        state: directory
        mode: '0755'

Here's a breakdown of this playbook:

  • path specifies the location where you want the directory to be created.
  • state: directory tells Ansible to ensure this path is a directory. If it doesn't exist, Ansible will create it; if it does, Ansible will move on without errors.
  • mode: '0755' sets the directory's permissions. The "0755" code makes the directory readable and executable by others but writable only by the owner.  To learn more about the "0755" code and file permissions, check out this article.

Once you run this playbook, you should see the following output:

Using the file module for directory creation

2. Using the command module for directory creation

Although the file module is ideal for creating directories in Ansible, you can also use the command module if you need more control or flexibility. This module allows you to run shell commands directly, such as using mkdir.

If you  create another directory for storing daily logs using the command module, your playbook will look like this:

---
- hosts: all
  become: true
  tasks:
    - name: Create directory for daily logs with command module
      ansible.builtin.command:
        cmd: "mkdir -p /var/logs/app/daily_logs"

Below is a breakdown of this playbook:

  • cmd: "mkdir -p /var/logs/app/daily_logs"  runs the mkdir -p command, which creates the directory if it doesn't exist.
  • The -p option ensures that Ansible doesn't throw an error if parts of the directory structure don't already exist.

The command module isn't idempotent on its own, but mkdir -p makes it safe by preventing errors if the directory already exists.

NOTE: This module is more convenient if you need greater control over the shell environment or want to combine commands. However, it's not typically idempotent, so it's best used when a file doesn't meet your needs.

Once you run this playbook, you should see the following output:

Using the command module for directory creation

3. Conditional directory creation

Sometimes you might want to create a directory only under specific conditions. For instance, you might want to create the log directory only if another directory, /var/logs/app, exists already.

This is how to structure your playbook:

---
- hosts: all
  become: true
  tasks:
    - name: Check if the app directory exists
      ansible.builtin.stat:
        path: /var/logs/app
      register: app_dir

    - name: Conditionally create directory for daily logs
      ansible.builtin.file:
        path: /var/logs/app/daily_logs
        state: directory
      when: app_dir.stat.exists

From the playbook above:

  • ansible.builtin.stat on /var/logs/app: This first task checks if the /var/logs/app directory exists and stores the result in the app_dir variable.
  • when: app_dir.stat.exists: The when condition in the second task checks if /var/logs/app exists. If it does, Ansible creates the daily_logs subdirectory. If it doesn't, the task is skipped.

Once you run this playbook, you should see the following output:

Conditional directory creation

4. Creating a directory structure with multiple levels (recursive creation)

Sometimes you need to create a directory structure with several nested levels. The file module can handle this with a simple configuration.

Using the daily logs example, let's say you want a structure like /var/logs/app/daily_logs/yyyy/mm/dd where logs are grouped by year, month, and day.

This is how to structure your playbook:

---
- hosts: all
  become: true
  tasks:
    - name: Create nested directory structure for daily logs
      ansible.builtin.file:
        path: /var/logs/app/daily_logs/2024/11/07
        state: directory
        mode: '0755'

By specifying a deeply nested path in path, Ansible will automatically create any missing parent directories, making recursive creation straightforward.

Once you run this playbook, you should see the following output:

Creating a directory structure with multiple levels (recursive creation)

5. Creating multiple directories file (iterative creation)

Let's say you need to create multiple directories in a single task. You can do this by iterating over a list of directories.

This technique is efficient for setting up multiple directories in a single task. It's particularly useful if your app needs multiple folders organized separately for different types of data or configuration files.

For instance, let's say you want to create folders for logs, config, and data for the app. You'll write your playbook like this:

---
- hosts: all
  become: true
  tasks:
    - name: Create multiple directories for app
      ansible.builtin.file:
        path: "{{ item }}"
        state: directory
        mode: '0755'
      loop:
        - /var/logs/app
        - /var/config/app
        - /var/data/app

In this playbook, loop allows you to iterate over each path in the list, creating each one in turn.

Once you run this playbook, you should see the following output:

Creating multiple directories file (iterative creation)