Первоначально опубликовано на blog.ruanbekker.com
В этом посте мы будем использовать Врождений LibVirt С террафом для развертывания виртуальной машины KVM на удаленном хосте KVM с помощью SSH и используйте Anbible для развертывания Nginx на нашем виртуальной машине.
В моем Предыдущий пост Я продемонстрировал, как я создал свой хост KVM и создал специальный пользователь для террафора для аутентификации на нашем хосте KVM для обеспечения VMS.
Как только у вас установлен KVM, и ваш доступ SSH отсортирован, мы можем начать с установки наших зависимостей.
Установите наши зависимости
Сначала мы установим террафору:
$ wget https://releases.hashicorp.com/terraform/0.13.3/terraform_0.13.3_linux_amd64.zip $ unzip terraform_0.13.3_linux_amd64.zip $ sudo mv terraform /usr/local/bin/terraform
Тогда мы устанавливаем Anbible:
$ virtualenv -p python3 .venv $ source .venv/bin/activate $ pip install ansible
Теперь, чтобы использовать Provisioner Libvirt, нам нужно установить его, где мы будем запускать наш развертывание Terraform:
$ cd /tmp/ $ mkdir -p ~/.local/share/terraform/plugins/registry.terraform.io/dmacvicar/libvirt/0.6.2/linux_amd64 $ wget https://github.com/dmacvicar/terraform-provider-libvirt/releases/download/v0.6.2/terraform-provider-libvirt-0.6.2+git.1585292411.8cbe9ad0.Ubuntu_18.04.amd64.tar.gz $ tar -xvf terraform-provider-libvirt-0.6.2+git.1585292411.8cbe9ad0.Ubuntu_18.04.amd64.tar.gz $ mv ./terraform-provider-libvirt ~/.local/share/terraform/plugins/registry.terraform.io/dmacvicar/libvirt/0.6.2/linux_amd64/
Наша SSH Config для нашего Host KVM в ~/.ssh/config :
Host *
Port 22
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Host ams-kvm-remote-host
HostName ams-kvm.mydomain.com
User deploys
IdentityFile ~/.ssh/deploys.pem
Террафор все вещи
Создайте каталог Workspace для нашей демонстрации:
$ mkdir -p ~/workspace/terraform-kvm-example/ $ cd ~/workspace/terraform-kvm-example/
Сначала давайте создадим наш Proyers.tf :
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.2"
}
}
}
Тогда наше variables.tf Просто дважды проверьте, где вам нужно изменить значения, чтобы набрать вашу среду:
variable "libvirt_disk_path" {
description = "path for libvirt pool"
default = "/opt/kvm/pool1"
}
variable "ubuntu_18_img_url" {
description = "ubuntu 18.04 image"
default = "http://cloud-images.ubuntu.com/releases/bionic/release-20191008/ubuntu-18.04-server-cloudimg-amd64.img"
}
variable "vm_hostname" {
description = "vm hostname"
default = "terraform-kvm-ansible"
}
variable "ssh_username" {
description = "the ssh user to use"
default = "ubuntu"
}
variable "ssh_private_key" {
description = "the private key to use"
default = "~/.ssh/id_rsa"
}
Создать main.tf , Вы заметите, что мы используем SSH для подключения к KVM, и потому, что личный диапазон наших виртуальных виртов не портируется через Интернет, я использую хост-бастион, чтобы связаться с ними.
Хост Bastion (SSH Config из раздела Pre-требования) является хостом KVM, и вы увидите, что Anisible также использует этот хост в качестве полевого поля, чтобы добраться до VM. Я также использую облако-init для загрузки узла с SSH и т. Д.
Причина, по которой я использую Remote-Exec до того, как непредвиденное развертывание, заключается в том, чтобы мы могли установить команду через SSH, прежде чем Anisible Starts.
provider "libvirt" {
uri = "qemu+ssh://deploys@ams-kvm-remote-host/system"
}
resource "libvirt_pool" "ubuntu" {
name = "ubuntu"
type = "dir"
path = var.libvirt_disk_path
}
resource "libvirt_volume" "ubuntu-qcow2" {
name = "ubuntu-qcow2"
pool = libvirt_pool.ubuntu.name
source = var.ubuntu_18_img_url
format = "qcow2"
}
data "template_file" "user_data" {
template = file("${path.module}/config/cloud_init.yml")
}
data "template_file" "network_config" {
template = file("${path.module}/config/network_config.yml")
}
resource "libvirt_cloudinit_disk" "commoninit" {
name = "commoninit.iso"
user_data = data.template_file.user_data.rendered
network_config = data.template_file.network_config.rendered
pool = libvirt_pool.ubuntu.name
}
resource "libvirt_domain" "domain-ubuntu" {
name = var.vm_hostname
memory = "512"
vcpu = 1
cloudinit = libvirt_cloudinit_disk.commoninit.id
network_interface {
network_name = "default"
wait_for_lease = true
hostname = var.vm_hostname
}
console {
type = "pty"
target_port = "0"
target_type = "serial"
}
console {
type = "pty"
target_type = "virtio"
target_port = "1"
}
disk {
volume_id = libvirt_volume.ubuntu-qcow2.id
}
graphics {
type = "spice"
listen_type = "address"
autoport = true
}
provisioner "remote-exec" {
inline = [
"echo 'Hello World'"
]
connection {
type = "ssh"
user = var.ssh_username
host = libvirt_domain.domain-ubuntu.network_interface[0].addresses[0]
private_key = file(var.ssh_private_key)
bastion_host = "ams-kvm-remote-host"
bastion_user = "deploys"
bastion_private_key = file("~/.ssh/deploys.pem")
timeout = "2m"
}
}
provisioner "local-exec" {
command = < nginx.ini
echo "${libvirt_domain.domain-ubuntu.network_interface[0].addresses[0]}" >> nginx.ini
echo "[nginx:vars]" >> nginx.ini
echo "ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ProxyCommand=\"ssh -W %h:%p -q ams-kvm-remote-host\"'" >> nginx.ini
ansible-playbook -u ${var.ssh_username} --private-key ${var.ssh_private_key} -i nginx.ini ansible/playbook.yml
EOT
}
}
Как я уже упоминал, я использую Cloud-init, так что позволяет настроить сетевую конфигурацию и облако init под config/ . каталог:
$ mkdir config
И наше config/cloud_init.yml Просто убедитесь, что вы настраиваете публичную клавишу SSH для SSH-доступа в конфиге:
#cloud-config
# vim: syntax=yaml
# examples:
# https://cloudinit.readthedocs.io/en/latest/topics/examples.html
bootcmd:
- echo 192.168.0.1 gw.homedns.xyz >> /etc/hosts
runcmd:
- [ ls, -l, / ]
- [ sh, -xc, "echo $(date) ': hello world!'" ]
ssh_pwauth: true
disable_root: false
chpasswd:
list: |
root:password
expire: false
users:
- name: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, admin
home: /home/ubuntu
shell: /bin/bash
lock_passwd: false
ssh-authorized-keys:
- ssh-rsa AAAA ...your-public-ssh-key-goes-here... user@host
final_message: "The system is finally up, after $UPTIME seconds"
И наша сетевая конфиг, в config/network_config.yml :
version: 2
ethernets:
ens3:
dhcp4: true
Теперь мы создадим нашу Anisible Playbook, чтобы развернуть Nginx на наш VM, создать аналимный каталог:
$ mkdir ansible
Тогда создайте Ansible/Playbook.yml :
---
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_module.html#examples
- hosts: nginx
become: yes
become_user: root
become_method: sudo
tasks:
- name: Install nginx
apt:
name: nginx
state: latest
update_cache: yes
- name: Enable service nginx and ensure it is not masked
systemd:
name: nginx
enabled: yes
masked: no
- name: ensure nginx is started
systemd:
state: started
name: nginx
Это необязательно, но я использую Ansible.cfg Файл для определения моих по умолчанию:
[defaults] host_key_checking = False ansible_port = 22 ansible_user = ubuntu ansible_ssh_private_key_file = ~/.ssh/id_rsa ansible_python_interpreter = /usr/bin/python3
И, наконец, наше OPTIONS.TF которые будут отображать наш IP-адрес нашего VM:
output "ip" {
value = libvirt_domain.domain-ubuntu.network_interface[0].addresses[0]
}
output "url" {
value = "http://${libvirt_domain.domain-ubuntu.network_interface[0].addresses[0]}"
}
Развернуть наше развертывание террафора
Пришло время развертывать экземпляр KVM с террафом и развертывать NGINX к нашей виртуальную машину с помощью Anbible, используя Previsioner Local-Exec.
Инициализируйте террафору для скачивания всех плагинов:
$ terraform init Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/template... - Finding dmacvicar/libvirt versions matching "0.6.2"... - Installing hashicorp/template v2.1.2... - Installed hashicorp/template v2.1.2 (signed by HashiCorp) - Installing dmacvicar/libvirt v0.6.2... - Installed dmacvicar/libvirt v0.6.2 (unauthenticated) The following providers do not have any version constraints in configuration, so the latest version was installed. To prevent automatic upgrades to new major versions that may contain breaking changes, we recommend adding version constraints in a required_providers block in your configuration, with the constraint strings suggested below. * hashicorp/template: version = "~> 2.1.2" Terraform has been successfully initialized!
Запустите план, чтобы увидеть, что будет сделано:
$ terraform plan ... Plan: 4 to add, 0 to change, 0 to destroy. Changes to Outputs: + ip = (known after apply) + url = (known after apply) ...
И запустите применить, чтобы запустить наше развертывание:
$ terraform apply -auto-approve ... libvirt_domain.domain-ubuntu (local-exec): PLAY RECAP ********************************************************************* libvirt_domain.domain-ubuntu (local-exec): 192.168.122.213 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 libvirt_domain.domain-ubuntu: Creation complete after 2m24s [id=c96def6e-0361-441c-9e1f-5ba5f3fa5aec] Apply complete! Resources: 4 added, 0 changed, 0 destroyed. Outputs: ip = 192.168.122.213 url = http://192.168.122.213
Вы всегда можете получить вывод потом с использованием Show или вывода:
$ terraform show -json | jq -r '.values.outputs.ip.value' 192.168.122.213 $ terraform output -json ip | jq -r '.' 192.168.122.213
Проверьте нашу виртуальную машину
Перейдите на хост KVM и проверьте nginx:
$ curl -I http://192.168.122.213 HTTP/1.1 200 OK Server: nginx/1.14.0 (Ubuntu) Date: Thu, 08 Oct 2020 00:37:43 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Thu, 08 Oct 2020 00:33:04 GMT Connection: keep-alive ETag: "5f7e5e40-264" Accept-Ranges: bytes
через гипю
Спасибо
Спасибо за чтение, проверьте мой Сайт или следовать за мной в @Ruanbekker в Твиттере.
Оригинал: «https://dev.to/ruanbekker/terraform-with-kvm-2d9e»