본문 바로가기

* Twodragon

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

안녕하세요. Twodragon 입니다.

가시다 님의 온라인 A101(Ansible 101 study) 강의에 대한 3번째 주차이며 시스템 구축 및 환경 설정 자동화를 위한 도전기 입니다!

 

 

Ansible을 사용한 사용자 계정 생성

Ansible을 사용하여 리모트 서버에 사용자 계정을 생성하고 암호를 설정하는 플레이북을 작성해보겠습니다. 이때 계정과 패스워드 정보는 Ansible Vault를 이용하여 암호화됩니다.

사전 분석

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

플레이북 설계

  • 프로젝트 디렉터리 생성 및 ansible.cfg, inventory 파일 작성
  • 사용자 계정 정보가 정의된 변수 파일을 생성
  • 사용자 계정을 생성하는 플레이북 작성

플레이북 개발

1. 프로젝트 디렉터리 및 파일 생성

bashCopy code
# 프로젝트 디렉터리 생성
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. 사용자 계정 정보가 정의된 변수 파일 생성

bashCopy code
# 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. 사용자 계정 생성하는 플레이북 작성

yamlCopy code
---

- 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 }}"

4. 플레이북 실행

bashCopy code
# 문법 체크
ansible-playbook --syntax-check create_user.yml

# 실행 : 외부 변수(-e)로 userid 정의하고 전달 실행
ansible-playbook -e userid=ansible create_user.yml --ask-vault-pass

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

이렇게 하면 Ansible을 사용하여 여러 호스트에 사용자 계정을 생성하는 플레이북을 구성할 수 있습니다. 이 플레이북은 Vault를 사용하여 보안성을 강화하며, 각 호스트에 동일한 계정을 생성합니다.

 

도전과제 1 - 실습 시 Vault에 AWS SecretManager를 활용하기

도전과제 1에서는 Ansible Vault를 사용하여 AWS SecretManager에서 비밀 정보를 가져와 사용하는 방법을 적용해보겠습니다.

  1. AWS SecretManager에 시크릿 생성
  2. 먼저 AWS SecretManager에서 Ansible이 사용할 시크릿을 생성합니다. 여기서는 ansible_secrets라는 이름의 시크릿을 만들어 userid와 userpw를 저장합니다.
  3. 시크릿 정보 가져오기
  4. Ansible Vault에서 시크릿 정보를 가져올 때는 lookup 함수를 사용합니다. 시크릿을 가져오는 플레이북에서 lookup 함수를 사용하여 AWS SecretManager에서 값을 가져오고, 해당 값을 변수에 할당합니다.
  5. Vault 암호화된 변수 파일 수정
  6. 앞서 가져온 SecretManager의 정보를 이용하여 Vault 암호화된 변수 파일을 수정합니다.
  7. 플레이북 실행
  8. 최종적으로 수정된 Vault 암호화된 변수 파일을 사용하여 플레이북을 실행합니다.

도전과제를 해결하기 위한 플레이북 예시는 다음과 같습니다:

yamlCopy code
---

- hosts: all

  # AWS SecretManager에서 시크릿 정보를 가져와 변수에 할당
  vars:
    secret_info: "{{ lookup('aws_secret', 'ansible_secrets') }}"

  # 가져온 정보를 변수에 할당하고 계정 생성
  tasks:
    - name: Assign secret values
      set_fact:
        user_info: "{{ secret_info | from_json }}"

    - name: Create user
      ansible.builtin.user:
        name: "{{ item.userid }}"
        password: "{{ item.userpw | password_hash('sha512', 'mysecret') }}"
        state: present
        shell: /bin/bash
      loop: "{{ user_info }}"

위의 플레이북에서 lookup('aws_secret', 'ansible_secrets') 부분은 AWS SecretManager에서 ansible_secrets 시크릿을 가져오는 부분입니다. 이를 통해 Vault에 저장된 정보를 가져와 계정을 생성할 수 있습니다.

 

9.2 SSH Key 생성 및 복사하기

사전 분석

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

플레이북 설계

  • Ansible 공식 문서의 콘텐츠 컬렉션에서 SSH 키 생성 및 복사에 필요한 모듈을 찾았다.
  • 플레이북명은 **create_sshkey.yml**로 설정하고, ‘Create SSH key’ 태스크와 ‘Copy SSH Pub Key’라는 2개의 태스크를 갖는다.
  • ‘Create SSH key’ 태스크는 localhost에서 실행하고, ‘Copy SSH Pub Key’ 태스크는 tnode에서 실행한다.
  • 인벤토리에는 tnode라는 그룹을 만들고, 모든 관리 노드를 tnode 그룹으로 정의한다.

 

플레이북 개발

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

bashCopy code
mkdir ~/my-ansible/chapter_09.2
cd ~/my-ansible/chapter_09.2
cp ~/my-ansible/ansible.cfg ./

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

ansible-doc -l -t lookup

2. SSH 키 생성 및 복사 플레이북 작성 (create_sshkey.yml)

bashCopy code
---

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

Sources

  1. ansible.posix.authorized_key Module
  2. Lookups Plugin

도전과제 2: Lookups 플러그인을 사용한 플레이북 작성

Lookups 플러그인을 사용하여 간단한 플레이북을 작성해보겠습니다. 이 예제에서는 파일에서 데이터를 조회하고, 조회한 데이터를 사용하여 사용자를 생성하는 작업을 수행하는 플레이북입니다.

lookup_example.yml

yamlCopy code
---
- hosts: localhost
  tasks:
    - name: Read user data from file
      set_fact:
        user_data: "{{ lookup('file', '/path/to/user_data.txt') }}"

    - name: Create user from lookup data
      ansible.builtin.user:
        name: "{{ user_data.split(':')[0] }}"
        uid: "{{ user_data.split(':')[1] }}"
        state: present

이 플레이북은 localhost에서 실행되며, 먼저 파일에서 데이터를 읽어와서 변수 user_data에 저장한 후, 이 데이터를 이용하여 사용자를 생성합니다.

참조 : Lookups Plugin 문서

 

9.3 NTP 서버 설치 및 설정하기 - Lookups 플러그인을 활용한 플레이북

사전 분석

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

플레이북 설계

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

롤 구성에 필요한 플레이북

  • 롤의 기본 구조를 생성하기 위해 ansible-galaxy 명령어를 사용한다.
bashCopy code
ansible-galaxy role init --init-path ./roles myrole.chrony

롤 디렉터리 구조

luaCopy code
roles/
|-- myrole.chrony/
|   |-- defaults/
|   |-- files/
|   |-- handlers/
|   |-- meta/
|   |-- tasks/
|   |   |-- main.yml
|   |-- templates/
|   |   |-- chrony.conf.j2
|   |-- tests/
|   |   |-- inventory
|   |   |-- test.yml
|   |-- vars/
|   |   |-- main.yml

변수 및 템플릿 설정

  • vars/main.yml 파일을 통해 패키지 이름, 서비스 이름 및 Fedora 계열의 운영체제 정보를 설정한다.
yamlCopy code
# vars file for myrole.chrony

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

  • templates/chrony.conf.j2 파일을 통해 외부에서 받은 ntp_server 변수를 사용하여 템플릿을 작성한다.
bashCopy code
# 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

핸들러 설정

  • handlers/main.yml 파일에는 chrony 서비스를 재시작하는 핸들러를 설정한다.
yamlCopy code
# handlers file for myrole.chrony

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

운영체제별 태스크

  • tasks/main.yml 파일에서는 운영체제별로 설치할 패키지를 정의하고 템플릿을 복사한 후 핸들러를 호출한다.
yamlCopy code
# 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

운영체제별 패키지 설치

  • 각 운영체제별로 패키지를 설치하는 tasks/{distribution}.yml 파일을 작성한다.
yamlCopy code
# tasks/RedHat.yml

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

yamlCopy code
# tasks/CentOS.yml

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

yamlCopy code
# tasks/Ubuntu.yml

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

메인 플레이북

  • 최종적으로 install_ntp.yml 파일에서 롤을 추가하고 ntp_server 변수를 함께 선언한다.
yamlCopy code
# install_ntp.yml

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

플레이북 실행

bashCopy code
# 플레이북 실행
ansible-playbook install_ntp.yml

  • 결과 확인 및 검증
bashCopy code
# 설정 파일 확인
ansible -m shell -a "cat /etc/chrony/chrony.conf" tnode1

도전 과제 3: Apache HTTP 서버 설치 플레이북

사전 분석:

  • Ubuntu 및 CentOS에서 Apache HTTP 서버를 설치하는 플레이북을 작성할 것입니다.
  • Roles 및 Templates을 활용하여 효율적인 구성을 할 예정입니다.

플레이북 설계:

  1. 앤서블 공식 문서 및 참고 자료에서 각 운영체제별로 Apache를 설치하는 모듈을 찾습니다.
  2. 설치된 Apache 서비스의 구성을 변경할 수 있도록 템플릿을 활용하여 설정 파일을 관리합니다.
  3. Ubuntu 및 CentOS에서 동일한 플레이북을 사용할 수 있도록 Roles를 구성합니다.

검색 결과 활용:

  1. Stack Overflow : Ubuntu에 Nginx를 설치하는 예제를 참고하여 Apache 설치 모듈을 찾습니다.
  2. Ansible Documentation - apt_module : Ansible의 apt 모듈을 통해 Ubuntu에 패키지를 설치하는 방법을 확인합니다.
  3. Middleware Inventory : Ansible을 사용하여 다양한 작업을 수행하는 블로그 글에서 핸들러를 사용하여 서비스를 관리하는 방법을 참고합니다.

플레이북 개발:

  • 아래는 플레이북의 일부분으로, Roles 및 Templates을 사용하여 Apache HTTP 서버를 Ubuntu 및 CentOS에 설치하는 내용을 포함합니다.
yamlCopy code
---
- name: Install Apache HTTP Server
  hosts: webservers
  become: true
  vars:
    apache_pkg:
      Ubuntu: apache2
      CentOS: httpd

  tasks:
    - name: Install Apache on Ubuntu
      ansible.builtin.apt:
        name: "{{ apache_pkg.Ubuntu }}"
        state: present
      when: ansible_facts['distribution'] == 'Ubuntu'

    - name: Install Apache on CentOS
      ansible.builtin.yum:
        name: "{{ apache_pkg.CentOS }}"
        state: present
      when: ansible_facts['distribution'] == 'CentOS'

    - name: Copy Apache configuration template
      ansible.builtin.template:
        src: apache.conf.j2
        dest: /etc/apache2/apache2.conf
      when: ansible_facts['distribution'] == 'Ubuntu'

    - name: Copy Apache configuration template
      ansible.builtin.template:
        src: apache.conf.j2
        dest: /etc/httpd/conf/httpd.conf
      when: ansible_facts['distribution'] == 'CentOS'

    - name: Start Apache service
      ansible.builtin.service:
        name: "{{ apache_pkg[ansible_facts['distribution']] }}"
        state: started
        enabled: yes

플레이북 실행:

bashCopy code
ansible-playbook install_apache.yml

이 플레이북은 Ubuntu 및 CentOS에 Apache HTTP 서버를 설치하고, 각각의 설정 파일을 관리합니다. Roles 및 Templates를 사용하여 모듈화된 구조로 설계되었습니다.

 

10.1 환경 설정 자동화 챕터의 네트워크 IP 설정하기

사전 분석

  • 우분투 OS에서는 netplan 파일을 사용하여 IP를 설정합니다.
  • netplan은 파일 형태이므로 먼저 파일 구조를 확인하고 jinja2 템플릿을 이용하여 작성합니다.
  • CentOS/레드햇 OS에서는 nmcli 모듈을 사용하여 IP를 설정합니다. (community.general.nmcli 모듈 참조)
  • 예제에서는 ethernet 타입의 네트워크 IP를 설정합니다.
  • IP 설정과 관련된 정보는 메인 플레이북에서 변수로 정의하며, 해당 인터페이스가 호스트에 존재하는지 앤서블 팩트를 통해 확인합니다.

플레이북 설계

  • 우분투와 CentOS/레드햇 각각을 대상으로 하는 롤을 구성합니다.
  • OS 종류에 따라 해당 롤을 호출하는 메인 플레이북을 설계합니다.
  • ansible.builtin.template 모듈: docs.ansible.com

플레이북 개발 및 실행

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

bashCopy code
# 프로젝트 디렉터리 생성 및 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

2. 롤 생성: myrole.nmcli, myrole.netplan

bashCopy code
# 롤 생성
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

3. myrole.nmcli에 태스크 파일 작성

yamlCopy code
# 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

  • nmcli 모듈을 사용하여 외부에서 받은 변수로 네트워크 IP를 설정합니다.
  • 변수는 배열 형식으로 받기 때문에 loop를 사용하고, 외부에서 받은 인터페이스가 앤서블 팩트에 존재하는지 확인하는 when 키워드를 사용합니다.

myrole.netplan에 Jinja2 템플릿 파일 작성

bashCopy code
# Jinja2 템플릿 파일 생성
touch ~/ansible-project/chapter_10.1/roles/myrole.netplan/templates/01-netplan-ansible.yaml.j2

01-netplan-ansible.yaml:

yamlCopy code
# 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 문으로 처리합니다.

myrole.netplan에 태스크 파일 작성

yamlCopy code
# 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

  • template 모듈을 사용하여 템플릿 파일을 호스트에 복사합니다.
  • 외부에서 받은 인터페이스가 앤서블 팩트에 존재하는지 확인하고, 템플릿 복사가 성공하면 notify 키워드를 사용하여 핸들러를 호출합니다.

myrole.netplan에 핸들러 파일 작성: 핸들러는 command 모듈을 사용하여 netplan apply 명령어를 실행합니다.

yamlCopy code
# handlers file for myrole.netplan

- name: Netplan apply
  ansible.builtin.command: netplan apply

마지막으로 롤을 호출할 메인 플레이북을 작성합니다.

  • 메인 플레이북에서는 롤에 전달할 변수를 vars 섹션에 선언하고 tasks 섹션에 롤을 추가합니다.
  • ansible.builtin.include_role 모듈을 사용하여 롤을 호출하면서 when 구문을 함께 사용하여 OS 버전에 따라 해당 롤을 호출합니다.
yamlCopy code
# set_ip.yml

---

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

 

플레이북 실행

  • 실행 전 tnode1의 네트워크 정보 확인
bashCopy code
# 실행 전 tnode1 정보 확인
ssh tnode1 ls /etc/netplan
ssh tnode1 cat /etc/netplan/50-cloud-init.yaml
ssh tnode1 ip -br -c addr
ssh tnode1 ip -c route
ssh tnode1 nslookup blog.cloudneta.net

ansible -m shell -a "cat /var/log/syslog | grep -i dhcp" tnode1
ssh tnode1 sudo dhclient -v ens5

bashCopy code
# 문법 체크
ansible-playbook --syntax-check set_ip.yml

# 플레이북 실행
ansible-playbook set_ip.yml

# 실행 후 tnode1 정보 확인
ssh tnode1 ls /etc/netplan
ssh tnode1 cat /etc/netplan/01-netplan-ansible.yaml
ssh tnode1 ip -br -c addr
ssh tnode1 ip -c route
ssh tnode1 nslookup blog.cloudneta.net


🌐 Sources

  1. ansible.builtin.template - Ansible Documentation
  2. community.general.nmcli - Ansible Documentation
  3. Jinja2 Template Engine - Introduction

 

도전과제4 Jinja2 템플릿을 활용한 예시 playbook를 구글링하여 실습 환경에 맞게 구성 후 실습해보세요

먼저, Jinja2 템플릿을 사용한 예시 플레이북을 구글에서 찾아보겠습니다. 그런 다음 실습 환경에 맞게 조정하고 전체적인 요약을 제공하겠습니다.

  1. Google에서 "Jinja2 template Ansible playbook example"을 검색합니다.
  2. 검색 결과 중에서 Jinja2 템플릿을 사용한 예시 플레이북을 찾습니다.

예시 플레이북을 찾았다면, 해당 플레이북을 기반으로 실습 환경에 맞게 조정합니다. 예시 플레이북의 구조와 역할에 따라 필요한 수정을 수행합니다.

아래는 가상의 예시일 수 있으며, 특정 예시 플레이북이나 템플릿을 기반으로 작성한 것이 아닙니다.

예시 플레이북 (example_playbook.yml):

yamlCopy code
---
- name: Configure Network on tnode1
  hosts: tnode1
  tasks:
    - name: Copy network configuration template
      template:
        src: templates/network.j2
        dest: /etc/netplan/01-netplan-ansible.yaml
      notify: Apply network configuration

  handlers:
    - name: Apply network configuration
      command: netplan apply

Jinja2 템플릿 (templates/network.j2):

yamlCopy code
network:
  version: 2
  ethernets:
    ens5:
      addresses: {{ ip_address }}/24
      gateway4: {{ gateway }}
      nameservers:
        addresses: [{{ nameserver }}]

위의 예시에서 {{ ip_address }}{{ gateway }}{{ nameserver }} 등의 변수는 실제 값으로 대체되어야 합니다. 네트워크 인터페이스 이름(ens5 등)도 실제 환경에 맞게 수정이 필요합니다.

실습 단계:

  1. 위에서 구성한 플레이북과 템플릿을 저장합니다.
  2. 필요한 변수 값을 실제 환경에 맞게 설정합니다.
  3. Ansible을 사용하여 플레이북을 실행합니다.