Updating Ansible inventory file from playbook

Task: We need to deploy a new virtual machine using the cloud API, add this host to inventory file and continue to use it as part of the host group. In this article we will use Vultr cloud hosting. But it could be any other. First of all we need to define variables. Go to your Vultr account and get API key in your profile. Create variables file somewhere. This can be a host variable for example: host_vars/localhost.yml 

vultr_common:
  apikey: YOUR_API_KEY_HERE 
  sshkey_name: myansible
  inventory_file: /etc/ansible/hosts
# default variables for Vultr host VPS
  target_os: "Ubuntu 18.10 x64"
  target_plan: "2048 MB RAM,55 GB SSD,2.00 TB BW"
  target_region: "New Jersey"

Next. We need to add our

SSH key into cloud hosting and deploy new cloud VM. Here is playbook example. Change your public ssh_key file or create it using ssh-keygen. Define servername variable or pass it via command line using ansible-playbook -e servername=your.name.

# check global ssh keys on Vultr
- name: "Setup Deployment"
  hosts: localhost
  connection: local
  gather_facts: false
  tasks:

  - name: "Set vars"
    set_fact:
      target_servername={{ servername }}
      target_hostname={{ servername }}
      target_group=mail

  - name: "Ensure an SSH key is present"
    delegate_to: localhost
    vultr_ssh_key:
      api_key: "{{ vultr_common.apikey }}"
      name: "{{ vultr_common.sshkey_name }}"
      ssh_key: "{{ lookup('file', '/etc/ansible/id_ansible_rsa.pub') }}"

  # deploy server
  - name: "Ensure a cloud server exists"
    delegate_to: localhost
    vultr_server:
      api_key: "{{ vultr_common.apikey }}"
      name: "{{ target_servername }}" 
      hostname: "{{ target_hostname }}"
      tag: "auto-created"
      os: "{{ vultr_common.target_os }}"
      plan: "{{ vultr_common.target_plan }}"
      region: "{{ vultr_common.target_region }}"
      ssh_key: "{{ vultr_common.sshkey_name }}"
      state: present
    register: BUILD

See

vultr_server module for more details. You can also wait until the server starts:

# wait start
  - name: "Wait for server starting up." 
    wait_for:
      port: 22
      host: "{{ BUILD.vultr_server.v4_main_ip }}"
      delay: 10

Now we need to add our new server into

inventory file.

# Update Ansible inventory 
  - name: "Initialize SERVER list"
    set_fact: SERVER=[]
    when: (BUILD is defined)

  # pupulate 
  - name: "Populate SERVER list"
    set_fact:
      SERVER: "{{ SERVER }} + [ '{{ BUILD.vultr_server.name }},{{ BUILD.vultr_server.v4_main_ip }},{{ BUILD.vultr_server.v6_mai
n_ip }}' ]"
      target_ip: "{{ BUILD.vultr_server.v4_main_ip }}" 
      target_passwd: "{{ BUILD.vultr_server.default_password }}" 
    when: (SERVER is defined)

  # save to inventory file
  - name: "Update inventory file with SERVER list"
    delegate_to: localhost
    ini_file:
      dest: "{{ vultr_common.inventory_file }}"
      section: "{{ target_group }}"
      option: "{{ item.split(',')[0] }} ansible_host"
      value: "{{ item.split(',')[1] }}"
      no_extra_spaces: yes
      mode: 0666
      state: present
      backup: no
    with_items: "{{ SERVER }}"
    when: (SERVER is defined)

But we can’t use this

inventory file immediately! We need to refresh it:

# Refrefh inventory after deployment with new server name
- name: "Refresh inventory file"
  hosts: localhost
  connection: local
  gather_facts: false
  tasks:
    - meta: refresh_inventory

Done! NOTE: All previous steps was delegated to

localhost! But now we can execute tasks on remote hosts using updated inventory file:

# Deploy Mail server
- name: "Mail server deployment"
  hosts: "mail"
  tasks:
    ... here is your tasks on remote hosts

Good luck! Useful links:

https://www.renemoser.net/blog/2018/03/18/begin-vultr-with-ansible/ https://www.davideaves.com/2018/02/ansible-provisioning-vultr-servers/

Tagged with:

Leave a Reply

Your email address will not be published.