구성 시간을 절약하기 위해 Ansible 템플릿 생성하는 방법

다중 서버 및 환경의 구성을 관리하는 것은 Ansible의 큰 장점입니다. 그러나 서버마다 구성 파일이 다른 경우에는 별도의 구성 파일을 생성하는 대신 Ansible 템플릿을 사용해야 합니다.

이 자습서에서는 Ansible 템플릿이 무엇인지, 어떻게 작동하며 Ansible 템플릿 모듈을 사용하여 시간을 절약하는 방법을 배우게 될 것입니다.

준비 사항

이 글은 단계별 자습서입니다. 따라하려면 Ansible 컨트롤러 호스트가 필요합니다. 이 자습서에서는 Ansible v2.9.18을 사용합니다.

Ansible 템플릿이란 무엇인가요?

가끔은 텍스트 파일을 원격 호스트로 전송해야 할 때가 있습니다. 이러한 텍스트 파일은 일반적으로 구성 파일입니다. 예를 들어 단일 서버에서 작업하는 경우, app.conf라는 구성 파일을 생성해야 할 수 있습니다.

구성 파일에는 호스트 이름, IP 주소 등과 같이 해당 서버에 특정한 정보가 포함될 수 있습니다. 단일 서버와 작업하고 있으므로, Ansible 컨트롤러에서 파일을 생성한 다음 복사 모듈플레이북에서 사용하여 서버로 복사할 수 있습니다.

하지만 여러 개의 웹 서버가 각각 고유한 값이 필요한 동일한 구성 파일이 필요한 경우 어떻게 해야 할까요? 모든 기계에 구성 파일을 그대로 복사할 수는 없습니다. 구성 파일은 특정 호스트 이름, IP 주소 등을 갖고 있는 단일 서버용으로 만들어져 있습니다. Ansible 템플릿이 필요합니다.

Ansible 템플릿을 사용하면 정적인 값 대신 변수를 사용하여 플레이북 실행 중에 변수를 대체할 수 있습니다.

Ansible 템플릿은

Jinja2 템플릿 언어로 구성된 텍스트 파일이며, j2 확장자를 가지고 있습니다. Jinja2 템플릿은 원격 호스트에 배포하려는 텍스트 파일과 정확히 동일한 모습을 가지고 있습니다. 유일한 차이점은 정적인 값 대신 파일에 변수가 포함되어 있다는 것입니다.

예를 들어, 각 웹서버에 서버의 IP 주소, Ansible 호스트 및 Ansible 사용자에 대한 참조가 포함된 app.conf라는 구성 파일을 가져와야 할 수도 있습니다. 단일 서버의 app.conf 파일은 아래 예시와 같을 수 있습니다.

my_ip    = "192.168.0.1"
my_host  = "ANSBILECONTROL"
my_user  = "ansible_user"

각 항목은 원격 호스트의 IP, Ansible 컨트롤러의 호스트 이름 및 Ansible 사용자에 따라 고유합니다. 이 파일을 각 웹서버로 복사할 수 없습니다.

각각의 값을 정적으로 설정하는 대신, Ansible 템플릿을 사용하면 실행 시간에 해석되고 원격 호스트에서 대체되는 변수를 정의할 수 있습니다.

아래에는 app.conf.j2 템플릿 파일의 예시가 있습니다. 이제 각 정적 값이 양쪽에 중괄호로 표시된 변수로 대체된 것을 볼 수 있습니다. 이 경우, 이러한 변수는 Ansible 팩트에서 가져옵니다.

템플릿 파일은 항상 J2 파일 확장자를 가지며 대상 호스트에서 생성되는 파일과 동일한 이름을 일반적으로 가집니다.

my_ip    = "{{ansible_default_ipv4["address"]}}"
my_host  = "{{ansible_host}}"
my_user  = "{{ansible_user}}"

원격 호스트에 템플릿 파일을 어떻게 생성합니까?

템플릿을 생성한 후, 해당 템플릿 파일을 원격 호스트로 전송하여 실제 텍스트 파일로 “변환”해야 합니다. 이를 위해 플레이북에서 템플릿 파일을 참조해야 합니다.

대부분의 Ansible 관리자는 원격 호스트로 파일을 전송하기 위해 copy 모듈을 사용하지만, 위에서 언급한대로 템플릿으로는 이 작업을 수행할 수 없습니다.

아래에서는 플레이북에서 간단한 예제 참조를 볼 수 있습니다. 이 예제는 app.conf 파일을 플레이북의 대상 호스트들의 /opt 디렉토리로 복사하는 작업입니다.

- name: copy file from local host to remote host
  copy:                               # Declaring Copy Module 
    src: "app.conf"                   # Source Location 
    dest: "/opt/app.conf"             # Destination Location on remote host

이제 이전 섹션에서 언급한대로 Ansible 컨트롤러에서 app.conf 구성 파일을 app.conf.j2 템플릿 파일로 변환했다고 가정해 봅시다. 이제 변수들이 실제 값으로 대체된 app.conf 파일이 /opt 디렉토리로 이동되어야 합니다.

플레이북에게 app.conf 파일을 /opt 디렉토리에 생성하도록 지시하기 위해, 아래와 같이 copy 참조를 template으로 대체하면 됩니다. 이렇게 하면 Ansible은 template 모듈을 호출하여 템플릿을 전송하고 변수를 정적인 값으로 대체합니다.

- name: template file to remote host
  template:                 # Ansible template module
    src: "app.conf.j2"      # This is template src i.e source location 
    dest: "/opt/app.conf"   # Destination of Remote host

위의 작업이 플레이북에서 실행되면 Ansible은 app.conf.j2 파일을 원격 호스트의 /opt 디렉토리로 복사하고, 내부의 모든 변수를 정적인 값으로 대체한 후 파일 이름을 app.conf로 변경합니다.

템플릿 src에 디렉토리 경로를 제공하면 Ansible은 //files/ 디렉토리에서 템플릿을 찾습니다. 파일 이름만 제공하는 경우, 대신 //templates/ 디렉토리에서 템플릿을 찾습니다.

환경 설정 파일 렌더링: 템플릿 예시

이제 Ansible 템플릿을 설정하고 Ansible 템플릿 모듈을 사용하여 동적으로 구성 파일을 생성하는 방법을 확인하기 위해 데모로 넘어갑시다. 이 예시에서는 app.conf라는 파일을 /etc 디렉토리에 SRV1라는 서버에 생성합니다.

이 섹션의 단계는 모든 종류의 텍스트 파일에 대해 작동합니다. 이 튜토리얼에서는 구성 파일을 단일 예시로 사용합니다.

1. 일반적으로 Ansible을 관리하는 데 사용하는 사용자로 Ansible 컨트롤러 호스트에 SSH로 로그인합니다.

2. 이 튜토리얼의 데모 파일을 보관할 홈 디렉토리의 폴더를 생성하고 작업 디렉토리를 해당 폴더로 변경합니다.

mkdir ~/ansible_template_demo
cd ~/ansible_template_demo

3. 다음과 같이 보이는 디렉토리에 app.conf.j2라는 템플릿 파일을 생성합니다.

my_ip = {{ansible_default_ipv4["address"]}}
my_host  = {{ansible_host}}
my_user  = {{ansible_user}}

템플릿 내에서 Ansible 템플릿 모듈에 특정한 변수도 사용할 수 있습니다.

4. 같은 디렉토리에 my_playbook.yml라는 간단한 플레이북을 생성합니다. 이 플레이북은 app.conf 파일을 /etc 디렉토리에 생성합니다.


name: Ansible template example 
hosts: myserver 
remote_user: ubuntu   # Using Remote host as ubuntu 
tasks: 
 - name: Create the app.conf configuration file
   template:
     src: "~/ansible_template_demo/app.conf.j2"
     dest: "/etc/app.conf"
   become: true 

5. SRV1 원격 호스트를 대상으로 하는 Ansible 플레이북을 실행합니다.

ansible-playbook my_playbook.yml --inventory SRV1
You should then see Ansible execute the playbook.

6. 이제 /etc/app.conf 구성 파일이 존재하고 예상한 값이 있는지 확인하세요.

confirm the /etc/app.conf configuration file

템플릿 모듈을 사용하여 파일 권한 업데이트

템플릿 모듈 사용의 기본을 보았으므로 이제 좀 더 고급 기능에 대해 알아보겠습니다. 이 데모에서는 이전에 보여준 것과 같은 app.conf 파일을 생성합니다. 하지만 이번에는 파일 소유자와 권한을 설정할 것입니다.

템플릿 모듈이 생성하는 파일의 권한을 변경하려면 플레이북 내에서 세 개의 매개변수를 사용해야 합니다:

  • owner – 파일 소유자
  • group – 파일이 속해야 할 그룹
  • mode – 권한. 이 문자열은 기호로 표시하거나 8진수로 표시할 수 있습니다

기호 모드에서, u는 “사용자”를, g는 “그룹”을, o는 “기타”를 나타냅니다.

이전 섹션에서 생성한 ~/ansible_template_demo 폴더가 있는 경우, my_playbook.yml 플레이북을 열고 아래 내용으로 대체하십시오. 이 예제에서 Ansible은 연결 변수를 사용하여 소유자와 그룹을 Ansible 사용자로 설정합니다. 그런 다음 파일 권한을 0644로 설정합니다. 이는 다음을 나타냅니다:

  • 소유자에게 읽기/쓰기 권한이 있음
  • 그룹의 사용자 및 다른 모든 사용자에게 읽기 권한이 있음
---
- name: Ansible file permission example
  remote_user: ubuntu
  tasks:
    - name: Create the app.conf configuration file and assign permissions
      template:
          src: "~/ansible_template_demo/app.conf.j2"
          dest: "/etc/app.conf"
	  owner: "{{ ansible_user }}"
          group: "{{ ansible_user }}"
          mode:  0644 ## OR  mode: u=rw, g=w,o=r       
      become: true

사용 가능한 모든 템플릿 모듈 매개변수는 Ansible 템플릿 모듈 설명서에서 찾을 수 있습니다.

이제 아래에 표시된대로 플레이북을 다시 실행하십시오.

ansible-playbook my_playbook.yml --inventory SRV1

이제 app.conf에 예상한 파일 권한이 할당되어 있는 것을 확인할 수 있습니다.

app.conf

여러 파일에 템플릿 루프 사용하기

하나의 파일만으로는 충분하지 않은 경우, 원격 호스트에 여러 파일을 추가해야 할 수 있습니다. 이 경우, 템플릿 모듈과 루프를 함께 사용할 수 있습니다. loop 매개변수를 사용하여 루프를 정의하면 디렉토리에 저장된 여러 텍스트 파일을 추가할 수 있습니다.

이전 섹션에서 생성한 ~/ansible_template_demo 폴더가 있는 경우, 이미 app.conf.j2 파일이 있어야 합니다.

1. 아래에 표시된대로 app2.conf.j2라는 두 번째 템플릿 파일을 ~/ansible_template_demo 폴더에 생성합니다.

 template_host = "{{ template_host }}"
 template_uid = "{{ template_uid }}"
 template_path = "{{ template_path }}"
 template_fullpath = "{{ template_fullpath }}"
 template_run_date = "{{ template_run_date }}"

2. my_playbook.yml 파일을 열고 아래의 YAML로 모든 내용을 대체합니다. 이 플레이북은 {{item}} 변수를 사용하여 각 템플릿 파일을 처리하는 루프를 나타냅니다. loop 매개변수는 루프가 처리할 각 템플릿 파일을 정의합니다.

---
- name: Ansible file permission example 
  remote_user: ubuntu 
  tasks: 
   - name: Create the app.conf configuration file and assign permissions 
     template:   
        src: "~/ansible_template_demo/{{item}}.j2"    # 2개의 템플릿을 반복 처리합니다   
        dest: "/etc/{{item}}"
        owner: "{{ ansible_user }}"   
        group: "{{ ansible_user }}"   
        mode:  0644 ## 또는  mode: u=rw, g=w,o=r로 설정합니다        
     become: true     
     loop: # 템플릿 모듈에 이러한 각 템플릿을 찾고 처리하도록 지시합니다                                              
      - app1.conf 
      - app2.conf 

3. 이제 플레이북을 다시 실행합니다. ansible-playbook my_playbook.yml --inventory SRV1

ansible-playbook my_playbook.yml --inventory SRV1
Notice now that Ansible sees each template file and processes them accordingly.

결론

Ansible 템플릿과 템플릿 모듈은 시간을 절약하고 원격 호스트의 동적 텍스트 파일을 생성할 수 있습니다. copy 모듈은 유사한 기능을 제공하지만 동적 텍스트 파일을 생성해야 하는 경우 템플릿 모듈을 사용하세요.

Source:
https://adamtheautomator.com/ansible-template/