본문 바로가기

study/Ansible101 1기

Ansible101 1기 3주차 첫번째

3주차 스터디 공유 시작하겠습니다.

 

사용자 계정 생성하기

사용자 계정패스워드Vault를 이용해 암호화 처리한다.

사용자 계정 생성은 ansible.builtin.user 모듈을 이용한다.

 

플레이북 개발

1. 프로젝트 디렉터리 생성 및 ansible.cfg, inventory 파일 작성

#
mkdir ~/my-ansible/chapter_09.1
cd ~/my-ansible/chapter_09.1

# ansible.cfg, inventory 파일 작성
cp ~/my-ansible/ansible.cfg ./

cat <<EOT> inventory
tnode1
tnode2
tnode3
EOT

 

2. 사용자 계정 정보가 정의된 변수 파일을 생성

~/my-ansible/chapter_09.1/vars/secret.yml

# vault 암호는 편하게 입력
ansible-vault create vars/secret.yml
New Vault password: qwe123
Confirm New Vault password: qwe123

## 에디터 창으로 전환 : (아래 내용 복붙) user_info 변수에 userid와 userpw가 같이 있는 사전형 변수를 정의
---

user_info:
  - userid: "ansible"
    userpw: "ansiblePw1"
  - userid: "stack"
    userpw: "stackPw1"
~
~
:wq

# 변수 파일 확인
ls -l vars/secret.yml
cat vars/secret.yml

 

실행경과

 

3. 사용자 계정을 생성하는 플레이북을 작성 : 모든 호스트에 동일하게 생성하며 vault로 작성된 변수 파일을 읽어 사용함

~/my-ansible/chapter_09.1/create_user.yml

---

- hosts: all

  # vault로 사용자 계정 관련 변수가 정의된 파일을 임포트하여 사용
  vars_files:
    - vars/secret.yml

  tasks:
  # loop 문을 사용하여 user_info의 userid와 userpw 사용
  - name: Create user
    ansible.builtin.user:
      name: "{{ item.userid }}"
      password: "{{ item.userpw | password_hash('sha512', 'mysecret') }}"
      state: present
      shell: /bin/bash
    loop: "{{ user_info }}"

 

실행결과

- 문법 체크

# 에러 메시지 없이 플레이북 이름만 출력되면 문법 정상!
ansible-playbook --syntax-check create_user.yml
...

# 실패! > 다시 실행
ansible-playbook --ask-vault-pass --syntax-check create_user.yml
Vault password: qwe123

playbook: create_user.yml

 

실행 결과

 

확인

ansible -m shell -a "tail -n 3 /etc/passwd;echo" all

 

 

SSH 키 생성 및 복사하기

사용자 아이디는 외부 변수로 받는다.

ansible-server에서 ansible 계정을 만들고 SSH 키를 생성한다.

ansible-server에 생성된 SSH 공개 키를 각 tnode에 복사한다.

계정을 생성할 때는 ansible.builtin.user 모듈을, SSH 공개 키를 복사할 때는 ansible.posix.authorized_key 모듈을 이용한다.

 

플레이북 설계

앤서블 공식 문서의 콘텐츠 컬렉션에서 플레이북 개발에 필요한 SSH 키 생성 모듈과 SSH 키 복사 모듈을 찾았다면, 해당 모듈의 예제와 파라미터 정보를 이용해 플레이북을 설계합니다.

해당 플레이북명은 create_sshkey.yml 로 설정하고, ‘Create ssh key’ 태스크와 ‘Copy SSH Pub Key’ 라는 2개의 태스크를 갖습니다.

‘Create ssh key’ 태스크는 localhost에서 실행하고, ‘Copy SSH Pub Key’ 태스크는 tnode에서 실행합니다.

인벤토리에는 다음과 같이 tnode라는 그룹을 만든 다음 모든 관리 노드를 tnode 그룹으로 정의합니다.

 

ansible.posix.authorized_key 모듈 - https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html

Lookups 플러그인 - https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_lookups.html

 

1. 플레이북

#프로젝트 디렉터리 생성 및 inventory 파일 작성
#
mkdir ~/my-ansible/chapter_09.2
cd ~/my-ansible/chapter_09.2

# ansible.cfg, inventory 파일 작성
cp ~/my-ansible/ansible.cfg ./

# inventory 파일 수정
cat <<EOT> inventory
[tnode]
tnode1
tnode2
tnode3
EOT

# lookup 플러그인
ansible-doc -l -t lookup

 

2. SSH 키 생성하고 복사하는 플레이북을 작성 : 여기서는 태스크가 실행될 호스트별로 태스크 작성

- localhost인 ansible-server에서 생성된 SSH 공개 키는 ansible.posix.authorized_key 모듈을 이용하여 인벤토리의 tnode 호스트 그룹의 각 서버로 복사됩니다.

- 이때 키를 등록하기 위해 lookup 함수가 사용 : 외부 소스(파일, DB, key/value stores, APIs 등)으로 부터 데이터를 검색

#~/my-ansible/chapter_09.2/create_sshkey.yml
---

- hosts: localhost
  tasks:
  - name : Create ssh key
    ansible.builtin.user:
      name: "{{ userid }}"
      generate_ssh_key: true
      ssh_key_bits: 2048
      ssh_key_file: /home/{{ userid }}/.ssh/id_rsa
      shell: /bin/bash

- hosts: tnode 
  tasks:
  - name: Copy SSH Pub key
    ansible.posix.authorized_key:
      user: "{{ userid }}"
      state: present
      key: "{{ lookup('file', '/home/{{ userid }}/.ssh/id_rsa.pub') }}"

 

 

2. 실행

실행 : 실행 시 외부 변수(-e) 로 사용하기 위해, 사용자 계정을 플레이북이나 별도의 파일에 정의하지 않았습니다. 

# 문법 체크
ansible-playbook --syntax-check create_sshkey.yml

# 실행 : 외부 변수(-e)로 userid 정의하고 전달 실행 >> 실패!
ansible-playbook -e userid=ansible create_sshkey.yml
ansible-playbook -e userid=ansible create_sshkey.yml -vvvvv

# 
ls -l /home/ansible/.ssh/id_rsa.pub
sudo ls -l /home/ansible/.ssh/id_rsa.pub

 

해결방안

##ansible.cfg 파일 수정
[defaults]
inventory = ./inventory
remote_user = root
inject_facts_as_vars = false

##플레이북을 root 로 실행하고 ssh 암호 입력
sudo ansible-playbook -e userid=ansible create_sshkey.yml --ask-pass
SSH password: qwe123
...

 

실행 결과

 

 

공개 키 복시 및 접속 확인

# ansible 계정 전환
sudo su - ansible

# bash
echo $SHELL
whoami
pwd

# 
ls -al
ls -l .ssh
total 8
-rw------- 1 ansible ansible 1856 Jan  5 05:57 id_rsa
-rw-r--r-- 1 ansible ansible  417 Jan  5 05:57 id_rsa.pub

# tnode SSH 접속 테스트
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i hostname; echo; done

# 대상 노드에 정보 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tree /home/ansible/.ssh; echo; done
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i cat /home/ansible/.ssh/authorized_keys; echo; done

# ubuntu로 복귀
exit
whoami
pwd

 

tnode 관리 노드에 ansible 계정에 패스워드 입력 없이 sudo 권한 줄 수 있게 설정 : root 계정 권한으로 진행

~/my-ansible/chapter_09.2/sudo-ansible.yml
---
- hosts: all

  tasks:
  - name: Create file
    ansible.builtin.file:
      path: /etc/sudoers.d/ansible
      mode: '0600'
      state: touch

  - name: Edit file
    ansible.builtin.lineinfile:
      path: /etc/sudoers.d/ansible
      line: ansible ALL=(root) NOPASSWD:ALL

 

실행

sudo ansible-playbook sudo-ansible.yml --ask-pass
SSH password: qwe123

 

 

확인

 

 

NTP 서버 설치 및 설정하기

- NTP 서버 주소는 메인 플레이북에서 정의한다.

- 운영체제가 Ubuntuapt 모듈을 사용하여 chrony를 설치한다.

- 운영체제가 CentOS/레드햇이면 dnf 모듈을 사용하여 chrony를 설치한다.

- Jinja2 템플릿 방식의 chrony.conf 파일을 대상 호스트로 복사한다.

- 설정 파일이 복사되면 chrony 서비스를 재시작한다.

- 다음에도 사용할 수 있도록 롤을 이용하여 설계하고 작성한다.

 

 

플레이북 설계

이번 예제에서는 chrony를 서로 다른 운영체제에서 각각모듈을 이용하여 설치할 것이므로 생성하고 호출하는 방식으로 작성하자.

대략적인 설계가 끝나면 롤에 대한 상세 설계를 합니다. chrony 서비스 설치를 위한 롤에서는 변수를 정의하는 vars, 환경 설정 템플릿을 위한 templates, 태스크를 정의한 tasks, 환경 설정 후 chrony 서비스를 재시작하기 위한 handlers를 사용합니다.

 

 

플레이북 개발

실습 편리를 위해서 VSCODE에서 remote SSH 접속 시 root 계정으로 로그인 설정

커맨드창(Ctrl + Shift + P) 입력 후 “Remote-SSH: Open Config…” 선택 후 자신의 SSH Config 파일을 열기: ls ~/.ssh/config

실습 편의를 위해 root로 진행
# Read more about SSH config files: https://linux.die.net/man/5/ssh_config
Host ansible-server
    HostName 50.1.1.1 <- 각자 자신의 ansible-server 의 유동 공인 IP
    User root

 

1. ansible 계정의 실습 디렉터리 생성

#
su - ansible -c 'mkdir -p ~/ansible-project/chapter_09.3'
ls -l /home/ansible/

 

1-2 VSCODE에서 작업 영역에 폴더 추가 : /home/ansible/ansible-project → remote SSH 작업이라 약간 지연 발생 ⇒ 잠시 대기 후 재로딩됨

whomai
pwd
cd

 

2. ansible 계정으로 프로젝트 디렉터리 생성 및 ansible.cfg, inventory 파일 작성

# ansible 계정 전환
su - ansible
whoami
cd
pwd

# 프로젝트 디렉터리로 이동
cd ~/ansible-project/chapter_09.3
pwd
/home/ansible/ansible-project/chapter_09.3

 

2-1 ansible.cfg 파일 생성 : remote_user 는 ansible 로 설정

cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
roles_path = ./roles

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT

 

2-2 inventory 파일 생성

cat <<EOT > inventory
[tnode]
tnode1
tnode2
tnode3
EOT

 

3.  롤 생성

# --init-path 옵션으로 롤 생성 경로를 ./roles로 설정
ansible-galaxy role init --init-path ./roles myrole.chrony

# 확인
tree roles

 

확인

 

4. 롤 디렉터리에 vars/main.yml 파일 선택 후 아래 내용 추가

#chapter_09.3/roles/myrole.chrony/vars/main.yml

---
# vars file for myrole.chrony

package_name : chrony
service_name : chronyd
fedora_os:
 - RedHat
 - CentOS

 

5. chrony.conf.j2 파일을 생성 : 외부로부터 입력받은 ntp_server 변수를 사용

touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/templates/chrony.conf.j2

- 롤 디렉터리에 templates/chrony.conf.j2 파일 선택 후 아래 내용 추가

- chrony.conf 파일의 내용은 이미 chrony 서비스가 설치되어 있는 서버의 chrony.conf 파일 내용을 참조하여 작성합니다.

 

#chapter_09.3/roles/myrole.chrony/templates/chrony.conf.j2
pool {{ ntp_server }}
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 10.10.0.0/16
local stratum 10
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony

 

6. 핸들러에는 chrony 서비스를 재시작하는 태스크가 포함

#chapter_09.3/roles/myrole.chrony/handlers/main.yml
---
# handlers file for myrole.chrony

- name: Restart chrony
  ansible.builtin.service:
    name: "{{ service_name }}"
    state: restarted

 

7. 메인 태스크 작성

- ansible_facts.distribution 팩트 변수를 이용하여 다른 파일에서 태스크를 포함 시킴

- 운영체제에 맞는 chrony 환경 설정 파일 설정 복사 → 복사 후 notify로 ‘Restart chrony’ 핸들러 호출

#chapter_09.3/roles/myrole.chrony/tasks/main.yml
---
# tasks file for myrole.chrony

- name: Import playbook
  ansible.builtin.include_tasks:
    file: "{{ ansible_facts.distribution }}.yml"

- name: Copy chrony config file when Ubuntu
  ansible.builtin.template:
    src: chrony.conf.j2
    dest: /etc/chrony/chrony.conf
  notify: "Restart chrony"
  when: ansible_facts.distribution == "Ubuntu"

- name: Copy chrony config file when Other OS
  ansible.builtin.template:
    src: chrony.conf.j2
    dest: /etc/chrony.conf
  notify: "Restart chrony"
  when: ansible_facts.distribution in fedora_os

 

8. 메인 태스크에서 호출된 온영체제별 플레이북을 하나씩 작성

- 아래 touch로 파일 생성 후 작업 폴더 창에 새로고침 아이콘 클릭

touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/RedHat.yml
touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/CentOS.yml
touch ~/ansible-project/chapter_09.3/roles/myrole.chrony/tasks/Ubuntu.yml

 

chapter_09.3/roles/myrole.chrony/tasks/RedHat.yml

---

- name: Install chrony using dnf
  ansible.builtin.dnf:
    name: "{{ package_name }}"
    state: latest

 

chapter_09.3/roles/myrole.chrony/tasks/CentOS.yml

---

- name: Install chrony using dnf
  ansible.builtin.dnf:
    name: "{{ package_name }}"
    state: latest

 

chapter_09.3/roles/myrole.chrony/tasks/Ubuntu.yml

---

- name: Install chrony using apt
  ansible.builtin.apt:
    name: "{{ package_name }}"
    state: latest

 

 

9. 메인 플레이북인 install_ntp.yml 파일을 작성 : 롤 추가 후 ntp_server 변수를 함께 선언

touch ~/ansible-project/chapter_09.3/install_ntp.yml

 

chapter_09.3/install_ntp.yml

---

- hosts: tnode
  roles:
    - role: myrole.chrony
      ntp_server: 0.kr.pool.ntp.org

 

 

실행

# 문법 체크
ansible-playbook --syntax-check install_ntp.yml

# 플레이북 실행 : when문을 통해 해당 운영체제에 따라 특정 태스크만 실행됨
ansible-playbook install_ntp.yml

 

결과

 

확인

#
ansible -m shell -a "cat /etc/chrony/chrony.conf" tnode1
ansible -m shell -a "systemctl status chrony" tnode1

'study > Ansible101 1기' 카테고리의 다른 글

Ansible101 1기 4주차 첫번째  (0) 2024.02.04
Ansible101 1기 3주차 두번째  (0) 2024.01.28
Ansible101 1기 2주차 두번째  (0) 2024.01.14
Ansible101 1기 2주차 첫번째  (0) 2024.01.14
Ansible101 1기 1주차  (0) 2024.01.07