Ansibleでコンテンツ付きのファイルを作成する方法

AnsibleAnsibleBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

Introduction

Ansible is a powerful IT automation tool that simplifies infrastructure management. In this hands-on lab, you will learn how to use Ansible to create files with specific content on target systems. By the end of this lab, you will understand the basics of Ansible file management and be able to implement automated file creation in your own infrastructure.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ansible(("Ansible")) -.-> ansible/PlaybookEssentialsGroup(["Playbook Essentials"]) ansible(("Ansible")) -.-> ansible/ModuleOperationsGroup(["Module Operations"]) ansible/ModuleOperationsGroup -.-> ansible/apt("Package Manager") ansible/ModuleOperationsGroup -.-> ansible/copy("Transfer Files") ansible/ModuleOperationsGroup -.-> ansible/file("Manage Files/Directories") ansible/ModuleOperationsGroup -.-> ansible/ping("Network Test") ansible/ModuleOperationsGroup -.-> ansible/template("Generate Files from Templates") ansible/PlaybookEssentialsGroup -.-> ansible/playbook("Execute Playbook") subgraph Lab Skills ansible/apt -.-> lab-417416{{"Ansibleでコンテンツ付きのファイルを作成する方法"}} ansible/copy -.-> lab-417416{{"Ansibleでコンテンツ付きのファイルを作成する方法"}} ansible/file -.-> lab-417416{{"Ansibleでコンテンツ付きのファイルを作成する方法"}} ansible/ping -.-> lab-417416{{"Ansibleでコンテンツ付きのファイルを作成する方法"}} ansible/template -.-> lab-417416{{"Ansibleでコンテンツ付きのファイルを作成する方法"}} ansible/playbook -.-> lab-417416{{"Ansibleでコンテンツ付きのファイルを作成する方法"}} end

Installing and Setting Up Ansible

Before we can start using Ansible to create files, we need to install and configure it on our system. Let us set up our environment:

Installing Ansible

First, we will update the package lists and install Ansible on our Ubuntu 22.04 system:

sudo apt update
sudo apt install -y ansible

After running these commands, you should see output indicating that Ansible has been successfully installed. Let us verify the installation:

ansible --version

You should see output similar to this:

ansible [core 2.12.0]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, ...) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

Creating a Simple Ansible Inventory

Ansible uses an inventory file to define the hosts it will manage. For this lab, we will create a local inventory that includes our own machine:

  1. Create a new directory for our Ansible project:
mkdir -p ~/project/ansible-files
cd ~/project/ansible-files
  1. Create an inventory file using VSCode:
    • Click on the Explorer icon in the WebIDE
    • Navigate to the ~/project/ansible-files directory
    • Right-click and select "New File"
    • Name the file inventory
    • Add the following content to the file:
[local]
localhost ansible_connection=local

This inventory file tells Ansible to run commands on the local machine without using SSH.

  1. Create a simple ansible.cfg file in the same directory:
    • Click on the Explorer icon in the WebIDE
    • Navigate to the ~/project/ansible-files directory
    • Right-click and select "New File"
    • Name the file ansible.cfg
    • Add the following content to the file:
[defaults]
inventory = ./inventory
host_key_checking = False
  1. Let us verify our setup by running a simple Ansible command:
cd ~/project/ansible-files
ansible local -m ping

You should see output similar to:

localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

This confirms that Ansible is correctly installed and configured to run commands on your local machine.

Creating Files with Content Using Ansible Playbooks

Now that we have Ansible set up, let us learn how to create files with content. Ansible provides several modules for managing files, and we will focus on the copy module in this step.

Understanding Ansible Playbooks

Ansible Playbooks are YAML files that describe a set of tasks to be executed on target hosts. Each task utilizes a specific Ansible module to perform an action.

Let us create our first playbook to create a file with content:

  1. In the WebIDE, create a new file in the ~/project/ansible-files directory:
    • Right-click on the directory and select "New File"
    • Name the file create_file.yml
    • Add the following content:
---
- name: Create a file with content
  hosts: local
  tasks:
    - name: Create a simple text file
      copy:
        dest: "~/project/hello.txt"
        content: |
          Hello from Ansible!
          This file was created using the Ansible copy module.
          Current date: {{ ansible_date_time.date }}

Let us understand what this playbook does:

  • The hosts: local line specifies that this playbook will run on the hosts in the local group from our inventory.
  • The tasks section contains a list of tasks to execute.
  • The copy module is used to create a file with content.
  • The dest parameter specifies the destination path for the file.
  • The content parameter contains the text content that will be written to the file.
  • The {{ ansible_date_time.date }} is a variable that will be replaced with the current date when the playbook runs.
  1. Now, let us run the playbook:
cd ~/project/ansible-files
ansible-playbook create_file.yml

You should see output similar to:

PLAY [Create a file with content] ***********************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create a simple text file] ***********************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  1. Let us verify that the file was created and contains the expected content:
cat ~/project/hello.txt

You should see output similar to:

Hello from Ansible!
This file was created using the Ansible copy module.
Current date: 2023-08-15

The date will reflect the current date when you run the playbook.

Idempotence in Ansible

Idempotence is a key feature of Ansible - running the same playbook multiple times should produce the same result. Let us run the playbook again to see idempotence in action:

ansible-playbook create_file.yml

This time, you should see that the "changed" count is 0:

PLAY [Create a file with content] ***********************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create a simple text file] ***********************************************
ok: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

This shows that Ansible recognizes the file already exists with the correct content, so it does not modify it again.

Using Variables and Templates in Ansible

In this step, we will explore how to use variables and templates to create more dynamic files with Ansible.

Working with Variables

Variables make your playbooks more flexible and reusable. Let us create a playbook that uses variables to create a configuration file:

  1. Create a new file in the WebIDE in the ~/project/ansible-files directory:
    • Right-click on the directory and select "New File"
    • Name the file variables_demo.yml
    • Add the following content:
---
- name: Create files using variables
  hosts: local
  vars:
    app_name: "MyApplication"
    app_version: "1.0.0"
    port_number: 8080
    log_level: "INFO"
  tasks:
    - name: Create config file with variables
      copy:
        dest: "~/project/app_config.ini"
        content: |
          ## Configuration for {{ app_name }}
          ## Generated by Ansible

          [application]
          name = {{ app_name }}
          version = {{ app_version }}

          [server]
          port = {{ port_number }}
          log_level = {{ log_level }}

In this playbook:

  • The vars section defines variables that can be used throughout the playbook.
  • The variables are referenced using the {{ variable_name }} syntax.
  • The copy module is used to create a file with content that includes these variables.
  1. Now, let us run the playbook:
cd ~/project/ansible-files
ansible-playbook variables_demo.yml

You should see output similar to:

PLAY [Create files using variables] ********************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create config file with variables] ***************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  1. Let us examine the content of the generated file:
cat ~/project/app_config.ini

You should see output similar to:

## Configuration for MyApplication
## Generated by Ansible

[application]
name = MyApplication
version = 1.0.0

[server]
port = 8080
log_level = INFO

Using Jinja2 Templates

For more complex file content, Ansible supports Jinja2 templates. Let us create a template file and use it in a playbook:

  1. Create a templates directory:
mkdir -p ~/project/ansible-files/templates
  1. Create a template file in the WebIDE:
    • Navigate to the ~/project/ansible-files/templates directory
    • Right-click and select "New File"
    • Name the file web_config.j2
    • Add the following content:
## Web Server Configuration
## Generated by Ansible on {{ ansible_date_time.date }}

server {
    listen {{ web_port }};
    server_name {{ server_name }};

    location / {
        root {{ doc_root }};
        index index.html;
    }

    {% if enable_ssl %}
    ## SSL Configuration
    ssl_certificate {{ ssl_cert }};
    ssl_certificate_key {{ ssl_key }};
    {% endif %}
}
  1. Now create a playbook that uses this template:
    • Navigate to the ~/project/ansible-files directory
    • Right-click and select "New File"
    • Name the file template_demo.yml
    • Add the following content:
---
- name: Create files using templates
  hosts: local
  vars:
    web_port: 80
    server_name: "example.com"
    doc_root: "/var/www/html"
    enable_ssl: true
    ssl_cert: "/etc/ssl/certs/example.com.crt"
    ssl_key: "/etc/ssl/private/example.com.key"
  tasks:
    - name: Create web server config from template
      template:
        src: templates/web_config.j2
        dest: ~/project/web_server.conf

In this playbook:

  • The template module is used instead of copy.
  • The src parameter points to our template file.
  • The dest parameter specifies where to create the output file.
  • The variables defined in the vars section will be used in the template.
  1. Run the playbook:
cd ~/project/ansible-files
ansible-playbook template_demo.yml

You should see output similar to:

PLAY [Create files using templates] ********************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create web server config from template] **********************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  1. Let us examine the generated configuration file:
cat ~/project/web_server.conf

You should see output similar to:

## Web Server Configuration
## Generated by Ansible on 2023-08-15

server {
    listen 80;
    server_name example.com;

    location / {
        root /var/www/html;
        index index.html;
    }

    ## SSL Configuration
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
}

Notice how the Jinja2 template was rendered with our variables, and the conditional section for SSL was included because enable_ssl was set to true.

Advanced File Management with Ansible

In this final step, we will explore some advanced file management techniques with Ansible, including file permissions, conditional file creation, and using multiple file-related modules.

Setting File Permissions and Ownership

When creating files, you often need to set specific permissions and ownership. Let us create a playbook that demonstrates this:

  1. Create a new file in the WebIDE:
    • Navigate to the ~/project/ansible-files directory
    • Right-click and select "New File"
    • Name the file file_permissions.yml
    • Add the following content:
---
- name: Manage file permissions and ownership
  hosts: local
  tasks:
    - name: Create a script file with execute permissions
      copy:
        dest: ~/project/script.sh
        content: |
          #!/bin/bash
          echo "This script was created by Ansible"
          echo "Current user: $(whoami)"
          echo "Current directory: $(pwd)"
        mode: "0755"

    - name: Create a read-only configuration file
      copy:
        dest: ~/project/readonly.conf
        content: |
          ## This is a read-only configuration file
          setting1 = value1
          setting2 = value2
        mode: "0444"

In this playbook:

  • The mode parameter is used to set file permissions.
  • 0755 means read, write, and execute for the owner, and read and execute for group and others.
  • 0444 means read-only for everyone.
  1. Run the playbook:
cd ~/project/ansible-files
ansible-playbook file_permissions.yml

You should see output similar to:

PLAY [Manage file permissions and ownership] **********************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create a script file with execute permissions] **************************
changed: [localhost]

TASK [Create a read-only configuration file] **********************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  1. Let us check the permissions of the created files:
ls -l ~/project/script.sh ~/project/readonly.conf

You should see output similar to:

-rwxr-xr-x 1 labex labex 118 Aug 15 12:34 /home/labex/project/script.sh
-r--r--r-- 1 labex labex  73 Aug 15 12:34 /home/labex/project/readonly.conf
  1. Let us verify that the script can be executed:
~/project/script.sh

You should see output similar to:

This script was created by Ansible
Current user: labex
Current directory: /home/labex/project/ansible-files

Conditional File Creation

Sometimes you need to create files only when certain conditions are met. Let us create a playbook that demonstrates conditional file creation:

  1. Create a new file in the WebIDE:
    • Navigate to the ~/project/ansible-files directory
    • Right-click and select "New File"
    • Name the file conditional_file.yml
    • Add the following content:
---
- name: Conditional file creation
  hosts: local
  vars:
    environment: "development"
    create_debug_file: true
    create_backup: false
  tasks:
    - name: Create environment-specific configuration
      copy:
        dest: "~/project/{{ environment }}_config.yml"
        content: |
          ## Configuration for {{ environment }} environment
          debug: {{ 'enabled' if environment == 'development' else 'disabled' }}
          log_level: {{ 'DEBUG' if environment == 'development' else 'INFO' }}

    - name: Create debug log file
      copy:
        dest: ~/project/debug.log
        content: |
          ## Debug log file
          ## Created: {{ ansible_date_time.iso8601 }}
        mode: "0644"
      when: create_debug_file

    - name: Create backup directory
      file:
        path: ~/project/backup
        state: directory
        mode: "0755"
      when: create_backup

In this playbook:

  • The when directive is used for conditional execution of tasks.
  • Jinja2 conditionals are used in the file content to change values based on variables.
  • The file module is used to create a directory.
  1. Run the playbook:
cd ~/project/ansible-files
ansible-playbook conditional_file.yml

You should see output similar to:

PLAY [Conditional file creation] **********************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create environment-specific configuration] ******************************
changed: [localhost]

TASK [Create debug log file] **************************************************
changed: [localhost]

TASK [Create backup directory] ************************************************
skipped: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

Notice that the "Create backup directory" task was skipped because create_backup was set to false.

  1. Let us examine the created files:
cat ~/project/development_config.yml
cat ~/project/debug.log
ls -la ~/project/ | grep backup

You should see the contents of the two files that were created, and confirm that no backup directory was created.

Ansible provides several modules for file management. Let us create a playbook that demonstrates using multiple file-related modules:

  1. Create a new file in the WebIDE:
    • Navigate to the ~/project/ansible-files directory
    • Right-click and select "New File"
    • Name the file file_modules.yml
    • Add the following content:
---
- name: Demonstrate file-related modules
  hosts: local
  tasks:
    - name: Create a directory
      file:
        path: ~/project/ansible_demo
        state: directory
        mode: "0755"

    - name: Create a file using the copy module
      copy:
        dest: ~/project/ansible_demo/copied.txt
        content: "This file was created using the copy module.\n"

    - name: Create a symbolic link
      file:
        src: ~/project/ansible_demo/copied.txt
        dest: ~/project/ansible_demo/link_to_copied.txt
        state: link

    - name: Create a file with blockinfile module
      blockinfile:
        path: ~/project/ansible_demo/block.txt
        create: true
        block: |
          This is a block of text
          that will be inserted
          as a single unit.
        marker: "## {mark} ANSIBLE MANAGED BLOCK"

In this playbook:

  • The file module is used with state: directory to create a directory.
  • The file module is used with state: link to create a symbolic link.
  • The blockinfile module is used to create a file with a block of text surrounded by marker comments.
  1. Run the playbook:
cd ~/project/ansible-files
ansible-playbook file_modules.yml

You should see output similar to:

PLAY [Demonstrate file-related modules] ***************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Create a directory] *****************************************************
changed: [localhost]

TASK [Create a file using the copy module] ************************************
changed: [localhost]

TASK [Create a symbolic link] *************************************************
changed: [localhost]

TASK [Create a file with blockinfile module] **********************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  1. Let us verify the results:
ls -la ~/project/ansible_demo/
cat ~/project/ansible_demo/copied.txt
cat ~/project/ansible_demo/link_to_copied.txt
cat ~/project/ansible_demo/block.txt

You should see:

  • A directory called ansible_demo
  • A file called copied.txt with the specified content
  • A symbolic link called link_to_copied.txt pointing to copied.txt
  • A file called block.txt with a block of text surrounded by marker comments

The output of the last command should be similar to:

## BEGIN ANSIBLE MANAGED BLOCK
This is a block of text
that will be inserted
as a single unit.
## END ANSIBLE MANAGED BLOCK

This demonstrates the versatility of Ansible's file management capabilities.

Summary

Congratulations on completing this Ansible file management lab. You have learned several important concepts and techniques:

  1. How to install and configure Ansible for basic automation tasks
  2. Creating files with specific content using the copy module
  3. Using variables to make your file content dynamic
  4. Working with Jinja2 templates for more complex file generation
  5. Setting file permissions and ownership
  6. Implementing conditional file creation based on variables
  7. Using various Ansible modules for different file management tasks

These skills form a solid foundation for automating file management tasks in your infrastructure. With Ansible, you can ensure consistent file content across multiple servers, apply changes in a controlled manner, and maintain an auditable record of your configuration.

To continue your Ansible learning journey, consider exploring more advanced topics such as roles, playbook organization, and integrating Ansible with other DevOps tools.