이제 먼저 앤서블 실행 시 필요한 인벤토리 파일을 만듦
[root@IaC opentofu]# vi inventory.tf
resource "local_file" "ansible_inventory" {
filename = "../ansible/hosts"
content = templatefile("${path.module}/inventory.tpl", {
haproxy_ip = openstack_compute_instance_v2.haproxy_server.network[0].fixed_ip_v4
control_ips = openstack_compute_instance_v2.control_plane[*].network[0].fixed_ip_v4
worker_ips = openstack_compute_instance_v2.worker_node[*].network[0].fixed_ip_v4
all_nodes_ips = concat(
openstack_compute_instance_v2.control_plane[*].network[0].fixed_ip_v4,
openstack_compute_instance_v2.worker_node[*].network[0].fixed_ip_v4,
)
})
}
[root@IaC opentofu]# vi inventory.tpl
[all:vars]
ansible_user=rocky
ansible_ssh_private_key_file=/root/.ssh/id_ed25519_k8s
ansible_python_interpreter=/usr/bin/python3
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
[k8s_cluster:children]
control
worker
haproxy
[haproxy]
proxy ansible_host=${haproxy_ip}
[control]
%{ for ip in control_ips ~}
control${index(control_ips, ip) + 1} ansible_host=${ip}
%{ endfor ~}
[worker]
%{ for ip in worker_ips ~}
worker${index(worker_ips, ip) + 1} ansible_host=${ip}
%{ endfor ~}
[root@IaC opentofu]# vi hosts.tf
locals {
control_host_lines = [
for i in range(3) :
"${openstack_compute_instance_v2.control_plane[i].network[0].fixed_ip_v4} control${i + 1}"
]
worker_host_lines = [
for i in range(5) :
"${openstack_compute_instance_v2.worker_node[i].network[0].fixed_ip_v4} worker${i + 1}"
]
k8s_nodes_hosts = join("\n", concat(local.control_host_lines, local.worker_host_lines))
haproxy_host = "${openstack_compute_instance_v2.haproxy_server.network[0].fixed_ip_v4} proxy"
}
resource "null_resource" "update_hosts_file" {
depends_on = [
openstack_compute_instance_v2.haproxy_server,
openstack_compute_instance_v2.control_plane,
openstack_compute_instance_v2.worker_node,
]
provisioner "local-exec" {
command = <<-EOT
HOSTS_FILE=/etc/hosts
sed -i '/# K8S NODES START/,/# K8S NODES END/d' $HOSTS_FILE
HOSTS_ENTRY="${local.haproxy_host}\n${local.k8s_nodes_hosts}"
echo "" >> $HOSTS_FILE
echo "# K8S NODES START" >> $HOSTS_FILE
echo "$HOSTS_ENTRY" >> $HOSTS_FILE
echo "# K8S NODES END" >> $HOSTS_FILE
EOT
}
}
총 3개의 코드를 더 만들어 줌. IaC 노드의 /etc/hosts에 노드들 등록, 앤서블 인벤토리 탬플릿과 그걸로 생성하는 코드 하나
해서 tofu init --upgrade 후 다시 apply 적용해주면 앤서블 디렉터리 밑에 hosts파일이 생기고 /etc/hosts에도 등록이 됨
[root@IaC opentofu]# tofu apply
data.openstack_compute_flavor_v2.haproxy_flavor: Reading...
data.openstack_compute_flavor_v2.k8s_node_flavor: Reading...
data.openstack_compute_flavor_v2.k8s_node_flavor: Read complete after 0s [id=ee1b3749-219e-4665-afb3-6d25b00d2d97]
data.openstack_compute_flavor_v2.haproxy_flavor: Read complete after 0s [id=774c9136-d522-4466-8097-a907dd4b50a8]
OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
OpenTofu will perform the following actions:
# local_file.ansible_inventory will be created
+ resource "local_file" "ansible_inventory" {
+ content = (known after apply)
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
...
openstack_compute_instance_v2.worker_node[1]: Still creating... [40s elapsed]
openstack_compute_instance_v2.worker_node[3]: Creation complete after 43s [id=917c9374-a4c0-4c81-898b-a528b842d8ab]
openstack_compute_instance_v2.control_plane[1]: Creation complete after 43s [id=4ab644fe-4f58-4d17-abfa-765fe6770253]
openstack_compute_instance_v2.control_plane[0]: Creation complete after 42s [id=c275c046-0d1a-40de-877a-a5a228c332b4]
openstack_compute_instance_v2.worker_node[1]: Still creating... [50s elapsed]
openstack_compute_instance_v2.worker_node[1]: Creation complete after 53s [id=3911b782-8389-49c9-ba08-699bfb05c2e1]
null_resource.update_hosts_file: Creating...
null_resource.update_hosts_file: Provisioning with 'local-exec'...
null_resource.update_hosts_file (local-exec): Executing: ["/bin/sh" "-c" "HOSTS_FILE=/etc/hosts\n \nsed -i '/# K8S NODES START/,/# K8S NODES END/d' $HOSTS_FILE\n \nHOSTS_ENTRY=\"10.0.1.50 haproxy\\n10.0.4.241 control1\n10.0.5.22 control2\n10.0.2.133 control3\n10.0.3.249 worker1\n10.0.5.69 worker2\n10.0.3.165 worker3\n10.0.3.6 worker4\n10.0.5.126 worker5\"\n \necho \"\" >> $HOSTS_FILE\necho \"# K8S NODES START\" >> $HOSTS_FILE\necho \"$HOSTS_ENTRY\" >> $HOSTS_FILE\necho \"# K8S NODES END\" >> $HOSTS_FILE\n"]
local_file.ansible_inventory: Creating...
null_resource.update_hosts_file: Creation complete after 0s [id=5926752306975499695]
local_file.ansible_inventory: Creation complete after 0s [id=55527eea0bdf8a0ce8d1c2b57f36909314b3ea1a]
Apply complete! Resources: 21 added, 0 changed, 0 destroyed.
Outputs:
all_nodes_ips = [
"10.0.4.241",
"10.0.5.22",
"10.0.2.133",
"10.0.3.249",
"10.0.5.69",
"10.0.3.165",
"10.0.3.6",
"10.0.5.126",
]
control_plane_ips = [
"10.0.4.241",
"10.0.5.22",
"10.0.2.133",
]
haproxy_internal_ip = "10.0.1.50"
kube_api_endpoint = "121.254.163.236"
worker_node_ips = [
"10.0.3.249",
"10.0.5.69",
"10.0.3.165",
"10.0.3.6",
"10.0.5.126",
]
[root@IaC opentofu]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# K8S NODES START
10.0.1.50 proxy
10.0.4.241 control1
10.0.5.22 control2
10.0.2.133 control3
10.0.3.249 worker1
10.0.5.69 worker2
10.0.3.165 worker3
10.0.3.6 worker4
10.0.5.126 worker5
# K8S NODES END
이제 진짜 앤서블로 클러스터 구성이 가능한 사전 준비가 끝났지만 그 전에 형상관리를 위한 저장소를 구축하고자 함
저장소 인스턴스 하나 만들고 podman 컨테이너로 도커 레지스트리, 깃티, 미니오를 띄워 내부망 저장소를 만듦
[root@IaC opentofu]# cd ..
[root@IaC ~]# ls
ansible opentofu
[root@IaC ~]# mkdir tofu-backend
[root@IaC ~]# cd tofu-backend/
[root@IaC ~]# pwd
/root/tofu-backend
이후 프로바이더 똑같이 설정하고 디스크 추가하고 인스턴스 생성 코드 만들고 인벤토리에 얘도 추가시켜 줌.
보안 그룹은 귀찮으니 이전에 만들어놨던 거 모든 TCP 허용 그룹 하나 가져와서 쓴다.
여기서 디스크를 각 컨테이너마다 하나씩 추가한 이유는 관리 용이하게 하기 위해서와 인스턴스가 죽어도 데이터는 건질 수 있어서 이렇게 함
물론 한 디스크로 파티션을 나눠서 해도 되지만 이것도 그냥 이렇게 함
[root@IaC tofu-backend]# vi provider.tf
terraform {
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.50.0"
}
}
}
provider "openstack" {
insecure = true
region = "RegionOne"
}
[root@IaC tofu-backend]# vi repo-instance.tf
data "openstack_images_image_v2" "image" {
name = "lab-rocky-9"
}
data "openstack_compute_flavor_v2" "backend_flavor" {
name = "m1.medium"
}
resource "openstack_compute_instance_v2" "backend_server" {
name = "repository"
flavor_id = data.openstack_compute_flavor_v2.backend_flavor.id
image_id = data.openstack_images_image_v2.image.id
key_pair = "k8s-keypair"
security_groups = ["lab"]
network {
name = "net-infra"
}
}
resource "null_resource" "ansible_host_update" {
triggers = {
backend_ip = openstack_compute_instance_v2.backend_server.access_ip_v4
}
provisioner "local-exec" {
command = <<EOT
BACKEND_IP="${self.triggers.backend_ip}"
HOST_NAME="${openstack_compute_instance_v2.backend_server.name}"
HOSTS_FILE="/root/ansible/hosts"
sed -i "/^$HOST_NAME/d" $HOSTS_FILE
if ! grep -q "\\[repo\\]" $HOSTS_FILE; then
echo -e "\n[repo]" >> $HOSTS_FILE
fi
echo "$HOST_NAME ansible_host=$BACKEND_IP" >> $HOSTS_FILE
echo "--- Updated Ansible Hosts File ---"
cat $HOSTS_FILE
EOT
}
}
tofu apply 로 실행하면 맨 아래 저장소 노드도 추가됨 이걸로 컨테이너 저장소 배포 자동화까지 하면 됨
[root@IaC tofu-backend]# cat /root/ansible/hosts
[all:vars]
ansible_user=rocky
ansible_ssh_private_key_file=/root/.ssh/id_ed25519_k8s
ansible_python_interpreter=/usr/bin/python3
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
[k8s_cluster:children]
control
worker
haproxy
[haproxy]
proxy ansible_host=10.0.1.50
[control]
control1 ansible_host=10.0.4.241
control2 ansible_host=10.0.5.22
control3 ansible_host=10.0.2.133
[worker]
worker-1 ansible_host=10.0.3.249
worker-2 ansible_host=10.0.5.69
worker-3 ansible_host=10.0.3.165
worker-4 ansible_host=10.0.3.6
worker-5 ansible_host=10.0.5.126
[repo]
repo ansible_host=10.0.2.163
그리고 IaC 노드의 hosts에도 등록해줌. 이제 앤서블로 컨테이너 띄우면 됨
[root@IaC tofu-backend]# awk -F"[ =]+" 'END{ print $3, $1 }' /root/ansible/hosts >> /etc/hosts
[root@IaC tofu-backend]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# K8S NODES START
10.0.1.50 proxy
10.0.4.241 control1
10.0.5.22 control2
10.0.2.133 control3
10.0.3.249 worker1
10.0.5.69 worker2
10.0.3.165 worker3
10.0.3.6 worker4
10.0.5.126 worker5
# K8S NODES END
10.0.2.163 repository
이제 앤서블로 핑 테스트해서 석세스가 뜨면 생성이랑 연결은 잘 된 거
[root@IaC tofu-backend]# cd ../ansible
[root@IaC ansible]# ansible repository -i hosts -m ping
repository | SUCCESS => {
"changed": false,
"ping": "pong"
}
'리눅스 > 실습' 카테고리의 다른 글
| 내부 저장소 구축과 연동 - 1 (0) | 2025.11.10 |
|---|---|
| IaC 실습하기-3 (0) | 2025.11.10 |
| IaC 실습하기-1 (0) | 2025.11.09 |
| 웹서버에 TLS 적용하기 (0) | 2025.11.08 |
| 워드프레스 LEMP 서버 구축하기-2 (0) | 2025.11.08 |