Ansible 로 파일 내용 생성 방법

AnsibleBeginner
지금 연습하기

소개

Ansible 은 인프라 관리를 단순화하는 강력한 IT 자동화 도구입니다. 이 실습에서는 Ansible 을 사용하여 대상 시스템에 특정 내용의 파일을 생성하는 방법을 배우게 됩니다. 이 실습을 마치면 Ansible 파일 관리의 기본 사항을 이해하고 자체 인프라에서 자동화된 파일 생성을 구현할 수 있게 됩니다.

Ansible 설치 및 설정

파일 생성을 위해 Ansible 을 사용하기 전에 시스템에 설치하고 구성해야 합니다. 환경을 설정해 보겠습니다.

Ansible 설치

먼저 패키지 목록을 업데이트하고 Ubuntu 22.04 시스템에 Ansible 을 설치합니다.

sudo apt update
sudo apt install -y ansible

이 명령을 실행한 후 Ansible 이 성공적으로 설치되었음을 나타내는 출력을 볼 수 있습니다. 설치를 확인해 보겠습니다.

ansible --version

다음과 유사한 출력을 볼 수 있습니다.

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

간단한 Ansible 인벤토리 생성

Ansible 은 관리할 호스트를 정의하기 위해 인벤토리 파일을 사용합니다. 이 실습에서는 자체 머신을 포함하는 로컬 인벤토리를 생성합니다.

  1. Ansible 프로젝트를 위한 새 디렉토리를 생성합니다.
mkdir -p ~/project/ansible-files
cd ~/project/ansible-files
  1. VSCode 를 사용하여 인벤토리 파일을 생성합니다.
    • WebIDE 에서 탐색기 아이콘을 클릭합니다.
    • ~/project/ansible-files 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 inventory로 지정합니다.
    • 파일에 다음 내용을 추가합니다.
[local]
localhost ansible_connection=local

이 인벤토리 파일은 Ansible 에게 SSH 를 사용하지 않고 로컬 머신에서 명령을 실행하도록 지시합니다.

  1. 동일한 디렉토리에 간단한 ansible.cfg 파일을 생성합니다.
    • WebIDE 에서 탐색기 아이콘을 클릭합니다.
    • ~/project/ansible-files 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 ansible.cfg로 지정합니다.
    • 파일에 다음 내용을 추가합니다.
[defaults]
inventory = ./inventory
host_key_checking = False
  1. 간단한 Ansible 명령을 실행하여 설정을 확인해 보겠습니다.
cd ~/project/ansible-files
ansible local -m ping

다음과 유사한 출력을 볼 수 있습니다.

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

이것은 Ansible 이 로컬 머신에서 명령을 실행하도록 올바르게 설치 및 구성되었음을 확인합니다.

Ansible Playbook 을 사용하여 내용이 있는 파일 생성

이제 Ansible 을 설정했으므로 내용이 있는 파일을 생성하는 방법을 배우겠습니다. Ansible 은 파일을 관리하기 위한 여러 모듈을 제공하며, 이 단계에서는 copy 모듈에 집중합니다.

Ansible Playbook 이해

Ansible Playbook 은 대상 호스트에서 실행할 작업 집합을 설명하는 YAML 파일입니다. 각 작업은 특정 Ansible 모듈을 사용하여 작업을 수행합니다.

내용이 있는 파일을 생성하기 위해 첫 번째 playbook 을 만들어 보겠습니다.

  1. WebIDE 에서 ~/project/ansible-files 디렉토리에 새 파일을 생성합니다.
    • 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 create_file.yml로 지정합니다.
    • 다음 내용을 추가합니다.
---
- 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 }}

이 playbook 이 수행하는 작업을 이해해 보겠습니다.

  • hosts: local 줄은 이 playbook 이 인벤토리의 local 그룹에 있는 호스트에서 실행됨을 지정합니다.
  • tasks 섹션에는 실행할 작업 목록이 포함되어 있습니다.
  • copy 모듈은 내용이 있는 파일을 생성하는 데 사용됩니다.
  • dest 매개변수는 파일의 대상 경로를 지정합니다.
  • content 매개변수에는 파일에 기록될 텍스트 내용이 포함되어 있습니다.
  • {{ ansible_date_time.date }}는 playbook 이 실행될 때 현재 날짜로 대체될 변수입니다.
  1. 이제 playbook 을 실행해 보겠습니다.
cd ~/project/ansible-files
ansible-playbook create_file.yml

다음과 유사한 출력을 볼 수 있습니다.

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. 파일이 생성되었고 예상된 내용이 포함되어 있는지 확인해 보겠습니다.
cat ~/project/hello.txt

다음과 유사한 출력을 볼 수 있습니다.

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

날짜는 playbook 을 실행할 때 현재 날짜를 반영합니다.

Ansible 의 멱등성 (Idempotence)

멱등성은 Ansible 의 핵심 기능입니다. 동일한 playbook 을 여러 번 실행해도 동일한 결과가 생성되어야 합니다. 멱등성이 어떻게 작동하는지 확인하기 위해 playbook 을 다시 실행해 보겠습니다.

ansible-playbook create_file.yml

이번에는 "changed" 횟수가 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

이것은 Ansible 이 파일이 이미 올바른 내용으로 존재함을 인식하여 다시 수정하지 않음을 보여줍니다.

Ansible 에서 변수 및 템플릿 사용

이 단계에서는 Ansible 을 사용하여 보다 동적인 파일을 생성하기 위해 변수와 템플릿을 사용하는 방법을 살펴보겠습니다.

변수 사용

변수는 playbook 을 더 유연하고 재사용 가능하게 만듭니다. 변수를 사용하여 구성 파일을 생성하는 playbook 을 만들어 보겠습니다.

  1. WebIDE 에서 ~/project/ansible-files 디렉토리에 새 파일을 생성합니다.
    • 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 variables_demo.yml로 지정합니다.
    • 다음 내용을 추가합니다.
---
- 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 }}

이 playbook 에서:

  • vars 섹션은 playbook 전체에서 사용할 수 있는 변수를 정의합니다.
  • 변수는 {{ variable_name }} 구문을 사용하여 참조됩니다.
  • copy 모듈은 이러한 변수를 포함하는 내용으로 파일을 생성하는 데 사용됩니다.
  1. 이제 playbook 을 실행해 보겠습니다.
cd ~/project/ansible-files
ansible-playbook variables_demo.yml

다음과 유사한 출력을 볼 수 있습니다.

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. 생성된 파일의 내용을 살펴보겠습니다.
cat ~/project/app_config.ini

다음과 유사한 출력을 볼 수 있습니다.

## Configuration for MyApplication
## Generated by Ansible

[application]
name = MyApplication
version = 1.0.0

[server]
port = 8080
log_level = INFO

Jinja2 템플릿 사용

더 복잡한 파일 내용의 경우 Ansible 은 Jinja2 템플릿을 지원합니다. 템플릿 파일을 생성하고 playbook 에서 사용해 보겠습니다.

  1. 템플릿 디렉토리를 생성합니다.
mkdir -p ~/project/ansible-files/templates
  1. WebIDE 에서 템플릿 파일을 생성합니다.
    • ~/project/ansible-files/templates 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 web_config.j2로 지정합니다.
    • 다음 내용을 추가합니다.
## 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. 이제 이 템플릿을 사용하는 playbook 을 생성합니다.
    • ~/project/ansible-files 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 template_demo.yml로 지정합니다.
    • 다음 내용을 추가합니다.
---
- 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

이 playbook 에서:

  • template 모듈이 copy 대신 사용됩니다.
  • src 매개변수는 템플릿 파일을 가리킵니다.
  • dest 매개변수는 출력 파일을 생성할 위치를 지정합니다.
  • vars 섹션에 정의된 변수는 템플릿에서 사용됩니다.
  1. playbook 을 실행합니다.
cd ~/project/ansible-files
ansible-playbook template_demo.yml

다음과 유사한 출력을 볼 수 있습니다.

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. 생성된 구성 파일을 살펴보겠습니다.
cat ~/project/web_server.conf

다음과 유사한 출력을 볼 수 있습니다.

## 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;
}

Jinja2 템플릿이 변수로 렌더링되었고, enable_ssltrue로 설정되었기 때문에 SSL 에 대한 조건부 섹션이 포함된 것을 확인하세요.

Ansible 를 사용한 고급 파일 관리

이 마지막 단계에서는 파일 권한, 조건부 파일 생성, 여러 파일 관련 모듈 사용을 포함하여 Ansible 을 사용한 몇 가지 고급 파일 관리 기술을 살펴보겠습니다.

파일 권한 및 소유권 설정

파일을 생성할 때 특정 권한과 소유권을 설정해야 하는 경우가 많습니다. 이를 보여주는 playbook 을 만들어 보겠습니다.

  1. WebIDE 에서 새 파일을 생성합니다.
    • ~/project/ansible-files 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 file_permissions.yml로 지정합니다.
    • 다음 내용을 추가합니다.
---
- 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"

이 playbook 에서:

  • mode 매개변수는 파일 권한을 설정하는 데 사용됩니다.
  • 0755는 소유자에 대해 읽기, 쓰기 및 실행, 그룹 및 기타 사용자에 대해 읽기 및 실행을 의미합니다.
  • 0444는 모든 사용자에 대해 읽기 전용을 의미합니다.
  1. playbook 을 실행합니다.
cd ~/project/ansible-files
ansible-playbook file_permissions.yml

다음과 유사한 출력을 볼 수 있습니다.

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. 생성된 파일의 권한을 확인해 보겠습니다.
ls -l ~/project/script.sh ~/project/readonly.conf

다음과 유사한 출력을 볼 수 있습니다.

-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. 스크립트가 실행 가능한지 확인해 보겠습니다.
~/project/script.sh

다음과 유사한 출력을 볼 수 있습니다.

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

조건부 파일 생성

경우에 따라 특정 조건이 충족될 때만 파일을 생성해야 합니다. 조건부 파일 생성을 보여주는 playbook 을 만들어 보겠습니다.

  1. WebIDE 에서 새 파일을 생성합니다.
    • ~/project/ansible-files 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 conditional_file.yml로 지정합니다.
    • 다음 내용을 추가합니다.
---
- 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

이 playbook 에서:

  • when 지시문은 작업의 조건부 실행에 사용됩니다.
  • Jinja2 조건문은 변수를 기반으로 값을 변경하기 위해 파일 내용에 사용됩니다.
  • file 모듈은 디렉토리를 생성하는 데 사용됩니다.
  1. playbook 을 실행합니다.
cd ~/project/ansible-files
ansible-playbook conditional_file.yml

다음과 유사한 출력을 볼 수 있습니다.

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

create_backupfalse로 설정되었기 때문에 "Create backup directory" 작업이 건너뛴 것을 확인하세요.

  1. 생성된 파일을 살펴보겠습니다.
cat ~/project/development_config.yml
cat ~/project/debug.log
ls -la ~/project/ | grep backup

생성된 두 파일의 내용을 볼 수 있으며, 백업 디렉토리가 생성되지 않았음을 확인할 수 있습니다.

여러 파일 관련 모듈 사용

Ansible 은 파일 관리를 위한 여러 모듈을 제공합니다. 여러 파일 관련 모듈을 사용하는 playbook 을 만들어 보겠습니다.

  1. WebIDE 에서 새 파일을 생성합니다.
    • ~/project/ansible-files 디렉토리로 이동합니다.
    • 마우스 오른쪽 버튼을 클릭하고 "새 파일"을 선택합니다.
    • 파일 이름을 file_modules.yml로 지정합니다.
    • 다음 내용을 추가합니다.
---
- 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"

이 playbook 에서:

  • file 모듈은 state: directory와 함께 사용하여 디렉토리를 생성합니다.
  • file 모듈은 state: link와 함께 사용하여 심볼릭 링크를 생성합니다.
  • blockinfile 모듈은 마커 주석으로 둘러싸인 텍스트 블록으로 파일을 생성하는 데 사용됩니다.
  1. playbook 을 실행합니다.
cd ~/project/ansible-files
ansible-playbook file_modules.yml

다음과 유사한 출력을 볼 수 있습니다.

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. 결과를 확인해 보겠습니다.
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

다음과 같은 결과를 볼 수 있습니다.

  • ansible_demo라는 디렉토리
  • 지정된 내용이 있는 copied.txt라는 파일
  • copied.txt를 가리키는 link_to_copied.txt라는 심볼릭 링크
  • 마커 주석으로 둘러싸인 텍스트 블록이 있는 block.txt라는 파일

마지막 명령의 출력은 다음과 유사해야 합니다.

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

이것은 Ansible 의 파일 관리 기능의 다재다능함을 보여줍니다.

요약

이 Ansible 파일 관리 랩을 완료하신 것을 축하드립니다. 몇 가지 중요한 개념과 기술을 배우셨습니다.

  1. 기본 자동화 작업을 위해 Ansible 을 설치하고 구성하는 방법
  2. copy 모듈을 사용하여 특정 내용으로 파일 생성
  3. 파일 내용을 동적으로 만들기 위한 변수 사용
  4. 보다 복잡한 파일 생성을 위한 Jinja2 템플릿 사용
  5. 파일 권한 및 소유권 설정
  6. 변수를 기반으로 조건부 파일 생성 구현
  7. 다양한 파일 관리 작업을 위한 다양한 Ansible 모듈 사용

이러한 기술은 인프라에서 파일 관리 작업을 자동화하기 위한 견고한 기반을 형성합니다. Ansible 을 사용하면 여러 서버에서 일관된 파일 내용을 보장하고, 제어된 방식으로 변경 사항을 적용하며, 구성에 대한 감사 가능한 기록을 유지할 수 있습니다.

Ansible 학습 여정을 계속하려면 역할, playbook 구성 및 Ansible 을 다른 DevOps 도구와 통합하는 것과 같은 더 고급 주제를 탐색해 보십시오.