어쩌다 IT
article thumbnail
반응형

리뷰 (Review)

더보기

모듈

  • Ansible을 이용하여 Managed node에 대해 구성 관리(환경 설정)를 수행하는 실질적인 동작 수행
  • 모듈은 namespace 단위로 관리
  • namespace는 모듈의 집합을 의미
  • 모듈은 기본적으로 멱등성을 가지고 있다.
  • command, shell, raw 모듈은 멱등성이 반영되지 않는다.

 

YAML

  • 데이터를 표현하는 목적으로 사용하는 script 형식
  • 선언 정보나 환경 설정 정보를 기술하는 목적으로 활용
  • YAML은 단계 표현을 위한 들여쓰기는 스페이스 2칸을 사용, tap 사용 시 오류 발생

 

Playbook

  • 인벤토리에 정의된 Managed node에서 무엇을 해야 할 것인가(서버 환경 구성 정보)를 정의한 내용
  • YAML 포맷으로 표현
  • 설정이나 프로세스에 대한 모델 정의를 표현한 최소한의 문법으로 구성
  • Playbook의 목표는 Managed node 그룹을 정의된 Ansible 내에서 Task로 불리는 역할(role)에 매핑해 주는 것
  • 임의의 이름으로 Playbook 파일을 작성하고 확장자는 .yml 부여

Playbook 이해

 

Playbook 구조

 

  • Playbook - Play 집합


  • Playbook - Play - Task 구조
    • Playbook - Play 집합
    • Play -  Managed node에 적용할 여러 작업 코드의 집합, 한 번에 수행할 작업 단위, task 모음
    • Task - 실제 수행할 작업 내용, 모듈로 표현


  • Playbook의 Play 코드 구조
    • ---
      • Playbook 문서 시작
    • 타겟 부분 (필수 사항)
      • play에 대한 공통 정보
      • 실행 장비, 사용자 정보 등
      • name attribute
        • Play가 어떤 목적을 가지는지 설명하는 내용
        • Playbook 실행 시 출력되는 내용
        • 생략할 수 있다.
      • hosts attribute
        • Play가 적용될 Managed node에 대한 이름 (host 이름)
        • 인벤토리에 정의된 이름 사용
      • user attribute
        • Play를 적용할 사용자 ID
      • become attribute
        • 관리자 권한으로 권한 상승 유무 명시
        • Play 차원에서 관리자 권한 상승 유무 명시
      • become_user attribute
        • 관리자 권한을 갖는 사용자 명시
        • Play 차원에서 관리자 권한을 갖는 사용자 명시
      • gather_facts attribute
        • Managed node에 대한 fact 정보 수집 유무 확인
        • default - gather_facts: True
        • fact 정보 - Managed node에 대한 O/S, IP Address, Hostname 등 정보
        • Managed node에 대한 fact 정보 수집을 활성화하게 되면 동작 속도가 느려진다.
    • 변수 부분 (선택 사항)
      • Play 전체에서 사용하는 변수 목록
      • 변수 사용 시에만 기술되는 부분
      • vars - 변수 부분 명시
      • vars_files - 변수를 가지고 있는 외부 파일 기술 부분
    • 테스크 부분 (필수 사항)
      • Task 목록, 실제 수행할 모듈
      • name task attribute
        • 하나의 테스크 설명
        • name attribute의 내용을 기술하지 않아도 되나 실제로는 대부분 기술한다.
      • Managed node에서 수행할 모듈 명시

# Playbook 시작
---

# 타겟 부분 - Play
- name: ping test
  hosts: managed
  gather_facts: False
  # 변수 부분
  vars:
    test: 10
  # 테스크 부분 - Task
  tasks:
    - name: ping module
      # 모듈
      ping:
    - name: current directory
      shell:
        cmd: pwd

  • Playbook - Play - Role 구조
    • Role
      • 불필요하게 중복되는 소스를 제거하고 자주 사용하는 기능을 재사용하기 위해 사용하는 task 코드 집합
      • 라이브러리 (Library)
        • 통상 프로그래밍 언어에서 함수(function)를 모아놓은 파일을 의미
        • Role을 라이브러리로 생각할 수 있다.
      • YAML 형식으로 작성


  • Ansible Playbook을 이용한 Managed node 관리를 위한 프로젝트 구조
    • Managed node를 관리하기 위한 코드들을 체계적으로 관리하기 위해 프로젝트 형식으로 디렉토리 조직화
      • Ansible 프로젝트 - Managed node에 적용할 환경 구성을 위해 필요한 파일 집합 
      • group_vars - 공통 변수 저장 파일(YAML 형식) 저장 디렉토리
      • hosts - 인벤토리 파일 저장 디렉토리
      • playbooks - Playbook 파일 저장 디렉토리
      • roles - Role 파일 저장 디렉토리


 

GitHub - ansible/ansible-examples: A few starter examples of ansible playbooks, to show features and how they work together. Se

A few starter examples of ansible playbooks, to show features and how they work together. See http://galaxy.ansible.com for example roles from the Ansible community for deploying many popular appl...

github.com


변수와 fact 이해

 

변수 (Variable)

  • 값을 저장하는 메모리 영역
  • Ansible은 프로그래밍 언어는 아니지만 일부 프로그래밍 언어의 특징을 갖고 있다.
  • 가장 중요한 특징 중 하나는 변수 대체(variable substitution)이다.
  • 참고 자료

 

Play 변수 정의

  • vars 섹션에 key(변수 이름)와 value(값) 정의
    • Play에서 사용할 수 있는 변수
    • key: value 형식으로 정의
# 예시
vars:
key_file: /etc/nginx/ssl/nginx.key

 

  • vars_files 섹션을 이용하여 변수로 구성된 파일을 지정할 수 있다.
    • 중요 정보가 포함된 변수를 분리하여 관리
# 예시
nginx.yml	# 변수 저장 파일
key_file: /etc/nginx/ssl/nginx.key

# 예시
vars_files:	# Playbook의 vars_files 섹션
  - nginx.yml

 

  • 변수 사용
    • debug 모듈 사용
    • msg 파라미터 사용하여 변수 내용 출력
    • 변수 내용을 사용하고자 할 때는 "{{변수명}}" 형식으로 사용
    • debug 모듈을 이용하여 변수 출력 시 msg="{{변수명}}" 형식으로 사용해야 변수 내용을 출력할 수 있다.
---
- name: variable test
  hosts: managed
  gather_facts: False

  vars:
    message: Ansible variable test
  
  tasks:
    - name: debug module test
      debug:
        msg:

    - name: print variable
      debug:
        msg="{{message}}"
      # msg:"{{message}}"로도 사용 가능
[ec2-user@ip-12-12-12-12 work-ansible]$ ansible-playbook var_test.yml -i ./hosts

PLAY [variable test] ************************************************************************************************************

TASK [debug module test] ********************************************************************************************************
ok: [host1] => {
    "msg": null
}
ok: [host2] => {
    "msg": null
}
ok: [host3] => {
    "msg": null
}

TASK [print variable] ***********************************************************************************************************
ok: [host1] => {
    "msg": "Ansible variable test"
}
ok: [host2] => {
    "msg": "Ansible variable test"
}
ok: [host3] => {
    "msg": "Ansible variable test"
}

PLAY RECAP **********************************************************************************************************************
host1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host3                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[ec2-user@ip-12-12-12-12 work-ansible]$

 

  • Task 결과 변수 저장
    • Task 동작 결과에 따라 변수를 설정 시 모듈을 호출할 때 register를 사용하여 변수 생성
    • error 발생하더라도 무시하고 계속 실행하고자 한다면 ignore_errors True 설정하면 된다.
---
- name: task variable test
  hosts: private
  gather_facts: False

  vars:
    file_path: /home/ec2-user/work-jinook

  tasks:
    - name: create directory
      file:
        path: "{{file_path}}"
        state: directory
      register: result
      ignore_errors: True

    - name: change directory
      shell:
        cmd: cd "{{file_path}}"
      register: foo_result
      ignore_errors: True
    
    - name: print result
      debug:
        msg: "foo result -> {{foo_result}} | result -> {{result}}"
[ec2-user@ip-12-12-12-12 work-ansible]$ ansible-playbook var_test.yml -i ./hosts
PLAY [task variable test] *******************************************************************************************************

TASK [create directory] *********************************************************************************************************
ok: [host3]
TASK [change directory] *********************************************************************************************************
changed: [host3]

TASK [print result] *************************************************************************************************************
ok: [host3] => {
    "msg": "foo result -> {'stderr_lines': [], u'changed': True, u'end': u'2022-09-22 06:20:43.177548', 'failed': False, u'stdout': u'', u'cmd': u'cd \"/home/ec2-user/work-jinook\"', u'rc': 0, u'start': u'2022-09-22 06:20:43.138926', u'stderr': u'', u'delta': u'0:00:00.038622', 'stdout_lines': []} | result -> {u'group': u'ec2-user', u'uid': 1000, u'changed': True, 'failed': False, u'state': u'directory', u'gid': 1000, u'mode': u'0775', u'diff': {u'after': {u'path': u'/home/ec2-user/work-jinook', u'state': u'directory'}, u'before': {u'path': u'/home/ec2-user/work-jinook', u'state': u'absent'}}, u'owner': u'ec2-user', u'path': u'/home/ec2-user/work-jinook', u'size': 6}"
}

PLAY RECAP **********************************************************************************************************************
host1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host3                      : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[ec2-user@ip-12-12-12-12 work-ansible]$

 

  • 변수를 활용하여 Playbook을 동적으로 수행
더보기
---
- name: create directory & change directory
  hosts: private
  gather_facts: False

  tasks:
  - name: create directory
    file:
      path: "/home/ec2-user/{{file_name}}"
      state: directory
    register: result_create
  
  - name: change directory
    shell: cd "/home/ec2-user/{{file_name}}"
  
  - name: debug
    debug:
      var: result_create
[ec2-user@ip-12-12-12-12 work-ansible]$ ansible-playbook dir_manager.yml -i ./hosts -e "file_name=work2"

PLAY [create directory & change directory] **************************************************************************************

TASK [create directory] *********************************************************************************************************
changed: [host3]

TASK [change directory] *********************************************************************************************************
changed: [host3]

TASK [debug] ********************************************************************************************************************
ok: [host3] => {
    "result_create": {
        "changed": true, 
        "diff": {
            "after": {
                "path": "/home/ec2-user/work2", 
                "state": "directory"
            }, 
            "before": {
                "path": "/home/ec2-user/work2", 
                "state": "absent"
            }
        }, 
        "failed": false, 
        "gid": 1000, 
        "group": "ec2-user", 
        "mode": "0775", 
        "owner": "ec2-user", 
        "path": "/home/ec2-user/work2", 
        "size": 6, 
        "state": "directory", 
        "uid": 1000
    }
}

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

[ec2-user@ip-12-12-12-12 work-ansible]$

---
- name: copy file
  hosts: "{{host_name}}"
  gather_facts: False

  tasks:
  - name: copy file
    copy:
      src: "{{src_file}}"
      dest: "{{dest_file}}"
    register: result
  
  - name: confirm copy
    shell: ls -lF "{{dest_file}}"

  - name: debug
    debug:
      var: result
[ec2-user@ip-12-12-12-12 work-ansible]$ ansible-playbook file_copy.yml -i ./hosts -e "host_name=public src_file=./hosts dest_file=/home/ec2-user"

PLAY [copy file] ****************************************************************************************************************

TASK [copy file] ****************************************************************************************************************
changed: [host1]
changed: [host2]

TASK [confirm copy] *************************************************************************************************************
changed: [host1]
changed: [host2]

TASK [debug] ********************************************************************************************************************
ok: [host1] => {
    "result": {
        "changed": true, 
        "checksum": "c4a0561bd0cf1ead4194c2f571edeec08201a53d", 
        "dest": "/home/ec2-user/hosts", 
        "diff": [], 
        "failed": false, 
        "gid": 1000, 
        "group": "ec2-user", 
        "md5sum": "d9852837b7677f6d2f9dd9061773f8c5", 
        "mode": "0664", 
        "owner": "ec2-user", 
        "size": 1559, 
        "src": "/home/ec2-user/.ansible/tmp/ansible-tmp-1663832644.96-9649-232726777681008/source", 
        "state": "file", 
        "uid": 1000
    }
}
ok: [host2] => {
    "result": {
        "changed": true, 
        "checksum": "c4a0561bd0cf1ead4194c2f571edeec08201a53d", 
        "dest": "/home/ec2-user/hosts", 
        "diff": [], 
        "failed": false, 
        "gid": 1000, 
        "group": "ec2-user", 
        "md5sum": "d9852837b7677f6d2f9dd9061773f8c5", 
        "mode": "0664", 
        "owner": "ec2-user", 
        "size": 1559, 
        "src": "/home/ec2-user/.ansible/tmp/ansible-tmp-1663832644.96-9650-125136506082464/source", 
        "state": "file", 
        "uid": 1000
    }
}

PLAY RECAP **********************************************************************************************************************
host1                      : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2                      : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[ec2-user@ip-12-12-12-12 work-ansible]$ ansible public -m shell -a "ls -lF ~" -i ./hosts
host1 | CHANGED | rc=0 >>
total 8
-rw-rw-r-- 1 ec2-user ec2-user   12 Sep 21 03:26 hello.txt
-rw-rw-r-- 1 ec2-user ec2-user 1559 Sep 22 07:44 hosts
host2 | CHANGED | rc=0 >>
total 4
-rw-rw-r-- 1 ec2-user ec2-user 1559 Sep 22 07:44 hosts
[ec2-user@ip-12-12-12-12 work-ansible]$

팩트 - Facts

  • Managed node에 대한 정보
  • Ansible Playbook을 실행할 때 첫번째 수행 Task가 Managed node의 정보를 갖는 팩트를 수집하는 Task이다.
  • Ansible Facts를 수집할 때는 Managed node에 연결해서 이에 대한 모든 종류의 세부 정보를 쿼리(Query)라 하며,
    이 정보는 ansible_facts 변수에 저장된다.
  • gather_facts attribute - 팩트 수집 유무 결정
    • gather_facts: True - 팩트 수집, default
    • gather_facts: False - 팩트 수집 중단
  • Ad-hoc 명령으로 팩트 정보 확인
    • ansible <host 패턴> -m setup - 전체 팩트 정보 확인
    • ansible <host 패턴> -m setup -a "<filter=하위 facts key> ..." - 특정 key 팩트 정보 확인
[ec2-user@ip-12-12-12-12 work-ansible]$ ansible managed -m setup -i ./hosts -a "filter=ansible_user_id"
host3 | SUCCESS => {
    "ansible_facts": {
        "ansible_user_id": "ec2-user"
    }, 
    "changed": false
}
host2 | SUCCESS => {
    "ansible_facts": {
        "ansible_user_id": "ec2-user"
    }, 
    "changed": false
}
host1 | SUCCESS => {
    "ansible_facts": {
        "ansible_user_id": "ec2-user"
    }, 
    "changed": false
}
[ec2-user@ip-12-12-12-12 work-ansible]$

 

  • ansible_fact 변수의 특정 key 접근 방법
    • "{{ansible_fact['key 이름']}}"
---
- name: confirm facts
  hosts: private
  gather_facts: true

  tasks:
  - name: ansible facts
    debug:
      var: "{{ansible_facts['user_id']}}"
[ec2-user@ip-12-12-12-12 work-ansible]$ ansible-playbook facts.yml -i ./hosts

PLAY [confirm facts] ************************************************************************************************************

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

TASK [ansible facts] ************************************************************************************************************
ok: [host3] => {
    "ec2-user": "VARIABLE IS NOT DEFINED!"
}

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

[ec2-user@ip-12-12-12-12 work-ansible]$

TIF

이해가 된 듯, 안 된 듯... 할만한 듯, 어려운 듯...

리눅스 때처럼 주말에 다 다시 세팅해보고 다시 해봐야겠다.

 

혹시 모르니 코딩 테스트를 조금씩 준비해야 할 것 같다.

단기간이 되는 것은 아니기 때문에 코드업에서 기초부터 200여 문제 풀어보면서

이것이 코딩 테스트다 부록에 있는 문법 등도 공부해야겠다.

 

 

2022. 09. 22 에 작성된 글입니다.

반응형
profile

어쩌다 IT

@jwlish

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!