Terraform을 이용한 openstack provisioning

Sbae·2023년 9월 14일
0
post-thumbnail

들어가기전

  • Terraform이 무엇이고 어떻게 동작하는지 알고본다면 좀 더 쉽게 이해할 수 있다.
  • 공식문서 하나만 보고 머리박으면서 했는데 다음부턴 강의 먼저 들어야지...

구조

.
|-- create_toml.sh
|-- main.tf
|-- modules
|   |-- controlplane-node
|   |   |-- openstack-compute.tf
|   |   |-- openstack-output.tf
|   |   `-- openstack-vars.tf
|   |-- network
|   |   |-- openstack-network.tf
|   |   `-- openstack-vars.tf
|   |-- nfs-node
|   |   |-- openstack-compute.tf
|   |   |-- openstack-output.tf
|   |   `-- openstack-vars.tf
|   |-- regi-node
|   |   |-- openstack-compute.tf
|   |   |-- openstack-output.tf
|   |   `-- openstack-vars.tf
|   `-- worker-node
|       |-- openstack-compute.tf
|       |-- openstack-output.tf
|       `-- openstack-vars.tf
|-- output.json
`-- variables.tf

Example

최상위 main.tf

  • 최상위 디렉토리의 main.tf로 하위 모듈들을 실행하기 위하여 variables.tf의 값을 읽어서 각각의 모듈에 값을 전달해주는 역할을한다.
  • depends_on = [ module.network ]을 적용하여 네트워크 생성 전 인스턴스가 먼저 만들어지는 에러를 방지하기 위하여 삽입했다.
terraform {
required_version = ">= 0.14.0"
  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 1.51.1"
    }
  }
}

provider "openstack" {
  user_name   = var.openstack_user_name
  tenant_name = var.openstack_tenant_name
  password    = var.openstack_password
  auth_url    = var.openstack_auth_url
  region      = var.openstack_region
}

module "network" {
  source       = "./modules/network"
  network_name = var.network_name
}

module "controlplane_node" {
  source = "./modules/controlplane-node"
  instance_title    = var.cp_instance_title
  instance_type     = var.instance_type
  instances         = var.openstack_cluster_instance_count
  public_key_file   = var.public_key_file
  private_key_file  = var.private_key_file
  image_name        = var.image_name
  network_name      = var.network_name
  depends_on        = [ module.network ]
}

module "worker_node" {
  source = "./modules/worker-node"
  ...
}

module "regi_node" {
  source = "./modules/regi-node"
  ...
}

module "nfs_node" {
  source = "./modules/nfs-node"
  ...
}

output "controlplane_node_ips" {
  value       = module.controlplane_node.ips
}

output "controlplane_node_private_ip" {
  value = module.controlplane_node.private_ip
}

output "worker_node_ips" {
  value = module.worker_node.ips
}

output "worker_node_private_ip" {
  value = module.worker_node.private_ip
}

output "regi_node_ips" {
  value = module.regi_node.ips
}

output "regi_node_private_ip" {
  value = module.regi_node.private_ip
}

output "nfs_node_ips" {
  value = module.nfs_node.ips
}

output "nfs_node_private_ip" {
  value = module.nfs_node.private_ip
}

Network 모듈

opstack의 인스턴스 생성 전 네트워크 구성을 먼저 해주기 위한 과정

openstack-network.tf

  • 라우터, 서브넷, 보안 그룹, 키페어을 생성하여 네트워크를 구성하는 과정
# keypair
resource "openstack_compute_keypair_v2" "generic" {
  name   = "${var.network_name}-ssh"
  public_key = file(var.public_key_file)
}

# 라우터 이름
resource "openstack_networking_router_v2" "generic" {
  name                = "${var.network_name}-router"
  external_network_id = "----"
}

# 네트워크 이름
resource "openstack_networking_network_v2" "generic" {
  name = "${var.network_name}-network"
}

# 서브넷 생성
resource "openstack_networking_subnet_v2" "generic" {
  name            = "${var.network_name}-subnet"
  network_id      = openstack_networking_network_v2.generic.id
  cidr            = "10.30.30.0/24"
  dns_nameservers = ["8.8.8.8", "8.8.8.4"]
}

# Router interface configuration
resource "openstack_networking_router_interface_v2" "generic" {
  router_id = openstack_networking_router_v2.generic.id
  subnet_id = openstack_networking_subnet_v2.generic.id
}

# 보안 그룹 규칙 생성
resource "openstack_compute_secgroup_v2" "generic" {
  name        = "${var.network_name}-sg"
  description = "${var.network_name}-sg"
  rule {
  	...
  }
}

cp 모듈

  • 다양한 OS 이미지를 사용하기 때문에 랜덤 값을 이용하여 각각의 다른 인스턴스를 생성한다.
  • 외부에서 접속을 위하여 플로팅 아이피도 생성한다.
# Random
resource "random_integer" "generic" {
  min = 0
  max = length(var.image_name) - 1
}

# Create instance
resource "openstack_compute_instance_v2" "generic" {
  count           = var.instances
  name            = "${var.instance_title}-${count.index+1}"
  # image_name      = var.image_name[count.index]
  image_name = element(var.image_name, random_integer.generic.result + count.index % length(var.image_name))
  flavor_name     = var.instance_type
  key_pair        = "${var.network_name}-ssh"
  security_groups = [
    "default",
    "${var.network_name}-sg"
  ]
  network {
    name = "${var.network_name}-network"
  }
}

# Create floating ip
resource "openstack_networking_floatingip_v2" "generic" {
  count = var.instances
  pool  = "public"
}
resource "openstack_compute_floatingip_associate_v2" "generic" {
  count       = var.instances
  floating_ip = "${element(openstack_networking_floatingip_v2.generic.*.address, count.index)}"
  instance_id = "${element(openstack_compute_instance_v2.generic.*.id, count.index)}"
}

방식

  1. 최상위 main.tf에서 모듈들을 실행하면 최우선적으로 네트워크 및 키페어를 구성하고
  2. cp, worker, nfs, regi 모듈들이 실행되면서 각각의 맞는 인스턴스들을 생성한다.
  3. create_toml.sh 쉘 스크립트를 사용하여 output.json으로 나오는 값들을 파싱하여 원하는 형태의 파일을 생성한다.
  4. 생성된 파일로 내가 따로 만든 앤시블 코드의 템플릿으로 사용하면 완성

참고 사이트

profile
끄적이는 일반인

0개의 댓글