vms.tf (6511B)
1 # based on the example from: 2 # https://github.com/dmacvicar/terraform-provider-libvirt/tree/master/examples/v0.12/ubuntu 3 4 locals { 5 all_hosts = merge(libvirt_domain.host, libvirt_domain.hosts_type2) 6 } 7 8 terraform { 9 required_providers { 10 libvirt = { 11 source = "dmacvicar/libvirt" 12 version = "0.6.14" 13 } 14 } 15 } 16 17 # todo: LIBVIRT_DEFAULT_URI does not work? 18 provider "libvirt" { 19 uri = "qemu:///system" 20 } 21 22 # libvirt pool for the images in the path of the tf module 23 resource "libvirt_pool" "pool" { 24 name = var.project 25 type = "dir" 26 path = abspath("${path.module}/libvirt-pool-${var.project}") 27 } 28 29 # backing image to save disk space for multiple vms 30 # https://kashyapc.fedorapeople.org/virt/lc-2012/snapshots-handout.html 31 resource "libvirt_volume" "base_volume" { 32 name = "${var.project}-base" 33 pool = libvirt_pool.pool.name 34 source = var.baseimage 35 format = var.baseimage_format 36 37 # todo: required for "terraform destroy" 38 depends_on = [libvirt_pool.pool] 39 } 40 41 resource "libvirt_volume" "volume" { 42 # unique image (based on backing file) for each host 43 for_each = toset(var.hosts) 44 45 name = "${var.project}-cow-${each.value}" 46 pool = libvirt_pool.pool.name 47 base_volume_id = libvirt_volume.base_volume.id 48 size = var.disk 49 } 50 51 52 # ssh private key 53 resource "tls_private_key" "id_rsa" { 54 algorithm = "RSA" 55 } 56 resource "local_sensitive_file" "ssh_private_key" { 57 content = tls_private_key.id_rsa.private_key_pem 58 filename = "${path.module}/../ssh/id_rsa" 59 file_permission = "0600" 60 } 61 resource "local_sensitive_file" "ssh_public_key" { 62 content = tls_private_key.id_rsa.public_key_openssh 63 filename = "${path.module}/../ssh/id_rsa.pub" 64 } 65 66 67 # cloud init config files 68 data "template_file" "user_data" { 69 template = file("${path.module}/${var.cloudinit_userdata}") 70 } 71 data "template_file" "network_config" { 72 template = file("${path.module}/${var.cloudinit_networkconfig}") 73 } 74 # for more info about paramater check this out 75 # https://github.com/dmacvicar/terraform-provider-libvirt/blob/master/website/docs/r/cloudinit.html.markdown 76 # Use CloudInit to add our ssh-key to the instance 77 # you can add also meta_data field 78 resource "libvirt_cloudinit_disk" "commoninit" { 79 name = var.cloudinit_iso 80 user_data = data.template_file.user_data.rendered 81 network_config = data.template_file.network_config.rendered 82 pool = libvirt_pool.pool.name 83 } 84 85 resource "libvirt_domain" "host" { 86 # create each host 87 for_each = toset(var.hosts) 88 89 name = each.value 90 memory = var.memory 91 vcpu = var.vcpu 92 93 cloudinit = libvirt_cloudinit_disk.commoninit.id 94 qemu_agent = false 95 96 network_interface { 97 network_name = libvirt_network.network.name 98 wait_for_lease = true 99 } 100 101 # IMPORTANT: this is a known bug on cloud images, since they expect a console 102 # we need to pass it 103 # https://bugs.launchpad.net/cloud-images/+bug/1573095 104 console { 105 type = "pty" 106 target_port = "0" 107 target_type = "serial" 108 } 109 110 console { 111 type = "pty" 112 target_type = "virtio" 113 target_port = "1" 114 } 115 116 disk { 117 volume_id = libvirt_volume.volume[each.value].id 118 } 119 120 graphics { 121 type = "spice" 122 listen_type = "address" 123 autoport = true 124 } 125 } 126 127 resource "libvirt_network" "network" { 128 name = var.project 129 130 # mode can be: "nat" (default), "none", "route", "bridge" 131 mode = "nat" 132 autostart = true 133 134 # the domain used by the DNS server in this network 135 domain = var.domain 136 137 # list of subnets the addresses allowed for domains connected 138 # also derived to define the host addresses 139 # also derived to define the addresses served by the DHCP server 140 addresses = [var.network] 141 142 # (optional) the bridge device defines the name of a bridge device 143 # which will be used to construct the virtual network. 144 # (only necessary in "bridge" mode) 145 # bridge = "br7" 146 147 # (optional) the MTU for the network. If not supplied, the underlying device's 148 # default is used (usually 1500) 149 # mtu = 9000 150 151 # (Optional) DNS configuration 152 dns { 153 # (Optional, default false) 154 # Set to true, if no other option is specified and you still want to 155 # enable dns. 156 enabled = true 157 # (Optional, default false) 158 # true: DNS requests under this domain will only be resolved by the 159 # virtual network's own DNS server 160 # false: Unresolved requests will be forwarded to the host's 161 # upstream DNS server if the virtual network's DNS server does not 162 # have an answer. 163 local_only = true 164 165 # (Optional) one or more DNS forwarder entries. One or both of 166 # "address" and "domain" must be specified. The format is: 167 # forwarders { 168 # address = "my address" 169 # domain = "my domain" 170 # } 171 # 172 173 # (Optional) one or more DNS host entries. Both of 174 # "ip" and "hostname" must be specified. The format is: 175 # hosts { 176 # hostname = "my_hostname" 177 # ip = "my.ip.address.1" 178 # } 179 # hosts { 180 # hostname = "my_hostname" 181 # ip = "my.ip.address.2" 182 # } 183 # 184 185 # not possible due to cyclic dependency 186 # use Ansible instead and amend manually, see ('../ansible/dhcp-static-hosts.yml') 187 # dynamic "hosts" { 188 # for_each = var.hosts 189 # content { 190 # hostname = hosts.value 191 # ip = tolist(libvirt_domain.host[hosts.value].network_interface)[0]["addresses"][0] 192 # } 193 # } 194 195 # (Optional) one or more static routes. 196 # "cidr" and "gateway" must be specified. The format is: 197 # routes { 198 # cidr = "10.17.0.0/16" 199 # gateway = "10.18.0.2" 200 # } 201 } 202 203 dhcp { 204 enabled = true 205 } 206 } 207 208 resource "null_resource" "update_cloudinit" { 209 triggers = { 210 # when the ssh key in the local cloudinit file changes 211 key_id = local_sensitive_file.ssh_public_key.id 212 } 213 provisioner "local-exec" { 214 # recreate cloudinit config 215 command = "echo '${templatefile("${path.module}/templates/cloud_init.cfg.tpl", { public_key = tls_private_key.id_rsa.public_key_openssh })}' > ./cloud_init.cfg" 216 } 217 }