티스토리 뷰

CloudNet@의 가시다님 Ansible 1기 스터디에 참여하게 되어 배운 내용과 책의 내용을 함께 정리합니다.

📚 앤서블로 시작하는 인프라 자동화

 

앤서블로 시작하는 인프라 자동화 | 장현정 - 교보문고

앤서블로 시작하는 인프라 자동화 | 효율적인 IT 자동화를 위한 도구, 앤서블 설계부터 응용까지 단계별로 배우는 인프라 관리클라우드 컴퓨팅을 논할 때 IaC(Infrastructure as Code)를 빼놓을 수 없는

product.kyobobook.co.kr

1. 사용자 계정 생성

플레이북을 안전하고 효율적으로 사용하기 위해서는 플레이북에 필요한 모듈을 먼저 생각하고 이를 사용하는 플레이북을 미리 설계하여 작성하는 습관을 가져야 합니다.

 

사전 분석

  • 사용자 계정과 패스워드는 Vault를 이용해 암호화 처리합니다.
  • 사용자 계정 생성은 ansible.builtin.user 모듈을 이용합니다.

플레이북 설계

플레이북을 하나의 디렉토리 단위로 구분하면 디렉토리 안에 있는 ansible.cfg 파일과 inventory 파일을 플레이북마다 별도로 관리할 수 있어 보다 효율적입니다. 디렉토리를 기준으로 파일 이름, 태스크명, 사용할 모듈과 변수들의 정의, 변수명과 변수를 선언할 위치 등을 미리 설계해봅니다.

 

플레이북 개발

 

1. 프로젝트 디렉토리를 생성하고 ansible.cfg 파일과 inventory 파일을 작성합니다.

~/my-ansible/chapter_09.1

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

# ansible.cfg, inventory 파일 작성
cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false

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

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

 

생성된 secret 파일이 암호화된 것을 확인할 수 있습니다.

 

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/sh이므로 변경 권장
      shell: /bin/bash
    loop: "{{ user_info }}"

 

4. 플레이북을 실행하기 전에 플레이북의 문법을 체크합니다.

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

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

 

사용자 계정 정보가 정의된 변수를 생성할 때 secret 파일을 통해 생성했기 때문에 --ask-vault-pass 옵션을 함께 사용해주어야 합니다. 

 

5. 플레이북에 --ask-vault-pass 옵션을 주어 실행합니다.

ansible-playbook --ask-vault-pass create_user.yml

 

6. 계정이 생성되었는지 확인합니다.

# 계정 생성 확인
ansible -m shell -a "tail -n 3 /etc/passwd" all

 

도전과제1

  • 9.1 실습 시 vault에 AWS SecretManager를 활용해보세요

 

2. 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 module – Adds or removes an SSH authorized key — Ansible Documentation

This only applies if using a https url as the source of the keys. If set to false, the SSL certificates will not be validated. Returned: success Sample: true

docs.ansible.com

 

플레이북 개발

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
 

Lookups — Ansible Documentation

Lookups Lookup plugins retrieve data from outside sources such as files, databases, key/value stores, APIs, and other services. Like all templating, lookups execute and are evaluated on the Ansible control machine. Ansible makes the data returned by a look

docs.ansible.com

 

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 }}"
      # 해당 파라미터를 사용하면 userid에 대해 자동으로 ssh 키 생성
      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') }}"

 

3. 플레이북을 실행합니다.

  • 실행 시 외부 변수(-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

 

 

4. ubuntu계정에는 SSH Key Copy 권한이 없기 때문에 root 계정으로 플레이북을 실행하기 위해 ansible.cfg 파일을 수정합니다.

[defaults]
inventory = ./inventory
remote_user = root
inject_facts_as_vars = false

 

5. 각 노드에서 root 계정으로 실행되는 플레이북을 SSH Key 접근권한 때문에 localhost에서도 root 계정으로 실행해야 합니다.

 

6. tnode 그룹에만 있던 ansible계정이 localhost에서도 ansible계정이 생긴 것을 확인할 수 있습니다.

 

7. 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

 

8. ubuntu 계정에서 플레이북을 실행하면 패스워드 입력없이 sudo 권한을 가질 수 있습니다.

 

 

도전과제2

  • Lookups 플러그인을 활용한 playbook를 직접 작성해서 실습해보세요.

 

3. 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
# 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/

 

2. ansible 계정으로 전환하고 프로젝트 디렉토리로 이동합니다.

chapter_09.3/

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

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

 

3. ansible.cfg 파일과 inventory 파일을 생성합니다. (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

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

 

4. 롤을 생성합니다.

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

# 확인
tree roles

 

5. 롤 디렉토리에서 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

 

6. chrony.conf.j2 파일을 생성합니다. (외부로부터 입력받은 ntp_server 변수를 사용합니다.)

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

 

7. 롤 디렉토리에서 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

 

8. 핸들러에는 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

 

9. 메인 태스크를 작성합니다.

  • 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

 

10. 메인 태스크에서 호출된 운영체제별 플레이북을 하나씩 작성합니다.

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

 

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

chapter_09.3/install_ntp.yml

---

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

 

12. 플레이북을 실행합니다.

ansible-playbook --syntax-check install_ntp.yml

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함