====== Terraform libvirt ======
$ mkdir -p ~/terraform/projects/libvirt
$ cd ~/terraform/projects/libvirt
$ sudo usermod -aG kvm,libvirt $USER
$ sudo echo 'security_driver = [ "none" ]'> /etc/libvirt/qemu.conf
$ sudo systemctl restart libvirtd
===== Provider =====
terraform {
required_providers{
libvirt = {
source = "dmacvicar/libvirt"
}
}
}
provider "libvirt" {
uri = "qemu:///system"
}
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of dmacvicar/libvirt...
- Installing dmacvicar/libvirt v0.7.0...
- Installed dmacvicar/libvirt v0.7.0 (self-signed, key ID 96B1FE1A8D4E1EAB)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
===== Cloudinit =====
$ cat cloud_init.cfg
#cloud-config
ssh_pwauth: True
chpasswd:
list: |
root:centos
expire: False
===== Definição da VM =====
resource "libvirt_volume" "rhel" {
name = "rhel.qcow2"
pool = "default"
source = "/media/gean/HD1T/terraform/imagens/CentOS-7-x86_64-GenericCloud-1907.qcow2"
format = "qcow2"
}
resource "libvirt_domain" "centos" {
name = "rhel-vm-01"
memory = "2048"
vcpu = 2
cpu {
mode = "host-passthrough"
}
network_interface {
network_name = "default"
}
disk {
volume_id = libvirt_volume.rhel.id
}
cloudinit = libvirt_cloudinit_disk.commoninit.id
}
data "template_file" "user_data" {
template = file("${path.module}/cloud_init.cfg")
}
resource "libvirt_cloudinit_disk" "commoninit" {
name = "commoninit.iso"
pool = "default"
user_data = data.template_file.user_data.rendered
}
FIXME para criar a ISO do cloudinit e necessário ter o pacote ''mkisofs'' instalado
$ sudo apt install mkisofs
FIXME ao inserir as informações do cloudinit e necessário rodar o comando ''terraform init''
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of dmacvicar/libvirt from the dependency lock file
- Reusing previous version of hashicorp/template from the dependency lock file
- Using previously-installed dmacvicar/libvirt v0.7.0
- Using previously-installed hashicorp/template v2.2.0
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
$ terraform validate
Success! The configuration is valid.
$ terraform plan
data.template_file.user_data: Reading...
data.template_file.user_data: Read complete after 0s [id=38d0b2e21a479aa114d51308d5e8f703a259f0334672b592d371315305aa28dd]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# libvirt_cloudinit_disk.commoninit will be created
+ resource "libvirt_cloudinit_disk" "commoninit" {
+ id = (known after apply)
+ name = "commoninit.iso"
+ pool = "default"
+ user_data = <<-EOT
#cloud-config
ssh_pwauth: True
chpasswd:
list: |
root:centos
expire: False
EOT
}
# libvirt_domain.centos will be created
+ resource "libvirt_domain" "centos" {
+ arch = (known after apply)
+ autostart = (known after apply)
+ cloudinit = (known after apply)
+ emulator = (known after apply)
+ fw_cfg_name = "opt/com.coreos/config"
+ id = (known after apply)
+ machine = (known after apply)
+ memory = 2048
+ name = "rhel-vm-01"
+ qemu_agent = false
+ running = true
+ vcpu = 2
+ cpu {
+ mode = "host-passthrough"
}
+ disk {
+ scsi = false
+ volume_id = (known after apply)
}
+ network_interface {
+ addresses = (known after apply)
+ hostname = (known after apply)
+ mac = (known after apply)
+ network_id = (known after apply)
+ network_name = "default"
}
}
# libvirt_volume.rhel will be created
+ resource "libvirt_volume" "rhel" {
+ format = "qcow2"
+ id = (known after apply)
+ name = "rhel.qcow2"
+ pool = "default"
+ size = (known after apply)
+ source = "/media/gean/HD1T/terraform/imagens/CentOS-7-x86_64-GenericCloud-1907.qcow2"
}
Plan: 3 to add, 0 to change, 0 to destroy.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
$ terraform apply
data.template_file.user_data: Reading...
data.template_file.user_data: Read complete after 0s [id=38d0b2e21a479aa114d51308d5e8f703a259f0334672b592d371315305aa28dd]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# libvirt_cloudinit_disk.commoninit will be created
+ resource "libvirt_cloudinit_disk" "commoninit" {
+ id = (known after apply)
+ name = "commoninit.iso"
+ pool = "default"
+ user_data = <<-EOT
#cloud-config
ssh_pwauth: True
chpasswd:
list: |
root:centos
expire: False
EOT
}
# libvirt_domain.centos will be created
+ resource "libvirt_domain" "centos" {
+ arch = (known after apply)
+ autostart = (known after apply)
+ cloudinit = (known after apply)
+ emulator = (known after apply)
+ fw_cfg_name = "opt/com.coreos/config"
+ id = (known after apply)
+ machine = (known after apply)
+ memory = 2048
+ name = "rhel-vm-01"
+ qemu_agent = false
+ running = true
+ vcpu = 2
+ cpu {
+ mode = "host-passthrough"
}
+ disk {
+ scsi = false
+ volume_id = (known after apply)
}
+ network_interface {
+ addresses = (known after apply)
+ hostname = (known after apply)
+ mac = (known after apply)
+ network_id = (known after apply)
+ network_name = "default"
}
}
# libvirt_volume.rhel will be created
+ resource "libvirt_volume" "rhel" {
+ format = "qcow2"
+ id = (known after apply)
+ name = "rhel.qcow2"
+ pool = "default"
+ size = (known after apply)
+ source = "/media/gean/HD1T/terraform/imagens/CentOS-7-x86_64-GenericCloud-1907.qcow2"
}
Plan: 3 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
libvirt_cloudinit_disk.commoninit: Creating...
libvirt_volume.rhel: Creating...
libvirt_volume.rhel: Creation complete after 0s [id=/var/lib/libvirt/images/rhel.qcow2]
libvirt_cloudinit_disk.commoninit: Creation complete after 0s [id=/var/lib/libvirt/images/commoninit.iso;2acc6e5e-a06e-4b68-9312-3a5ed7037ee7]
libvirt_domain.centos: Creating...
libvirt_domain.centos: Creation complete after 1s [id=b795f0ef-4c63-4f31-943c-84336aae83fa]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
===== Acessando a vm =====
$ virsh list
Id Name State
----------------------------
2 rhel-vm-01 running
$ virsh domiflist rhel-vm-01
Interface Type Source Model MAC
-------------------------------------------------------------
vnet1 network default virtio 52:54:00:26:9a:49
$ virsh net-dhcp-leases default
Expiry Time MAC address Protocol IP address Hostname Client ID or DUID
---------------------------------------------------------------------------------------------------------
2022-11-26 11:54:26 52:54:00:26:9a:49 ipv4 192.168.122.171/24 - -
2022-11-26 11:44:22 52:54:00:e2:1d:d8 ipv4 192.168.122.157/24 - -
$ ssh root@192.168.122.171
The authenticity of host '192.168.122.171 (192.168.122.171)' can't be established.
ED25519 key fingerprint is SHA256:wece0Y0KeVmt2ZHBw+990HGGE99zBINbKyfq1wshDhU.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.122.171' (ED25519) to the list of known hosts.
root@192.168.122.171's password:
[root@localhost ~]#
===== Destruindo a vm =====
$ terraform destroy
data.template_file.user_data: Reading...
data.template_file.user_data: Read complete after 0s [id=38d0b2e21a479aa114d51308d5e8f703a259f0334672b592d371315305aa28dd]
libvirt_cloudinit_disk.commoninit: Refreshing state... [id=/var/lib/libvirt/images/commoninit.iso;2acc6e5e-a06e-4b68-9312-3a5ed7037ee7]
libvirt_volume.rhel: Refreshing state... [id=/var/lib/libvirt/images/rhel.qcow2]
libvirt_domain.centos: Refreshing state... [id=b795f0ef-4c63-4f31-943c-84336aae83fa]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# libvirt_cloudinit_disk.commoninit will be destroyed
- resource "libvirt_cloudinit_disk" "commoninit" {
- id = "/var/lib/libvirt/images/commoninit.iso;2acc6e5e-a06e-4b68-9312-3a5ed7037ee7" -> null
- name = "commoninit.iso" -> null
- pool = "default" -> null
- user_data = <<-EOT
#cloud-config
ssh_pwauth: True
chpasswd:
list: |
root:centos
expire: False
EOT -> null
}
# libvirt_domain.centos will be destroyed
- resource "libvirt_domain" "centos" {
- arch = "x86_64" -> null
- autostart = false -> null
- cloudinit = "/var/lib/libvirt/images/commoninit.iso;2acc6e5e-a06e-4b68-9312-3a5ed7037ee7" -> null
- cmdline = [] -> null
- emulator = "/usr/bin/qemu-system-x86_64" -> null
- fw_cfg_name = "opt/com.coreos/config" -> null
- id = "b795f0ef-4c63-4f31-943c-84336aae83fa" -> null
- machine = "ubuntu" -> null
- memory = 2048 -> null
- name = "rhel-vm-01" -> null
- qemu_agent = false -> null
- running = true -> null
- vcpu = 2 -> null
- cpu {
- mode = "host-passthrough" -> null
}
- disk {
- scsi = false -> null
- volume_id = "/var/lib/libvirt/images/rhel.qcow2" -> null
}
- network_interface {
- addresses = [
- "192.168.122.171",
] -> null
- mac = "52:54:00:26:9A:49" -> null
- network_id = "06757d40-0b1c-4a1e-bb10-12cd6be3722c" -> null
- network_name = "default" -> null
- wait_for_lease = false -> null
}
}
# libvirt_volume.rhel will be destroyed
- resource "libvirt_volume" "rhel" {
- format = "qcow2" -> null
- id = "/var/lib/libvirt/images/rhel.qcow2" -> null
- name = "rhel.qcow2" -> null
- pool = "default" -> null
- size = 8589934592 -> null
- source = "/media/gean/HD1T/terraform/imagens/CentOS-7-x86_64-GenericCloud-1907.qcow2" -> null
}
Plan: 0 to add, 0 to change, 3 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
libvirt_domain.centos: Destroying... [id=b795f0ef-4c63-4f31-943c-84336aae83fa]
libvirt_domain.centos: Destruction complete after 0s
libvirt_cloudinit_disk.commoninit: Destroying... [id=/var/lib/libvirt/images/commoninit.iso;2acc6e5e-a06e-4b68-9312-3a5ed7037ee7]
libvirt_volume.rhel: Destroying... [id=/var/lib/libvirt/images/rhel.qcow2]
libvirt_cloudinit_disk.commoninit: Destruction complete after 0s
libvirt_volume.rhel: Destruction complete after 0s
Destroy complete! Resources: 3 destroyed.
===== Referências =====
- [[https://github.com/bodsch/terraform-libvirt|KVM Provider]]
- [[https://computingforgeeks.com/how-to-provision-vms-on-kvm-with-terraform|How To Provision VMs on KVM with Terraform]]
- [[https://yum.oracle.com/oracle-linux-templates.html|Oracle Linux Cloud Images]]