it-artikel:linux:how-to-achieve-easy-automatic-deployment-of-centos7-as-virtualbox-vm-in-a-dynamic-dns-lan-environment-with-an-ansible-playbook
no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


it-artikel:linux:how-to-achieve-easy-automatic-deployment-of-centos7-as-virtualbox-vm-in-a-dynamic-dns-lan-environment-with-an-ansible-playbook [2022-08-31 12:30] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== How to achieve easy automatic deployment of Centos7 as VirtualBox VM in a dynamic DNS LAN environment with an Ansible playbook ======
  
 +
 +<note important>**PLEASE NOTE:** This Page describes my solution to some "made up" or very specialized problem/environment! I dont know how usefull this is "as is" in the real world. However, to me it was primarily a training/learning project to get wet with ansible. But hopefuly this is still of use for someone else.</note>
 +
 +===== Scenario / Environment: =====
 +
 +  * Have an internet connected LAN with a local DHCP and "dynamic DNS" Server (bind).
 +  * DHCP Clients provide their FQDN to the DHCP Server and receive IPv4.
 +  * DHCP Server updates local DNS Server (bind) so that the client FQDN becomes resolvable network wide. (Domainname is .lan )
 +  * My VirtualBox virtualisation host is my Ansible host. It itself is a DHCP Client.
 +  * VirtualBox Server contains one predefined/preinstalled template VM 
 +    * Guest OS CentOS7 
 +    * Guest VM template name "centos7-template" 
 +    * Guest template FQDN "centos7-template.lan"
 +    * Guest Network: enabled, dhcp, bridged, sshd enabled
 +    * Guest contains "root" user with generic start-password
 +    * Guests "root" account contains a "authorized_key" (for ssh public key authentication) for use with Ansible or generic administrative SSH access
 +
 +
 +
 +===== Problem: =====
 +
 +To deploy another fresh Centos7 VM all i need to do is to "clone" the template VM, boot it and change its hostname, reboot it again. 
 +
 +Easy task, right ? But how to automate this with Ansible, so all i'll have to do is fire up just one command line and be flexible with the guests VM name and hostnames?
 +
 +
 +===== My Solution: =====
 +
 +  - Have Ansible installed on the VirtualBox Host (because, why not?)
 +  - Have this Ansible Playbook prepared: <file yaml deploy-centos7-from-template-on-virtualbox.yml>
 +---
 +- hosts: localhost
 +  connection: local
 +  gather_facts: no
 +  tasks:
 +  - name: clone template vm
 +    command: VBoxManage clonevm centos7-template --mode all --name {{ newVmName }} --register
 +  - name: temp.start clone vm
 +    command: VBoxManage startvm {{ newVmName }} --type headless
 +  - name: add temp host to inventory (ram)
 +    add_host:
 +      hostname: "{{ newVmName }}.lan"
 +  - name: flush local dns cache
 +    command: systemd-resolve --flush-caches
 +  - name: wait for new vm to register/update dns hostname and come available
 +    shell: /ssd/VirtualBox\ VMs/wait-for-hostname-resolvable.sh centos7-template.lan 60
 +  - name: wait for ssh@vm to be accessable
 +    wait_for:
 +      timeout: 90
 +      sleep: 2
 +      host: "centos7-template.lan"
 +      port: 22
 +
 +- hosts: centos7-template.lan
 +  gather_facts: no
 +  remote_user: root
 +  tasks:
 +  - name: check connection again
 +    wait_for_connection:
 +      timeout: 60
 +  - name: change vms hostname
 +    command: hostnamectl set-hostname "{{ newVmName }}.lan"
 +  - name: reboot vm
 +    reboot:
 +
 +- hosts: localhost
 +  gather_facts: no
 +  connection: local
 +  tasks:
 +  - name: flush local dns cache
 +    command: systemd-resolve --flush-caches
 +  - name: wait for new vm to register/update dns hostname and come available
 +    shell: /ssd/VirtualBox\ VMs/wait-for-hostname-resolvable.sh "{{ newVmName }}.lan" 60
 +  - name: wait for ssh@vm to be accessable
 +    wait_for:
 +      timeout: 90
 +      sleep: 2
 +      host: "{{ newVmName }}.lan"
 +      port: 22
 +
 +- hosts: "{{ newVmName }}.lan"
 +  gather_facts: no
 +  remote_user: root
 +  tasks:
 +  - name: show fqdn of new vm
 +    command: hostname -f
 +
 +</file>
 +  - Also have this little Linux shell script with it, so that Ansible has some way to check when a fqdn gets available/resolvable in my dynamic DNS environment, but still have some way to check for a timeout: <file bash wait-for-hostname-resolvable.sh>
 +#!/bin/bash
 +
 +targetHostname="$1"
 +timeOut="$2"
 +
 +if test -z "$targetHostname" ; then 
 + echo "ERROR: No hostname given."
 + echo "Usage: $0 fqdn timeOutSeconds"
 + exit -1
 +fi
 +
 +if test -z "$timeOut" ; then 
 + timeOut=60
 +fi
 +
 +for seconds in $(seq $timeOut -1 1) ; do
 + systemd-resolve --flush-caches
 + if host "$targetHostname" 1>/dev/null 2>&1 ; then
 + if ping -c1 -w1 "$targetHostname" 1>/dev/null 2>&1 ; then
 + break
 + else
 + #echo "${seconds}s left"
 + continue
 + fi
 + else
 + #echo "${seconds}s left"
 + sleep 1
 + fi
 +done
 +
 +if test $seconds -gt 1 ; then
 + true
 +else
 + false
 +fi
 +
 +</file>
 +    * **NOTE:** Ansible comes already with modules to check for hosts and connections (like **wait_for** and **wait_for_connection** ). However, i was not successfull with any of those, because in my special network environment hostnames are not always resolvable PLUS i had massive problems with "hostname caching" of the systemd service. So i needed something that takes care of all this, which Ansibles modules seem not to do at the moment. The modules that come with Ansible seem to always asume the hostname is resolvable. If not resolvable the modules fail right on the spot.   
 +  - Have some Ansible "inventory" (hosts) file handy: <file ascii ansibleHosts>
 +[templatevms]
 +centos7-template.lan
 +
 +#[admin]
 +#centos7admin.lan
 +
 +#[cluster]
 +#centos7node1.lan
 +#centos7node2.lan
 +#centos7node3.lan
 +</file>
 +  - Run the Ansible playbook without SSH key checking to prevent answering security questions and provide the VMs new name on the command line: <code>
 +ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -v -i ansibleHosts -e newVmName=newVMsHostname deploy-centos7-from-template-on-virtualbox.yml
 +</code>
 +  - This will clone the template vm (resulting in new MAC and VBox media UUIDs), start the new VM, ssh into the new VM to change its hostname and reboots it. After new VM is back up it checks connection and hostname by a "hostname -f"
 +
 +<note important>About being "idempotent": Well.... this playbook isnt! Can be run ONLY ONCE for a specific VM name. After that choose a new VM name or delete the existing VM first.</note>
 +
 +
 +
 +
 +{{tag>linux centos 7 centos7 dynamic dns ddny dyndns bind dhcpd ansible playbook deploy vm virtualbox network local lan}}
it-artikel/linux/how-to-achieve-easy-automatic-deployment-of-centos7-as-virtualbox-vm-in-a-dynamic-dns-lan-environment-with-an-ansible-playbook.txt · Last modified: 2022-08-31 12:30 by 127.0.0.1