VM provisioning with Jenkins and Terraform on KVM
In this CI/CD activities we are going to provisioning a virtual guest on KVM host using Terraform and Jenkins.
Officially, Terraform does not have provider for KVM. But we are going to use third party provider for this.
I assume that host that runs terraform able to connect to the KVM hypervisor over ssh without password authentication. To do so, We already configured KVM hypervisor to logged in with SSH private key.
terraformm-provider-libvirt is a compiled binary, which needs to be put into the /terraform.d/plugins/linux_amd64 folder. You can find the compiled releases here or you can compile by yourself from the source. We are going to create following folder structure for Terraform.
libvirt/
├── libvirt.tf
├── terraform.d
│ └── plugins
│ └── linux_amd64
│ └── terraform-provider-libvirt
#libvirt.tf
provider "libvirt" {
uri = "qemu+ssh://[email protected]/system"
}
resource "libvirt_volume" "centos7-test" {
name = "centos7-test"
format = "qcow2"
pool = "KVMGuests"
source = "http://oregon.anatolia.io/qcow2-repo/centos71.qcow2"
}
resource "libvirt_domain" "centos7-test" {
autostart = "true"
name = "centos7-test"
memory = "2048"
vcpu = 2
running = "true"
network_interface{
hostname = "centos7-test"
network_name = "default"
}
disk {
volume_id = "${libvirt_volume.centos7-test.id}"
}
console {
type = "pty"
target_type = "virtio"
target_port = "1"
}
}
Creating a Pipeline in Jenkins
In this section Pipeline script has been created that needs to be defined in the Pipeline.
pipeline{
agent {label 'master'}
stages{
stage('TF Init'){
steps{
sh '''
cd /data/projects/terraform/libvirt
terraform init
'''
}
}
stage('TF Plan'){
steps{
sh '''
cd /data/projects/terraform/libvirt
terraform plan -out createkvm
'''
}
}
stage('Approval') {
steps {
script {
def userInput = input(id: 'Approve', message: 'Do you want to Approve?', parameters: [ [$class: 'BooleanParameterDefinition', defaultValue: false, description: 'Apply terraform', name: 'confirm'] ])
}
}
}
stage('TF Apply'){
steps{
sh '''
cd /data/projects/terraform/libvirt
terraform apply createkvm
'''
}
}
}
}
Figure-1 Jenkins Blue Ocean Flow
You may realize that domain name is centos7-test but the hostname is centos71. this is because I used a one of the template that I already created before. Address of the template defined in the source section of libvirt.tf file. In the next post, I will integrate it with the cloud-init which allows machine to setup at first boot. By doing that even machine customization will be done automatically.