DevOps/Ansible

[Ansible] YAML에서의 multiline - 1

Intro


Ansible playbook을 생성하면서 자주사용하는 부분에서 YAML 형식에서의 multiline을 작성하는 법입니다. 글쓴이는 흔히 ansible.builtin.shelllineinblock을 사용할 때 많이 사용하고, YAML에서의 multiline이 궁금해서 찾아보다가 좋은 내용이 있어서 정리겸 공유합니다. (영문 블로그를 번역에는 오역이 있을꺼같아서 전체적인 예제를 소개하는 형식으로 포스팅합니다.)

  • 예제에서 실행되는 base playbook은 ansible-playbook -v playbook.yml 을 실행하고 변수를 각 해당하는 style로 대체하는 형식입니다.

playbook.yml

---
- hosts: localhost
  connection: local
  vars:
    my_pattern: |
      With his own sword,
      Which he did wave against my throat, I have ta’en
      His head from him.
  tasks:
    - debug:
        var: my_pattern



Styles


YAML에서의 block은 크게 두가지 기본 style이 있습니다.

  • literal
  • folded

두가지 방법은 각각 미묘한 특징을 가지고 있어 Ansible을 사용할때 구분해서 사용하면 좋습니다.


Literal

YAML specification에는 literal 은 "is the simplest, most restricted, and most readable scalar style"으로 표현합니다.

  • literal은 |(pipe)로 표현됩니다.
my_pattern: |
  With his own sword,
  Which he did wave against my throat, I have ta’en
  His head from him.

Output

ok: [localhost] => {                              
    "my_pattern": "With his own sword,\nWhich he did wave against my throat, I have ta’en\nHis head from him.\n"                                                  
}

모든 라인 breaking이 보존(유지)됨을 확인할 수 있습니다. 그리고 여러줄의 line breaking도 적용됩니다. (단, 마지막줄에서의 여러 linebreaking은 하나로 인식합니다.)

my_pattern: |
  With his own sword,
  Which he did wave against my throat, I have ta’en


  His head from him.


Output

ok: [localhost] => {                              
    "my_pattern": "With his own sword,\nWhich he did wave against my throat, I have ta’en\n\n\nHis head from him.\n"                                                  
}

Folded

YAML specification에는 folded는 "similar to the literal style; however, folded scalars are subject to line folding"으로 표현합니다.
즉, 다음과 의미를 가집니다. "Folding allows long lines to be broken anywhere a single space character separates two non-space characters"

  • folded은 >(greater-than sign)로 표현됩니다.
my_pattern: >
  With his own sword,
  Which he did wave against my throat, I have ta’en
  His head from him.

Output

ok: [localhost] => {
    "my_pattern": "With his own sword, Which he did wave against my throat, I have ta’en His head from him.\n"
}

line break들이 공백(space)로 변경되었습니다. 게다가, 마지막에 있는 line break 변경되지 않고 그대로 유지되었습니다.


하지만 두개 이상의 line breaks는 공백으로 치환하지 않고 그대로 적용됩니다. 아래의 예시는 3개의 line breaks를 테스트하였습니다.

my_pattern: >                                 
  With his own sword,


  Which he did wave against my throat, I have ta’en
  His head from him.

Output

ok: [localhost] => {
    "my_pattern": "With his own sword,\n\nWhich he did wave against my throat, I have ta’en His head from him.\n"
}

Single line break(한줄바꿈)은 공백으로 치환되고, 그 이상의 line breaks는 줄바꿈이 그대로 적용됩니다. literal과 마찬가지로 마지막 줄의 line break는 하나의 줄바꿈으로 적용됩니다.



Block Chomping


Chomping은 마지막 줄의 line break를 어떻게 해석할지 제어합니다.
YAML specification에서는 3가지 chomping 방법을 제공합니다.


Strip

-의 chomping indicator로 표시를 합니다. strip은 마지막 줄바꿈을 제외합니다.


Literal style에서

my_pattern: |-
  With his own sword,


  Which he did wave against my throat, I have ta’en

  His head from him.


Output

ok: [localhost] => {
    "my_pattern": "With his own sword,\n\n\nWhich he did wave against my throat, I have ta’en\n\nHis head from him."
}
  • 중간의 줄바꿈은 유지되고, 마지막줄의 줄바꿈은 제거되었습니다.

Folded style에서

my_pattern: >-
  With his own sword,


  Which he did wave against my throat, I have ta’en

  His head from him.


Output

ok: [localhost] => {
    "my_pattern": "With his own sword,\n\nWhich he did wave against my throat, I have ta’en\nHis head from him."
}
  • 중간의 줄바꿈은 2개와 1개로 인정되고, 마지막 줄바꿈은 전체 제거되었습니다.

Keeping

+의 chomping indicator로 표시를 합니다. keeping은 마지막 줄바꿈을 모두 유지합니다.


Literal style에서

my_pattern: |+
  With his own sword,


  Which he did wave against my throat, I have ta’en

  His head from him.


Output

ok: [localhost] => {
    "my_pattern": "With his own sword,\n\n\nWhich he did wave against my throat, I have ta’en\n\nHis head from him.\n\n\n"
}
  • 모든 줄바꿈이 보존되었습니다.

Folded style에서

my_pattern: >+
   With his own sword,


   Which he did wave against my throat, I have ta’en

   His head from him.


Output

ok: [localhost] => {
     "my_pattern": "With his own sword,\n\nWhich he did wave against my throat, I have ta’en\nHis head from him.\n\n\n"
 }
  • folded style도 예외없이 줄바꿈이 모두 보존되었습니다.

Clipping

Clipping은 default behavior입니다. 아무런 적용을 하지 않으면 각 style에 기본적으로 적용됩니다.



Summary

이번 post에서는 YAML의 block style에 multiline방법을 소개하였습니다. 다음 2편에서는 실제 Ansible module을 이용한 예시를 소개하겠습니다.



Ref

Understanding multi line strings in YAML and Ansible (Part II - Ansible)

'DevOps > Ansible' 카테고리의 다른 글

[Ansible] 자동으로 known_hosts에 등록하기  (0) 2020.12.01