Livestrong Lance
Livestrong Lance

Reputation: 13

Ansible read variables from bash

I created 2 playbooks:

  1. deploy VM(centos8) into ESX
  2. join VM to AD

Inside of them are plenty variables which are useful only for one specific VM (beside info about ESX)

---
- name: create vm from template on ESX
  hosts: localhost
  gather_facts: no
  become: yes

  tasks:

  - name: clone the template
    vmware_guest:
      hostname:  "IP.."
      username: "user"
      password: "password"
      validate_certs: false
      name: ll-ansible
      template: ll
      datacenter: "LAB KE"
      folder: "OIR"
      resource_pool: "pool"
      cluster: "PROD cluster"
      networks:
        - name: IS-VLAN1102
          device_type: vmxnet3
          vlan: IS-VLAN1102
          ip: ip.ip.ip.ip
          netmask: 255.255.255.0
          gateway: gw.gw.gw.gw
      customization:
          hostname: ll-ansible
          timezone: timezone
          domain: domain
          dns_servers:
            - ip.ip.ip.ip
            - ip.ip.ip.ip
      disk:
        - size: 60gb
          type: default
          datastore: Dell-OIR
        - size: 10gb
          type: default
          datastore: Dell-OIR
      hardware:
        memory_mb: 4096
        num_cpus: 4
        num_cpu_cores_per_socket: 2
        boot-firmware: efi

      state: poweredon
      wait_for_ip_address: yes
    register: vm
  - debug: msg "{{ vm }}"

My question is:

Is there a way to make a script which will read all necessary variables for deploying VM from command line and fill fields in playbook and then run playbook.

Or if is it possible make it only within ansible possibilities.

Upvotes: 1

Views: 3699

Answers (1)

Yasen
Yasen

Reputation: 4474

There are many ways to send variables to playbook.

Let's start from these 3 most popular options:

  • env vars
  • ansible-playbook CLI arguments
  • var files

See also all 22 options: Understanding variable precedence

Option 1: use lookup('env') in the playbook

Just use "{{ lookup('env', 'ENV_VAR_NAME')}}"

E.g., for your case:

---
- name: create vm from template on ESX
  hosts: localhost
  gather_facts: no
  become: yes

  tasks:

  - name: clone the template
    vmware_guest:
      hostname: "{{ lookup('env', 'IP_ADDRESS')}}"

Option 2: pass var through CLI args

You may pass Env var value using --extra-vars CLI argument

For your case:

playbook.yml

...
  - name: clone the template
    vmware_guest:
      hostname: "{{ ip_address }}"
      user: "{{ user }}"

usage:

 ansible-playbook playbook.yml --extra-vars="user={{ lookup('env', 'USER') }}, ip_address='10.10.10.10'" 

Option 3: use vars_files in the playbook

For your case:

playbook.yml:

---
- name: create vm from template on ESX
  hosts: localhost
  gather_facts: no
  become: yes
  vars_files:
    - "vars/vars.yml"

  tasks:

  - name: clone the template
    vmware_guest:
      hostname: "{{ hostname }}"

vars/vars.yml:

---
hostname: "host.example.com"

Let's combine them all:

Suppose you have two different environments:

  • staging for staging environment
  • prod for productive environment

Then we create two different vars files:

vars/staging.yml

---
hostname: "staging.domain.com"

vars/prod.yml

---
hostname: "prod.domain.com"

playbook.yml:

---
- name: create vm from template on ESX
 y6uu hosts: localhost
  gather_facts: no
  become: yes
  vars_files:
    - "vars/{{ env }}.yml"

  tasks:

  - name: clone the template
    vmware_guest:
      hostname: "{{ hostname }}"

Usage

  • run playbook with staging vars: ansible-playbook playbook.yml --extra-vars=staging

  • run playbook with prod vars: ansible-playbook playbook.yml --extra-vars=prod

Upvotes: 1

Related Questions