새소식

IaC/Ansible

[A101 Study 3주차] 시스템 구축 자동화 플레이북 활용

  • -

CloudNet@ 팀의 가시다님께서 Leading 하시는 A101 Study 3주차 스터디 내용 정리

 

 

해당 스터디는 '앤서블로 시작하는 인프라 자동화' 책을 기반으로 진행하였습니다.
실습 환경은 'Control Node 1 대 + Target Node 3대' 로 구성하였습니다.



 

1. 시스템 구축 자동화

 

서비스를 구축하고 사용하기 위한 시스템 구축을 자동화하는 과정에서의 앤서블 활용법에 대해서 알아보겠습니다.

 

사용자 생성 -> SSH 키 생성 -> NTP 서버 설정 순으로 진행합니다.

 

 

1.1. 사용자 계정 생성

 

상황

 

사용자 계정 생성은 시스템 구축 시 가장 먼저 하는 작업으로, 다양한 목적에 따라 생성할 수 있습니다.
셸 스크립트만으로 충분히 가능한 작업이지만, 앤서블 플레이북을 통해 계정을 생성할 줄 알면 시스템이나 서비스 구축 시 해당 플레이북의 태스크를 활용할 수 있습니다.

 

사전 분석

 

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

 

플레이북 개발

 

 

- ansible.cfg file

[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false

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

 

 

 

- inventory file

tnode1
tnode2
tnode3

 

 

 

- Variable File (vars/secret.yml)

ansible-vault create vars/secret.yml
---

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

 

 

- Playbook File (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 --ask-vault-pass create_user.yml

 



 

1.2. SSH 키 생성 및 복사

 

상황

 

시스템을 구축하거나 애플리케이션을 설치하는 경우, 해당 애플리케이션을 사용하는 서버 간에 SSH 접속을 위한 SSH 키가 필요합니다.

 

 

사전 분석

 

  1. 사용자 아이디는 외부 변수로 받는다.
  2. ansible-server에서 ansible 계정을 만들고 SSH 키를 생성한다.
  3. ansible-server에 생성된 SSH 공개 키를 각 tnode에 복사한다.
  4. 계정을 생성할 때는 ansible.builtin.user 모듈을, SSH 공개 키를 복사할 때는 ansible.posix.authorized_key 모듈을 이용한다.

 

 

플레이북 개발

 

 

- ansible.cfg file

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

 

 

- inventory file

[tnode]
tnode1
tnode2
tnode3

 

 

 

- Playbook File (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') }}"

 

 

플레이북 실행

 

Root 유저로 플레이북을 실행합니다.
userid 변수는 외부 변수로 넣어줍니다.

sudo ansible-playbook -e userid=ansible create_sshkey.yml --ask-pass

 

 

 

 

1.3. NTP 서버 설치 및 설정

 

상황

 

NTP (Network Time Protocol) 은 여러 서버의 시간을 동기화하기 위한 애플리케이션입니다.
최근에는 'chrony' 라는 NTP 애플리케이션을 많이 사용합니다.

 

 

사전 분석

 

  1. NTP 서버 주소는 메인 플레이북에서 정의한다.
  2. 운영체제가 Ubuntuapt 모듈을 사용하여 chrony를 설치한다.
  3. 운영체제가 CentOS/레드햇이면 dnf 모듈을 사용하여 chrony를 설치한다.
  4. Jinja2 템플릿 방식의 chrony.conf 파일을 대상 호스트로 복사한다.
  5. 설정 파일이 복사되면 chrony 서비스를 재시작한다.
  6. 다음에도 사용할 수 있도록 롤을 이용하여 설계하고 작성한다.

 

 

플레이북 개발

 

ansible 사용자로 플레이북을 작성했습니다.

 

 

- ansible.cfg file

[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

 

 

- inventory file

[tnode]
tnode1
tnode2
tnode3

 

 

Role 생성

ansible-galaxy role init --init-path ./roles myrole.chrony

 

 

 

- roles/myrole.chrony/vars/main.yml

---
# vars file for myrole.chrony

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

 

 

- 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

 

 

- roles/myrole.chrony/handlers/main.yml

---
# handlers file for myrole.chrony

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

 

 

 

- 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

 

 

ubuntu 타겟 노드만 존재하기 때문에, ubuntu 를 제외한 나머지 Yaml 은 생성하지 않겠습니다.

 

- roles/myrole.chrony/tasks/Ubuntu.yml

---

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

 

 

메인 플레이북 작성

 

- Playbook File (install_ntp.yml)

---

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

 

 

플레이북 실행

ansible-playbook install_ntp.yml

 

 

 

 

 

Contents

포스팅 주소를 복사했습니다