질문:
terraform + extra_config + Ubuntu 클라우드 이미지를 사용하여 Cloud Init과 인터페이스하고 메타데이터/사용자 데이터를 제공하는 데 성공한 사람이 있나요? 이것이 DataSourceVMware와 상호 작용할 수 있기를 바라지만 현 단계에서는 확신할 수 없습니다.
내가 한 일:
저는 Terraform을 사용하여 VMware vSphere 7에 Ubuntu 클라우드 이미지를 배포하고 있습니다. vApp 속성을 사용하는 것은 충분히 쉽습니다.
... below code snipped from resource "vsphere_virtual_machine" "vm" { }
vapp {
properties = {
hostname = var.vm_Name_Lower
instance-id = var.vm_Name_Lower
user-data = base64encode(file("${path.module}/userdata.yml"))
}
}
그러나 extra_config를 사용하려는 시도는 실패했습니다. guestinfo.metadata와 guestinfo.userdata를 모두 제공하고 싶습니다. 그러나 현재 메타데이터(아래 참조)를 사용한 테스트는 호스트 이름이 VM에 설정되지 않았기 때문에 실패한 것으로 나타났습니다.
data "cloudinit_config" "metadata" {
gzip = true
base64_encode = true
part {
content_type = "text/cloud-config"
content = <<-EOF
local-hostname: testvm
instance-id: testvm
EOF
}
}
... below code snipped from resource "vsphere_virtual_machine" "vm" { }
extra_config = {
"guestinfo.metadata" = data.cloudinit_config.metadata.rendered
"guestinfo.metadata.encoding" = "gzip+base64"
}
extra_config가 전송되었음을 증명하는 vSphere 로그 항목을 볼 수 있습니다.
config.extraConfig("guestinfo.metadata"): (key = "guestinfo.metadata", value = "H4sIAAAAAAAA/2SOTUvGMBCE74H8h/De11dPQsSDHz14qIK ... snipped
참고자료:
- https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config
- https://github.com/vmware-archive/cloud-init-vmware-guestinfo
- https://grantorchard.com/terraform-vsphere-cloud-init/
- https://github.com/rgl/terraform-vsphere-ubuntu-example/blob/master/main.tf
버전 세부정보:
Client system (on which terraform is run): Ubuntu 20.04.3 LTS
ESXi: 7.0.2 / Build: 18538813
vCenter Server: 7.0.2 / Build: 18455184
Cloud Image: https://cloud-images.ubuntu.com/impish/current/impish-server-cloudimg-amd64.ova
Terraform v1.0.7
on linux_amd64
provider registry.terraform.io/hashicorp/template v2.2.0
provider registry.terraform.io/hashicorp/vsphere v1.24.3
답변1
문제는 cloud-init에 기본적으로 새 VMware 데이터 소스(cloud-init 21.3 기준) 이전에 호출된 OVF 데이터 소스 공급자가 있다는 것입니다. Terraform은 OVF 데이터 소스 공급자가 좋아하는 데이터를 제공하므로 정보를 처리합니다. 이는 vApp 속성 "user-data"가 cloud-config를 허용하는 이유를 설명합니다.
해결 방법은 cloud-init에서 OVF 데이터 소스 공급자를 제거하는 것입니다.
- [웹 브라우저[ OVA 다운로드: https://cloud-images.ubuntu.com/impish/current/impish-server-cloudimg-amd64.ova
- [VC UI] OVF에서 배포하고 기본값을 수락합니다(디스크 프로비저닝 제외, 씬 프로비저닝 사용).
- [VC UI] 설정 편집 / VM 옵션 / 부팅 옵션 / 부팅 지연 = 2000ms.
- [VC UI] VM 콘솔을 엽니다.
- [VM 콘솔] VM 전원을 켭니다.
- [VM 콘솔] BIOS 화면에서 Shift 키를 누르고 있습니다(GRUB가 메뉴를 표시하도록 함).
- [VM 콘솔] Ubuntu 고급 옵션을 선택합니다.
- [VM 콘솔] 끝에 "(복구 모드)"가 있는 최신 커널 버전을 선택합니다.
- [VM 콘솔] "root / 루트 쉘 프롬프트에 놓기"를 선택합니다.
- [VM 콘솔] 유지 관리를 위해 Enter 키를 누르세요.
- [VM 콘솔] # dpkg-reconfigure cloud-init
- [VM 콘솔] VMware 및 None을 제외한 모든 항목을 선택 취소합니다.
- [VM 콘솔] # cloud-init clean
- [VM 콘솔] # shutdown -h 지금
- [VC UI] 설정 편집 / VM 옵션 / 부팅 옵션 / 부팅 지연 = 0ms.
- [VC UI] 템플릿으로 변환
답변2
Ubuntu 클라우드 OVA에서도 동일한 작업을 수행하여 이에 대한 약간의 해결 방법을 찾았습니다. 재부팅이 필요하기 때문에 이상적이지는 않습니다. 즉, local-exec
인스턴스가 실제로 완료되는 시기를 감지하려면 프로비저너가 필요하지만 작동합니다.
사용자 데이터에 사용하는 두 개의 yaml 파일이 있다고 가정해 보겠습니다. 첫 번째 파일은 이름이 vApp 속성으로 전달 vapp-userdata.yaml
되고 두 번째 파일은 이름이 VMware 데이터 소스로 전달됩니다.guest-userdata.yaml
Terraform에서 이와 같은 것
vapp {
properties = {
user-data = base64encode(data.template_file.vapp_userdata[count.index].rendered)
}
}
extra_config = {
"guestinfo.metadata" = base64encode(data.template_file.guest-metadata[count.index].rendered)
"guestinfo.metadata.encoding" = "base64"
"guestinfo.userdata" = base64encode(data.template_file.userdata.rendered)
"guestinfo.userdata.encoding" = "base64"
}
현재 데이터 소스 정의를 덮어쓰고 이미 해당 지점에 도달하면 제거하는 vapp-userdata.yaml
작업이 있습니다 .write_file
OVF
write_files:
- path: /etc/cloud/cloud.cfg.d/90_dpkg.cfg
owner: root:root
permissions: "0644"
content: |
datasource_list: [ VMware, None ]
그런 다음 하단에서 재부팅으로 마무리합니다.
power_state:
timeout: 600
mode: reboot
VMware
마지막 명령 후 VM이 재부팅되면 새 cloud-init 구성에 정의된 대로 데이터 소스를 읽고 사용자 guest-userdata.yaml
가 metadata.yaml
정의한 경우 이를 처리합니다.
작업이 언제 완료되는지 감지하는 데 있어서는 여전히 최선의 방법을 찾으려고 노력 중입니다. 쉬운 방법은 nc -l 12345
끝에서 시작하여 guest-userdata.yaml
연결할 수 있을 때 진행되는 로컬 프로비저너를 갖지만 이상적이지 않은 tcp/12345
netcat 리스너를 열어 두는 것입니다 .tcp/12345
더 좋은 방법을 찾으시면 답변 부탁드립니다 :)
편집하다
더 나은 방법이 분명 있겠지만...
하단에는guest-userdata.yaml
runcmd:
- mkdir -p /mnt/sharedfolder
- sysctl -w vm.overcommit_memory=1
- sysctl -w kernel.panic=10
- sysctl -w kernel.panic_on_oops=1
- curl https://releases.rancher.com/install-docker/${docker_version}.sh | sh
- usermod -aG docker ubuntu
- nc -l 1234 & ncpid=$! #start nc and get PID
- sleep 20
- kill $ncpid #kill PID once Terraform has had time to connect
.tf
그런 다음 파일 끝에 프로비저너로
provisioner "local-exec" {
# Wait for cloud-init userdata cmds
# Netcat: z (scan port only), w1 (wait 1 second)
command = "count=0; until $(nc -zw1 ${self.default_ip_address} 1234); do sleep 1; count=`expr $count + 1`; done"
}