When working with an Ansible dynamic inventory, you may want to update it from your playbook on the fly. For instance, you may want to create a server and then install an application on it without calling a second playbook or developing specific code to create a runtime group (e.g. “add_host” module). Or you may want to update the inventory on the fly without having to wait for an asynchronous mechanism to be triggered. This all this project is about: providing you a simple, fully encrypted, interactive dynamic inventory made to measure for your environment.
Back-end setup
1) Install the database software:
This will serve as a data storage for your Ansible inventory data (More details here)
wget https://siodb.io/packages/InstallSiodb.sh chmod u+x ./InstallSiodb.sh sudo ./InstallSiodb.sh
2) Get the last version of the dynamic inventory:
git clone https://github.com/siodb/ansible-dynamic-inventory.git cd ansible-dynamic-inventory
3) Create the inventory data model and the database user:
sudo -i -u siodb siocli --user root < sio_inv_data_model.sql sudo -i -u siodb siocli --user root < sio_inv_user.sql
4) Create your groups, groupvars, hosts and hostvars:
On this step, you can add your groups, groupvars, hosts and hostvars by inserting them into the correct table. Also, you can link them together using the columns:
- groups_variables.group_id: to link variables to a group from the group table.
- hosts.group_id: to link a group from the group table.
- hosts_variables.host_id: to link variables to a host from the hosts table.
Here is a overview of the data model used for this inventory (red number indicating the order in which to insert data):
So, first connect to the database freshly installed from step 1):
sudo -i -u siodb siocli --user root
Then insert your data. For instance:
use database sioinv ;
insert into groups
values
( 'production' ),
( 'test' ),
( 'development' )
;
insert into groups_variables
values
( 1, 'domain_name', 'company.com' ),
( 2, 'environment_name', 'production' ),
( 2, 'subnet', '10.10.0.0/16' ),
( 3, 'environment_name', 'test' ),
( 3, 'subnet', '10.20.0.0/16' ),
( 4, 'environment_name', 'development' ),
( 4, 'subnet', '10.30.0.0/16' )
;
insert into hosts
values
( 2, 'server-01', CURRENT_TIMESTAMP ),
( 3, 'server-02', CURRENT_TIMESTAMP ),
( 4, 'server-03', CURRENT_TIMESTAMP )
;
insert into hosts_variables
values
( 1, 'public_ip', '0.1.2.3' ),
( 1, 'application', 'app01' ),
( 2, 'public_ip', '0.1.2.4' ),
( 2, 'application', 'app02' ),
( 3, 'public_ip', '0.1.2.4' ),
( 3, 'application', 'app02' )
;
Configure the inventory
You must tell the inventory script where to lookup for its data. That is done configuring the file sio_inv.ini:
[sio_inv] siodb_rest_ip = localhost siodb_rest_port = 50443 siodb_rest_user = sioinv siodb_rest_token = [token-generated-from-script-sio_inv_user.sql] siodb_rest_tls_verify_certificate = no
Validate the inventory
Use the command ansible-inventory to validate your inventory. For instance:
$ ansible-inventory -i ./sio_inv.py --graph --vars
@all:
|--@development:
| |--server-03
| | |--{domain_name = company.com}
| | |--{environment_name = development}
| | |--{subnet = 10.30.0.0/16}
| |--{environment_name = development}
| |--{subnet = 10.30.0.0/16}
|--@production:
| |--hypervisor-01
| | |--{domain_name = company.com}
| | |--{environment_name = production}
| | |--{subnet = 10.10.0.0/16}
| |--hypervisor-02
| | |--{domain_name = company.com}
| | |--{environment_name = production}
| | |--{subnet = 10.10.0.0/16}
| |--server-01
| | |--{application = app01}
| | |--{domain_name = company.com}
| | |--{environment_name = production}
| | |--{public_ip = 0.1.2.3}
| | |--{subnet = 10.10.0.0/16}
| |--server-04
| | |--{domain_name = company.com}
| | |--{environment_name = production}
| | |--{subnet = 10.10.0.0/16}
| |--{environment_name = production}
| |--{subnet = 10.10.0.0/16}
|--@test:
| |--server-02
| | |--{application = app02}
| | |--{domain_name = company.com}
| | |--{environment_name = test}
| | |--{public_ip = 0.1.2.4}
| | |--{subnet = 10.20.0.0/16}
| |--server-05
| | |--{domain_name = company.com}
| | |--{environment_name = test}
| | |--{subnet = 10.20.0.0/16}
| |--{environment_name = test}
| |--{subnet = 10.20.0.0/16}
|--@ungrouped:
|--{domain_name = company.com}
Example of playbook
Here is an example of how to interactively deal with the dynamic inventory while the playbook is running
(Set the variable {{ sioinv_user_token }} where it makes sense for you and store the token in Ansible Vault):
---
- name: Full Stack Service creation
hosts: hypervisor-01
tasks:
- name: Create machine
shell: >
echo "Module or command to create a new Virtual Machine {{ vm_name }}"
- name: Update the custom dynamic inventory on the fly with the just-created vm
uri:
url: https://localhost:50443/databases/sioinv/tables/hosts/rows
validate_certs: false
user: sioinv
password: "{{ sioinv_user_token }}"
method: POST
body: >
[{
"name": "{{ vm_name }}"
}]
force_basic_auth: yes
status_code: 201
body_format: json
register: r_vm_post
- name: Add hostvars on the fly to the just-created vm
uri:
url: https://localhost:50443/databases/sioinv/tables/hosts_variables/rows
validate_certs: false
user: sioinv
password: "{{ sioinv_user_token }}"
method: POST
body: >
[{
"host_id": {{ r_vm_post.json.trids[0] }},
"name": "ip_address",
"value": "10.10.0.0"
}]
force_basic_auth: yes
status_code: 201
body_format: json
- name: Refresh the inventory in current run to include the new VM and its variables before moving to the next play
meta: refresh_inventory
- name: Full Stack Service creation
hosts: "{{ vm_name }}"
tasks:
- name: Create the new database on the new VM
shell: >
echo "Module or command to create a new database on {{ vm_name }}"
Last words before you go
The inventory is the foundation of your Ansible strategy. It must be dynamic as possible and avoiding complexity to ensure smooth maintenance in the future. Modifying the inventory may lead you to change all your roles and playbooks and is something you may want to avoid. With this simple inventory describe here, you’ll have a strong foundation for your Ansible automation.
I hope this helps you, and please do contact us or comment below if you need more details.
