cd C:\4gl
vagrant init
vagrantfile 생성을 위해 명령어를 실행함

베이그런트는 아래 링크에서 사용하고 싶은 버전을 선택하여 사용할 수 있음
https://portal.cloud.hashicorp.com/vagrant/discover/almalinux/8
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.define "4gl-node" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.box_version = "8.10.20250220"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node1"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node1"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
end
end
vagrant up
vagrant destroy -f

# -*- mode: ruby -*-
# vi: set ft=ruby :
#=============#
# Node1 #
#=============#
Vagrant.configure("2") do |config|
config.vm.define "4gl-node" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.box_version = "8.10.20250220"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node1"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node1"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
end
#=============#
# Node2,3,4 #
#=============#
(2..4).each do |i|
config.vm.define "4gl-node#{i}" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node#{i}"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node#{i}"
cfg.vm.network "private_network", ip: "192.168.1.10#{i}"
cfg.vm.network "forwarded_port", guest: 22, host: "6010#{i}",auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
end
end
end
수정 후 파워쉘에서 vagrant up 명령어를 입력하여 실행해야 가상머신이 설치됨
install_pkg.sh
#!/bin/bash
#install package
dnf -y install epel-release
dnf -y install ansible
cfg.vm.provision "shell", path: "install_pkg.sh"

# -*- mode: ruby -*-
# vi: set ft=ruby :
#=============#
# Node1 #
#=============#
Vagrant.configure("2") do |config|
config.vm.define "4gl-node" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.box_version = "8.10.20250220"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node1"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node1"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "install_pkg.sh"
end
#=============#
# Node2,3,4 #
#=============#
(2..4).each do |i|
config.vm.define "4gl-node#{i}" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node#{i}"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node#{i}"
cfg.vm.network "private_network", ip: "192.168.1.10#{i}"
cfg.vm.network "forwarded_port", guest: 22, host: "6010#{i}",auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
end
end
end
vagrant provision
이때 provision으로 실행할 파일들은 vagrantfile 내에 provision 코드를 추가해놓아야 해당 명령어가 실행됨

ping_2_nds.sh
#!/bin/ssh
ping 192.168.1.102 -c 3
ping 192.168.1.103 -c 3
ping 192.168.1.104 -c 3
cfg.vm.provision "file", source: "ping_2_nds.sh", destination: "ping_2_nds.sh"
# -*- mode: ruby -*-
# vi: set ft=ruby :
#=============#
# Node1 #
#=============#
Vagrant.configure("2") do |config|
config.vm.define "4gl-node" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.box_version = "8.10.20250220"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node1"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node1"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "install_pkg.sh"
cfg.vm.provision "file", source: "ping_2_nds.sh", destination: "ping_2_nds.sh"
end
#=============#
# Node2,3,4 #
#=============#
(2..4).each do |i|
config.vm.define "4gl-node#{i}" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node#{i}"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node#{i}"
cfg.vm.network "private_network", ip: "192.168.1.10#{i}"
cfg.vm.network "forwarded_port", guest: 22, host: "6010#{i}",auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
end
end
end
가상머신 접속 후 해당 파일 실행
경로 확인: ls /home/vagrant
파일 실행: sh /home/vagrant/ping_2_nds.sh


해당 파일은 4gl 내에 userssh 파일을 생성 후 해당 파일 내에서 추가

useradd.sh
#!/bin/bash
set -eux
#ansuser가 없을 경우만 생성 되도록 조건 설정
# &>는 표준 출력 및 에러를 동시에 리다이렉션하기 위해 입력
if ! id ansuser &> /dev/null; then
PASSWORD_HASH=$(openssl passwd -6 'ansuser')
useradd ansuser
usermod -p "$PASSWORD_HASH" ansuser
fi
#openssl로 만든 값이 해당 유저에게 부여됨 (SHA-512)
#사용자 생성 시에는 visudo 말고 해당 사용자 이름이나 임의의 이름으로 /etc/sudoers.d/파일이름에 기입할 수 있음
echo "ansuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/ansuser
vagrantfile 내에 해당 명령어 추가
cfg.vm.provision "shell", path: "userssh/useradd.sh"
# -*- mode: ruby -*-
# vi: set ft=ruby :
#=============#
# Node1 #
#=============#
Vagrant.configure("2") do |config|
config.vm.define "4gl-node" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.box_version = "8.10.20250220"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node1"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node1"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "install_pkg.sh"
cfg.vm.provision "file", source: "ping_2_nds.sh", destination: "ping_2_nds.sh"
cfg.vm.provision "shell", path: "userssh/useradd.sh"
end
#=============#
# Node2,3,4 #
#=============#
(2..4).each do |i|
config.vm.define "4gl-node#{i}" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node#{i}"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node#{i}"
cfg.vm.network "private_network", ip: "192.168.1.10#{i}"
cfg.vm.network "forwarded_port", guest: 22, host: "6010#{i}",auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "userssh/useradd.sh"
end
end
end
완료 후 잘 되었는지 확인하기 위해서 mobaXterm에 접속하여 ansible ping 확인
su - ansuser
ansible all -m ping

copykey.sh
vi copykey.sh
#!/bin/bash
set -eux
#ansuser로 변경하여 해당 명령어 실행
sudo -u ansuser bash -c '
if [ ! -f /home/ansuser/.ssh/id_ed25519 ]; then
ssh-keygen -t ed25519 -f /home/ansuser/.ssh/id_ed25519 -N ""
fi
'
#/etc/ansible/hosts
sudo bash -c 'cat << EOF > /etc/ansible/hosts
[nodes]
node102 ansible_host=192.168.1.102 ansible_user=ansuser
node103 ansible_host=192.168.1.103 ansible_user=ansuser
node104 ansible_host=192.168.1.104 ansible_user=ansuser
EOF
'
for i in 2 3 4 ; do
IP="192.168.1.10${i}"
sudo -u ansuser bash -c "ssh-keyscan -H $IP >> /home/ansuser/.ssh/known_hosts"
sudo -u ansuser sshpass -p 'ansuser' ssh-copy-id -i /home/ansuser/.ssh/id_ed25519.pub ansuser@"$IP"
done
실행
sh copykey.sh
만약 오류가 났다면 useradd.sh가 정상적으로 실행되었는지 확인할 것 (ansuser가 있는지 확인하는것과 같음)

만약 가상머신에서 실행하지 않고 vagrantfile 내에서 provision을 추가하여 실행한다면 vagrantfile 내에 아래 내용으로 저장
# -*- mode: ruby -*-
# vi: set ft=ruby :
#=============#
# Node1 #
#=============#
Vagrant.configure("2") do |config|
config.vm.define "4gl-node" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.box_version = "8.10.20250220"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node1"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node1"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "install_pkg.sh"
cfg.vm.provision "file", source: "ping_2_nds.sh", destination: "ping_2_nds.sh"
cfg.vm.provision "shell", path: "userssh/useradd.sh"
cfg.vm.provision "file", source: "userssh/copykey.sh", destination: "userssh/copykey.sh"
end
#=============#
# Node2,3,4 #
#=============#
(2..4).each do |i|
config.vm.define "4gl-node#{i}" do |cfg|
cfg.vm.box = "almalinux/8"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "4gl-node#{i}"
vb.cpus = 2
vb.memory = 2048
vb.customize ["modifyvm", :id, "--groups", "/4gl-node"]
end
cfg.vm.host_name = "4gl-node#{i}"
cfg.vm.network "private_network", ip: "192.168.1.10#{i}"
cfg.vm.network "forwarded_port", guest: 22, host: "6010#{i}",auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "userssh/useradd.sh"
end
end
end
myname=4gl
echo myname
echo 뒤에 그대로 변수 이름을 쓰면 문자열로 인식하여 작성한 myname을 그대로 표시
echo $myname
변수는 사용 시 무조건 $를 붙여서 사용해야 변수인것을 인지하고 변수의 값을 출력함
echo '$myname'
''(작은 따옴표)는 내부의 문장을 문자열로 인식하여 그대로 표시함
echo "$myname"
""(큰 따옴표)는 내부의 변수를 변수의 값으로 치환하여 표시함
