본문 바로가기
Ansible/Study

시스템 구축 및 환경 설정 자동화

by 식사법 2024. 2. 4.

시스템 구축 및 환경 설정 자동화

이번주는 앤서블을 실제로 활용하는 방안에 대한 예시를 정리합니다.

시스템 구축 자동화

사용자 계정 생성하기

  1. 목적
  • 사용자 계정과 패스워드를 Vault를 활용하여 암호화처리
  1. 플레이북 설계
  • 폴더가 어떻게 구분되어있는지 잘 생각하여 설계하여야합니다

  1. 플레이북 개발
  • 디렉토리 생성 및 ansible.cfg, inventory, 변수 등 선언
#
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
  • 사용자 계정 정보가 정의된 변수파일 생성
# 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
  • 사용자 계정을 생성하는 플레이북을 작성 : 1회차 앤서블 기초를 참조
---

- 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 }}"
  1. 플레이북 실행
ansible-playbook **--ask-vault-pass** **create_user.yml**
Vault password: **qwe123**

SSH 키 생성 및 복사하기

  1. 목적
  • ansible-server에서 ansible 계정 생성 및 ssh키 생성 및 해당 키를 tnode로 복사
  • 유저 생성시 ansible.builtin.user 모듈을, SSH 공개 키를 복사할 때는 ansible.posix.authorized_key 모듈을 사용
  1. 플레이북 설계
  • 폴더가 어떻게 구분되어있는지 잘 생각하여 설계하여야합니다

  1. 플레이북 개발
  • 디렉토리 생성 및 ansible.cfg, 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
  • SSH 키 생성 및 복사를하는 플레이북 작성
---

- 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') }}"
  1. 플레이북 실행
  • 해당플레이북 실행시 오류가 발생
# 문법 체크
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 암호 입력

[도전과제2] Lookups 플러그인을 활용한 playbook를 직접 작성

---
- hosts: localhost

  tasks:
    - name: today Date
      debug:
        msg: "today is{{ lookup('pipe', 'date +%Y-%m-%d') }}"

    - name: get file
      debug:
        msg: "my file is{{ lookup('file', '/home/ubuntu/test.txt') }}"

환경 구축 자동화

네트워크 IP 설정하기

  1. 목적
  • 우분투의 netplan 을 이용하여 IP를 설정한다
  • centOS일 경우 nmcli 모듈을 사용하여 ip를 설정한다
  1. 플레이북 설계
  • 우분투 일 경우 netplan을 사용하는 롤과 CentOS/레드햇 일 경우 nmcli 모듈을 사용하는 롤로 구성
  • 그리고 OS의 종류에 따라 해당 롤을 호출하는 방식으로 메인 플레이북을 설계

  • 롤 설계

  1. 플레이북 개발
  • 디렉토리 생성 및 ansible.cfg, inventory, 변수 등 선언
#
mkdir ~/ansible-project/chapter_10.1
cd ~/ansible-project/chapter_10.1

# ansible.cfg, inventory 파일 작성
cat <<EOT> ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
ask_pass = false
inject_facts_as_vars = 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
  1. 롤생성
#
ansible-galaxy role init --init-path ./roles myrole.nmcli
ansible-galaxy role init --init-path ./roles myrole.netplan

# 확인
ansible-galaxy role list
tree roles -L 2
  1. myrole.nmcli - 테스크 기입
---
# tasks file for myrole.nmcli

- name: Setup nic ip
  community.general.nmcli:
    type: ethernet
    conn_name: "{{ item.con_name }}"
    ip4: "{{ item.ip_addr }}"
    gw4: "{{ item.ip_gw }}"
    dns4: "{{ item.ip_dns }}"
    state: present
  loop: "{{ net_info }}"
  when: net_info[0].con_name in ansible_facts.interfaces
  • 위에서 이야기 했듯 centos는 nmcli 모듈을 사용하여 외부로부터 받은 변수를 네트워크 ip로 설정가능
  • 배열형태로 받은 변수이기 때문에 loop 사용 , when 키워드를 사용하여 외부로 부터 받은 인터페이스가 앤서블 팩트에 존재하는지 확인
  1. myrole.netplan 에 Jinna2 템플릿(파이썬 웹 프로그래밍에 주로 쓰이는 템플릿 파일) 파일 작성
# This is the network config written by 'ansible'
network:
  version: 2
  ethernets:
{% for item in net_info %}
    {{ item.con_name }}:
      dhcp4: no
      dhcp6: no
      addresses: [{{ item.ip_addr }}]
      gateway4: {{ item.ip_gw }}
      nameservers:
        addresses: [{{ item.ip_dns }}]
{% endfor %}
  • Jinja2 템플릿을 이용하여 외부로부터 받은 배열형 변수for 문으로 하나씩 꺼내 사용할 수 있습니다.
  • Jinja2 템플릿에서 제어문이나 반복문을 사용할 때는 다음과 같이 {% ~ %}를 이용합니다.
  1. myrole.netplan 에 태스크 파일 작성
---
# tasks file for myrole.netplan

- name: Copy netplan file
  ansible.builtin.template:
    src: 01-netplan-ansible.yaml.j2
    dest: /etc/netplan/01-netplan-ansible.yaml
  when: net_info[0].con_name in ansible_facts.interfaces
  notify: Netplan apply
  1. myrole.netplan 에 핸들러 파일 작성 : 핸들러는 command 모듈을 이용하여 netplan apply 명령어를 수행
  • 위의 태스크 파일에서 선언한 handler를 선언해 주는 과정입니다
---
# handlers file for myrole.netplan

- name: Netplan apply
  ansible.builtin.command: netplan apply
  1. 위에서 생상한 모두를 통합하여 호출해줄 플레이북 작성
  • 아래에서 볼 수 있듯이 when을 통해서 0s에 따라 다른 role이 실행되도록 설정되었습니다
---

- hosts: tnode1
  vars:
    fedora_os: 
      - CentOS
      - RedHat
    net_info:
      - con_name: ens5
        ip_addr: 10.10.1.11/24
        ip_gw: 10.10.1.1
        ip_dns: 127.0.0.53

  tasks:
  - name: Include role in CentOS and RedHat
    ansible.builtin.include_role:
      name: myrole.nmcli
    when: ansible_facts.distribution in fedora_os

  - name: Include role in Ubuntu
    ansible.builtin.include_role:
      name: myrole.netplan
    when: ansible_facts.distribution == "Ubuntu"

- hosts: tnode2
  vars:
    fedora_os: 
      - CentOS
      - RedHat
    net_info:
      - con_name: ens7
        ip_addr: 10.10.1.12/24
        ip_gw: 10.10.1.1
        ip_dns: 127.0.0.53

  tasks:
  - name: Include role in CentOS and RedHat
    ansible.builtin.include_role:
      name: myrole.nmcli
    when: ansible_facts.distribution in fedora_os

  - name: Include role in Ubuntu
    ansible.builtin.include_role:
      name: myrole.netplan
    when: ansible_facts.distribution == "Ubuntu"

'Ansible > Study' 카테고리의 다른 글

Ansible - 보안설정/ 모니터링 자동화  (1) 2024.02.12
Ansible - 반복문, 조건문, 핸들러 ,롤 구조  (0) 2024.01.20
Ansible 기초 정리  (0) 2024.01.09