1. 변수 사용

  • Ansible은 변수를 사용하여 시스템 간의 차이점을 관리
  • Ansible을 사용하면 단일 명령으로 여러 시스템에서 tasks와 playbooks을 실행 가능
  • 서로 다른 시스템 간의 변형을 나타내기 위해 lists와 dictionary을 포함한 표준 YAML 구문을 사용하여 변수 생성
  • playbooks, inventory, files, roles 그리고 명령줄에 변수를 정의
  • tasks의 출력값을 새 변수로 등록하여서 playbooks를 실행하는 동안 변수를 생성하여 사용 가능
  • tasks의 출력값을 새 변수로 등록하여, "when" 조건문 구문, templates, loops에서 사용 가능


2. 유효한 변수 이름 만들기

  • 모든 문자열을 Ansible 변수 이름으로 사용하지는 못함 → 변수 이름에는 문자, 숫자 및 밑줄만 포함 가능
  • Python 키워드 또는 playbooks 키워드는 변수 이름으로 사용 불가
  • 변수 이름은 숫자로 시작할 수 없음
  • 변수 이름은 밑줄로 시작할 수 있음
  • 많은 프로그래밍 언어에서 밑줄로 시작하는 변수를 private로 사용하지만, ansible에서는 일반 변수와 동일하게 사용됨
  • 개인 정보 보호 또는 보안으로 ansible에서 밑줄로 시작하는 변수를 사용하여도 효과 X
  • 유효한 변수 이름과 잘못된 변수 이름의 예시

3. 단순 변수

  • 단순 변수는 변수 이름에 하나의 값을 결합
  • 단순 변수는 lists 및 dictionaries 등 다양한 곳에서 사용 가능
  • 단순 변수는 playbooks, inventory, files, roles 그리고 명령줄에서 사용 가능

3.1. 단순 변수 정의

  • 표준 YAML 구문에 단일 변수를 정의
  • 단순 변수 사용 예시
    remote_install_path: /opt/my_app_config

3.2. 단순 변수 참조

  • 단순 변수를 정의한 후 Jinja2 구문을 사용하여 단순 변수 참조 가능
  • Jinja2 변수는 이중 중괄호로 호출 가능
  • playbooks에서 Jinja2 구문을 사용하여 위에 선언한 단순 변수를 참조 → 변수는 시스템마다 다를 수 있는 파일의 위치를 정의
  • 단순 변수 참조 예시
    ansible.builtin.template:
    src: foo.cfg.j2
    dest: '{{ remote_install_path }}/foo.cfg'

※ 참조

  • Ansible은 templates에서 Jinja2 loops와 Jinja2 conditions을 사용 가능
  • Ansible은 playbooks에서Jinja2 loops와 Jinja2 conditions을 사용 불가 → 작업 루프를 생성 불가
  • Ansible의 playbooks은 순수한 기계 구문 분석이 가능한 YAML으로 해당 설정이 적용이 안되는 것


4. Quotes 사용한 변수

  • 문자열에서는 큰 따옴표보다 작은 따옴표를 선호
  • 큰 따옴표는 작은 따옴표 안에 중첩되거나, 문자열에 이스케이프 문자가 필요한 경우에 사용
  • folded block scalar로 불리는 > 을 사용할 때, 문자열에 따옴표를 생략
  • Quotes를 사용하면 안되는 경우
    1. 부울논리(true or false)
    2. 숫자 (42, 17),
    3. Ansible 환경을 참조 (부울 논리 또는 값을 할당할 변수의 이름을 사용하는 경우)
  • 문자열이 YAML의 기본 유형이지만, Quotes를 사용하면 명시적으로 구문을 강조하여 더 좋아 보임
  • 따옴표 없이 변수를 사용하는 경우 변수 호출에 문제 발생 → ERROR! Syntax Error while loading YAML.
    - hosts: app_servers
      vars:
          app_path: {{ base_path }}/22
  • 따옴표를 추가하는 경우, Ansible가 제대로 작동
    - hosts: app_servers
      vars:
           app_path: "{{ base_path }}/22"


5. 변수 나열

  • 목록 변수는 변수 이름을 여러 값과 결합
  • 여러 값을 항목별 목록으로 저장하거나 []쉼표로 구분하여 대괄호 안에 저장 가능

5.1. lists 변수 정의

  • YAML에 lists를 사용하여 여러 값으로 변수를 정의 가능
  • lists 변수 사용 예시
    region:
      - northeast
      - southeast
      - midwest

5.2. lists 변수 참조

  • lists(배열)로 정의된 변수를 사용하는 경우 해당 lists의 개별 특정 필드 사용 가능
  • lists의 첫 번째 항목은 항목 0이고 두 번째 항목은 항목 1임 → 일반 프로그래밍 언어와 같이 0부터 시작
  • 예시 → region 이름을 가진 lists 표현식의 값은 "북동쪽"
    region: "{{ region[0] }}"


6. dictionary 변수

  • dictionary 변수는 키-값 쌍으로 데이터를 저장
  • 일반적으로 dictionary 변수는 ID 또는 사용자 프로필에 포함된 정보와 관련 데이터를 저장하는 데 사용

6.1. 변수를 키:값 사전으로 정의

  • YAML의 dictionary 변수는 복잡한 변수를 정의 가능
  • YAML의 dictionary 변수는 key와 value로 매핑
  • 예시
    foo:
      field1: one
      field2: two

6.2. 키:값 dictionary 변수 참조

  • 키:값 dictionary(해시)으로 정의된 변수를 사용할 때 대괄호 표기법이나 점 표기법을 사용하여 dictionary의 특정 필드를 사용 가능
  • 대괄호 표기법은 항상 작동
  • 점 표기법은 일부 키가 파이썬 dictionary의 속성 및 메소드와 충돌하기 때문에 문제 발생 가능 → 점 표기법보다는 대괄호 표기법 사용하는게 좋음
  • 예시 → 아래 두 예는 모두 동일한 값("하나")을 참조
    foo['field1']
    foo.field1

7. 변수 등록

  • Ansible의 task의 출력 결과를 저장하는 register 변수 생성

  • register에 저장된 변수는 when 키워드를 사용하여 조건문에 사용 가능

  • register 변수는 많은 영역에서 사용 가능

    1. 단순 변수(simple variables)
    2. lists 변수
    3. dictionary 변수
    4. 중첩 데이터 변수
  • register 변수는 메모리에 저장

  • register 변수는 playbooks의 실행기간 동안에만 사용 가능

  • 루프가 있는 작업에 변수를 등록하면 register 변수에는 루프의 각 항목에 대한 값이 저장 → 루프가 동작하는 동안 변수에 저장된 데이터는 모든 응답 목록에 사용 가능

  • 예시

    - hosts: web_servers
    
      tasks:
         - name: Run a shell command and register its output as a variable
           ansible.builtin.shell: /usr/bin/foo
           register: foo_result
           ignore_errors: true
    
         - name: Run a shell command using output of the previous task
           ansible.builtin.shell: /usr/bin/bar
           when: foo_result.rc == 5

※ 참조

  • task가 실패하거나 건너뛴 경우 Ansible은 실패 또는 건너뜀


8. 중첩 변수 참조

  • 많은 register 변수는 중첩된 YAML 또는 JSON 데이터 구조를 가짐
  • {{ foo }}와 같이 간단한 구조로는 중첩 데이터에 접근 불가능 → 대괄호 표기법이나 점 표기법을 사용해야 함
  • 대괄호 표기법을 사용하여 ansible_facts에서 IP 주소를 참조
    {{ ansible_facts["eth0"]["ipv4"]["address"] }}
  • 점 표기법을 사용하여 ansible_facts에서 IP 주소를 참조
    {{ ansible_facts.eth0.ipv4.address }}


9. multi line 사용방법

  • JSON으로 표현할 때, 데이터 내에 \n을 넣어주는 것은 힘듦
  • 하지만, YAML 파일에는 데이터 내에 \n을 넣어주는 것은 쉬움 → YAML에 넣어서 JSON으로 치환해주면 됨
  • YAML파일에 \n와 같이 개행문자을 넣는 2가지 방법 → > (folded block scalar) 와 | (literal block scalar)

9.1. > (folded block scalar)

  • 개행 문자(\n)를 스페이스로 치환

  • 빈 줄 하나가 단독으로 있는 경우 줄바꿈(\n)으로 변경

  • > 뒤에 -을 붙이면 맨 끝의 줄바꿈 문자를 포함시키지 않음

  • > 만 사용 → YAML 파일을 \n을 스페이스로 치환하고, 맨끝 개행(\n) 문자 포함한 JSON 파일로 변경

    # YAML
    paragraph1: >
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph1": "abc def ghi\naab ccc\n"
    }
  • > 와 -를 사용 → YAML 파일을 \n을 스페이스로 치환하고, 맨끝 개행(\n) 문자는 제외한 JSON 파일로 변경

    # YAML
    paragraph2: >-
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph2": "abc def ghi\naab ccc"

9.2. | (literal block scalar)

  • 기록한 그대로 줄을 변경

  • 라인의 맨 마지막은 \n으로 표시

  • 빈줄은 \n을 표시

  • | 뒤에 -을 붙이면 맨 끝의 줄바꿈 문자를 포함시키지 않음

  • | 만 사용 → YAML 파일에 표시된 형식을 JSON 파일 그대로 변경, 맨 끝 개행문자(\n) 포함

    # YAML
    paragraph3: |
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph3": "abc\ndef\nghi\n\naab\nccc\n"
    }
  • | 와 -를 사용 → YAML 파일에 표시된 형식을 JSON 파일 그대로 변경, 맨 끝 개행문자(\n) 제외

    # YAML
    paragraph4: |-
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph4": "abc\ndef\nghi\n\naab\nccc"
    }



10. 변수 설정 위치

  • playbooks, inventory, files, roles 그리고 명령줄은 다양한 위치에서 변수를 정의 가능
  • Ansible은 사용 가능한 변수를 모두 로드한 다음 변수 우선 순위 규칙에 따라 적용할 변수를 선택

10.1. inventory의 변수 정의

  • 각 개별 호스트에 대해 서로 다른 변수를 정의하거나 inventory의 호스트 그룹에 대해 공유 변수를 설정 가능
  • inventory는 호스트 변수 및 그룹 변수를 저장

10.2. playbook에서 변수 정의하기

  • playbooks에서 직접 변수를 정의 가능
  • playbook에서 변수를 정의하면 해당 playbook에서 실행되는 tasks에만 사용 가능.
    - hosts: webservers
      vars:
        http_port: 80

10.3. include files 및 roles에서 변수 정의

  • include files 또는 roles에서 변수를 정의

  • 민감한 변수는 playbooks에 제외하고, include files 또는 roles에 변수를 정의 필요 → 암호나 기타 민감한 개인 데이터가 노출될 위험 없이 playbook을 소스 제어 소프트웨어에 저장하고 공유 가능

  • 외부 파일에 정의된 변수를 포함하는 방법

    ---
    - hosts: all
      remote_user: root
      vars:
        favcolor: blue
      vars_files:
        - /vars/external_vars.yml
    
      tasks:
      - name: This is just a placeholder
        ansible.builtin.command: /bin/echo foo
  • external_vars.yml 파일은 변수들을 저장하는 YAML파일로 playbooks에 선언하여 사용
    $ vi /vars/external_vars.yml
    ---
    # in the above example, this would be vars/external_vars.yml
    somevar: somevalue
    password: magic

※ 참조

  • 호스트별 및 그룹별 변수를 유사한 파일에 보관
  • 변수 구성에 대해 배우려면 호스트 및 그룹 변수 구성을 참조


11. 런타임에 변수 정의

  • --extra-vars 또는 -e 옵션을 사용하여 명령줄에 변수를 정의하여 playbook 실행에 사용
  • vars_prompt(대화협 입력)을 사용하여 사용자 입력을 요청 가능
  • 명령줄에서 변수를 전달할 때 아래 형식 중 하나로 하나 이상의 변수를 포함하는 작은 따옴표로 묶인 문자열을 사용
  • --extra-vars 옵션을 사용하는 예시 → 12. ansible-playbook을 사용하여 netbox 설치 -> extra-vars 변수 2개 사용

11.1. 키=값 형식

  • key=value 구문을 사용하여 값을 전달
  • 전달된 값은 문자열로 해석
    ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

11.2. JSON 문자열 형식

  • 부울, 정수, 부동 소수점, 목록 등과 같은 문자열이 아닌 값을 전달해야 하는 경우 JSON 형식을 사용해야함
  • 변수를 전달할 때 --extra-vars 마크업(예: JSON)과 셸 모두에 적절하게 따옴표 및 기타 특수 문자를 이스케이프해야 함
    ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
    ansible-playbook arcade.yml --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
  • 특수 문자가 많은 경우 변수 정의가 포함된 JSON 또는 YAML 파일을 사용
    ansible-playbook arcade.yml --extra-vars "{\"name\":\"Conan O\'Brien\"}"
    ansible-playbook arcade.yml --extra-vars '{"name":"Conan O'\\\''Brien"}'
    ansible-playbook script.yml --extra-vars "{\"dialog\":\"He said \\\"I just can\'t get enough of those single and double-quotes"\!"\\\"\"}"

11.3. JSON 또는 YAML 파일에 vars를 정의하여서 --extra-vars를 사용

  • JSON이나, YAML파일을 사용할 때 --extra-vars를 사용 예시
    ansible-playbook release.yml --extra-vars "@some_file.json"


12. 변수 우선 순위: 변수를 어디에 넣어야 할까??

  • 여러 위치에서 동일한 이름으로 여러 변수를 설정 가능 → Ansible은 사용 가능한 변수를 모두 로드한 다음 변수 우선 순위 규칙에 따라 적용할 변수를 선택
  • 다른 변수가 특정 순서로 서로를 무시 → 각 변수를 한 곳에서 정의하는 것이 좋음(변수를 정의할 위치를 단순하게 하는 것이 효율적)
  • 설정의 우선 순위에 따라 의도하지 않은 결과가 나올 수 있기에 주의하여서 변수를 정의하는 것이 중요
  • ansible 변수의 우선 순위(1번이 우선 순위가 낮음이고, 21번이 우선순위가 높음임)


+ Recent posts