ビビリフクロウの足跡

とあるインフラSEの勉強&備忘ブログ

oVirt環境のVMを管理するplaybookをさらす

久しぶりの投稿ですが、生きてますw 投稿しよう!と思いきれる真新しい発見なく過ごしていたので、放置気味でした…(汗

けど、細々としたことでもこまめにナレッジとして残しておいたほうが後々得すると思うので、少し更新頻度を上げたいと思います。 ということで今日はこんなAnsibleのplaybookを書いてみました、という話でも。

自宅ではoVirtという仮想化基盤でサーバ運用や技術検証を行っています。無償でライブマイグレーションの機能が使えたり、GlusterFSとのインテグレーションによってハイパーコンバージドインフラを構築できたりなど、個人利用には至れり尽くせりの機能を持っています。低予算かつ本格的な仮想化基盤を探している方は是非チェックしてみてください。

ところでこのoVirt、VMwareのようにAPIを叩くことも出来るようになっていて、API経由で仮想リソースを管理できるようになっています。つまり疑似プライベートクラウドのように使うことも可能なのです。そろそろお家環境もInfrastructure as Codeを適用しようと考えていたので、このAPIをバリバリ活用して自動化しようと思い立ちました。

それでインフラ構成をコード化するなら、最近ホットであり、仕事でも使っているAnsibleを使ってやろうということでplaybookを書いてみました。oVirtモジュールもVer 2.3で大量に導入されましたしね。数少ないoVirtユーザの参考になれば幸いです。

初めからconnection: localとせず、delegate_to: localhostを利用しているところがミソで、こうすることでVMを並列に作成・削除することができるようになります。また、host_varsのファイルもlocalhost.yamlに全VMのパラメータを格納することなく、<inventory_hostname>.yamlに各VMのパラメータを格納することができるようになり、保守性が高くなります!

◆manage-vm.yaml

---
- name: manage vm
  hosts: all
  gather_facts: no
  vars_files:
  - manage-vm_vars.yaml
  tasks:
  - name: login to ovirt
    ovirt_auth:
      url: https://<oVirt EngineのFQDN>/ovirt-engine/api
      username: admin@internal
      insecure: yes
      password: "{{ ovirt_admin_pass }}"
    connection: local
    delegate_to: localhost

  - block:
    - name: create disks
      ovirt_disk:
        auth: "{{ ovirt_auth }}"
        name: "{{ item.name }}"
        size: "{{ item.size }}"
        format: "{{ item.format }}"
        interface: "{{ item.interface }}"
        storage_domain: "{{ item.storage_domain }}"
        state: present
      with_items: "{{ ovirt_vm.persistent_disks | default([]) }}"

    - name: create vm
      ovirt_vms:
        auth: "{{ ovirt_auth }}"
        name: "{{ ovirt_vm.name }}"
        cluster: "{{ ovirt_cluster }}"
        template: "{{ ovirt_vm.template }}"
        memory: "{{ ovirt_vm.memory }}"
        cpu_cores: "{{ ovirt_vm.cpu_cores }}"
        nics: "{{ ovirt_vm.nics }}"
        cloud_init:
          host_name: "{{ ovirt_vm.hostname }}"
          dns_servers: "{{ ovirt_vm.dns_servers }}"
          user_name: "{{ ansible_user }}"
          root_password: "{{ ansible_ssh_pass | default('') }}"
          authorized_ssh_keys: "{{ ovirt_vm.authorized_keys | default('') }}"
          custom_script: "{{ ovirt_vm.custom_script | default('') }}"
        cloud_init_nics: "{{ ovirt_vm.nics }}"
        state: running

    - name: attach disks
      ovirt_disk:
        auth: "{{ ovirt_auth }}"
        name: "{{ item.name }}"
        vm_name: "{{ ovirt_vm.name }}"
        interface: "{{ item.interface }}"
        state: attached
      with_items: "{{ ovirt_vm.persistent_disks | default([]) }}"

    - name: wait for vm to be up
      wait_for:
        host: "{{ ansible_host }}"
        port: "{{ ansible_port }}"
        state: started
    when: ovirt_vm.state == "running"
    connection: local
    delegate_to: localhost

  - block:
    - name: detach disks
      ovirt_disk:
        auth: "{{ ovirt_auth }}"
        name: "{{ item.name }}"
        vm_name: "{{ ovirt_vm.name }}"
        state: detached
      when: item.protect_from_deletion | default(true)
      with_items: "{{ ovirt_vm.persistent_disks | default([]) }}"

    - name: remove vm
      ovirt_vms:
        auth: "{{ ovirt_auth }}"
        name: "{{ ovirt_vm.name }}"
        cluster: "{{ ovirt_cluster }}"
        state: absent
    when: ovirt_vm.state == "absent"
    connection: local
    delegate_to: localhost

◆manage-vm_vars.yaml

---
ovirt_admin_pass: <adminユーザのパスワード>
ovirt_cluster: <対象クラスタ名>

◆host_vars/<inventory_hostname>.yaml (サンプル)

---
ansible_host: <対象サーバのIP>
ansible_user: root
ansible_ssh_pass: <rootユーザのパスワード>
ansible_port: 22
ovirt_vm:
  name: <対象サーバの名前>
  template: <利用するテンプレート名(要cloud-init導入)>
  memory: 4GiB
  cpu_cores: 2
  hostname: <対象サーバのFQDN>
  dns_servers: <参照するDNSサーバ(カンマ区切り)>
  nics:
  - nic_boot_protocol: static
    nic_ip_address: "{{ ansible_host }}"
    nic_netmask: <サブネットマスク>
    nic_gateway: <デフォルトゲートウェイ>
    nic_name: eth0
    nic_on_boot: yes
    name: nic1
    interface: virtio
    profile_name : ovirtmgmt
  persistent_disks:
  - name: <追加するディスクの名前>
    size: 30GiB
    format: cow
    interface: virtio
    storage_domain: <ディスクの所属するストレージドメイン>
    protect_from_deletion: <削除時にこのディスクを保護するか(Boolean)>
  state: running