Import ansible facts into servicenow cmdb - ansible

I'm trying to determine if it's possible to populate our servicenow CMDB with Ansible facts gathered from our Ansible Tower instance. I can find a lot of documentation on pulling inventory FROM CMDB, or for using Ansible to create incidents, but nothing on updating CI objects based on gathered facts. Is this possible?

check out this repo, https://github.com/michaelford85/ansible-servicenow-exercises
especially the Ansible Playbook-> snow-table-fields.yml
- name: Retrieve fields for a table {{ snow_table }}
snow_record:
state: present
table: "{{ snow_table }}"
data:
name: delete_this_record
username: "{{ SN_USERNAME }}"
password: "{{ SN_PASSWORD }}"
instance: "{{ SN_INSTANCE }}"
register: table_output
where {{snow_table}} can be something like cmdb_ci_linux_server

Related

How can I disable Cross region replication in oracle cloud using ansible playbook?

I came across a situation where when deleting an image with CRR enabled, you must first disable CRR before you can successfully delete the image. I cannot come with an ansible role or task to do the same.
So far I've come up with this:
- name: Get information of all boot volume attachments in a compartment and availability domain
oci_boot_volume_attachment_facts:
compartment_id: "{{ COMPARTMENT_ID }}"
availability_domain: "{{ Availability_Domain}}"
instance_id: "{{ matching_id_instance }}"
register: boot_volume_data
- name: Update boot_volume
oci_blockstorage_boot_volume:
# required
boot_volume_id: "{{ item.boot_volume_id }}"
boot_volume_replicas: []
- # required
availability_domain: "{{ Availability_Domain}}"
with_items: "{{ boot_volume_data.boot_volume_attachments }}"
when:
- item.instance_id == "{{ matching_id_instance }}"
'm unable to test it because there is difficulty in setting up connectivity from my ubuntu machine to oracle cloud as I don't have required permission to add public key in the oracle cloud for my user. For connectivity I followed this: https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm
I also came across a cli command to do so in oracle: https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/volumereplication.htm#To_disable_boot_replication
So I actually want this ansible tasks to be verified and rectify for errors if any? Or a particular way in ansible to disable CRR in oracle cloud
Error message I'm getting at "Update boot_volume" task:
"msg": "Updating resource failed with exception: Parameters are invalid or incorrectly formatted. Update volume requires at least one parameter to update."}
No need to paas the availability_domain for disabling CRR. You can refer below ansible task for your reference.
- name: Disable CRR for boot_volume
oci_blockstorage_boot_volume:
boot_volume_id: "{{ boot_volume_id }}"
boot_volume_replicas: []
register: result

Ansible import role run conditionally

I am writing a parent ansible role that runs another role though import_role. The idea that this sibling role (staticdev.pyenv) only runs when an argument pyenv_python_versions is passed, otherwise this is skipped.
According to the official documentation, I tried the following approach:
parent/tasks/main.yml
---
- name: Install pyenv
import_role:
name: staticdev.pyenv
vars:
pyenv_owner: "{{ ansible_env.USER }}"
pyenv_path: "{{ ansible_env.HOME }}/pyenv"
pyenv_global: "{{ pyenv_global }}"
pyenv_python_versions: "{{ pyenv_python_versions }}"
pyenv_virtualenvs: []
when: pyenv_python_versions
I am using currently ansible 4.1.0 (core 2.11.1), and when I test it on Debian 11 (image: cisagov/docker-debian11-ansible:latest) it executes the role anyway, even without any value for pyenv_python_versions. when is not being considered and I also tried with include_role. Complete logs can be found here.
Any idea?
UPDATE: changed condition when from to pyenv_python_versions as suggested by #lonetwin.
The problem was role import was replicating variables from the imported role (pyenv_global, pyenv_python_versions and pyenv_virtualenvs), in this case you solve it just by omitting imported role params (they will be overwritten if you create new defaults for them).
Solution:
---
- name: Install pyenv
import_role:
name: staticdev.pyenv
vars:
pyenv_owner: "{{ ansible_env.USER }}"
pyenv_path: "{{ ansible_env.HOME }}/pyenv"
when: pyenv_python_versions

Setting Ansible vars with set_fact results

Im running ansible 2.9.18 on RHEL7.
I am using hvac to retrieve usernames and passwords from a Hashicorp vault.
vars:
- creds: "{{ lookup('hashi_vault', 'secret=tst2/data/cisco token= url=http://10.80.23.81:8200') }}"
tasks:
- name: set Cisco creds
set_fact:
cisco: "{{ creds['data'] }}"
- name: Get nxos facts
nxos_command:
username: "{{ cisco['username'] }}"
password: "{{ cisco['password'] }}"
commands: show ver
timeout: 30
register: ver_out
- debug: msg="{{ ver_out.stdout }}"
But username and password are deprecated and I am trying to figure out how to pass the username, password as a "provider" variable. And this code doesn't work:
vars:
asa_api:
- creds: "{{ lookup('hashi_vault', 'secret=tst2/data/cisco token= url=http://10.80.23.81:8200') }}"
set_fact:
cisco: "{{ creds['data'] }}"
username: "{{ cisco['username'] }}"
password: "{{ cisco['password'] }}"
tasks:
- name: show run
asa_command:
commands: show run
provider: "{{ asa_api }}"
register: run
become: yes
tags:
- show_run
I cannot figure how syntax for making this work. I would greatly appreciate any help.
Thanks,
Steve
Disclaimer: This is a generic answer. I do not have any network device to test this fully so you might have to adapt a bit after reading the documentation
Your are taking this the wrong way. You don't need set_fact at all and both method you are trying to use (user/pass or provider dict) are actually deprecated. Ansible treats you network device as any host and will use the available user and password you have configured if they exist.
In the following example, I'm assuming your playbook only targets network devices and that the login/pass stored in your vault is the same on all devices.
- name: Untested network device connection configuration demo
hosts: my_network_device_group
vars:
# This indicates which connection plugin to use. Default is ssh
# An other possible value is httpapi. See above documentation link
ansible_connection: network_cli
vault_secret: tst2/data/cisco
vault_token: verysecret
vault_url: http://10.80.23.81:8200
vault_options: "secret={{ vault_secret }} token={{ vault_token }} url={{ vault_url }}"
creds: "{{ lookup('hashi_vault', vault_options).data }}"
# These are the user and pass used for connection.
ansible_user: "{{ creds.username }}"
ansible_password: "{{ creds.password }}"
tasks:
- name: Get nxos version
nxos_command:
commands: show ver
timeout: 30
register: ver_cmd
- name: show version
debug:
msg: "NXOS version on {{ inventory_hostname }} is {{ ver_cmd.stdout }}"
- name: An other task to play on targets
debug:
msg: "Task played on {{ inventory_hostname }}"
Rather than vars at play level, you can store this information in your inventory for all hosts or for a specific group, even for each host. See how to organise your group and host variables if you want to use that feature.

How to extract individual ips of ec2 instances launch using ansible when count is more than 1

I am launching aws ec2 2 instances using ansible using count:2 please check below playbook
- name: Create an EC2 instance
ec2:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ key }}"
key_name: "{{ keypair }}"
region: "{{ region }}"
group: "{{ security_group }}"
instance_type: "{{ instance_type }}"
image: "{{ image }}"
wait: yes
count: 2
vpc_subnet_id: "{{ vpc_subnet_id }}"
assign_public_ip: "{{ assign_public_ip }}"
register: ec2
- name: Add the newly created 1 EC2 instance(s) to webserver group
lineinfile: dest=inventory
insertafter='^\[webserver\]$'
line="{{ item.private_ip }} {{hoststring}}"
state=present
with_items: "{{ ec2.instances }}"
- name: add newly created remaining ec2 instance to db group
lineinfile: dest=inventory
insertafter='^\[db-server\]$'
line="{{ item.private_ip }} {{hoststring}}"
state=present
with_items: "{{ ec2.instances }}"
Here i want to add one ip to webserver host group & remaining to db host group but its not working with above playbook please help me to achieve same?
i dont wnt to use add_host here.
Since you are using AWS, have you considered using the aws_ec2 plugin for dynamic inventory?
As long as you are tagging your instances correctly, and you set up the yaml file, it would do what you want it.
Otherwise, your register: ec2 has two elements in it. The way (if it worked) you are looping through ec2 would add both to each group. You would need to add a when condition to match the something like the tag/subnet/cidr to know which server to add to which group.
One way to help see what the return is would be do print out the ec2 variable:
- debug: var=ec2

how to get metadata of aws instance created in ansible?

I'm creating an AWS instance and need to get the hostname, ip address in the same play. How to get the metadata. I tried 'ec2_instance_facts', 'ec2_metadata_facts', these are giving the host ansible playbook is running not the one just created.
I have tried using different modules '
- name: Debug
ec2_metadata_facts:
- debug: var=ansible_ec2_hostname
- debug: var=ansible_ec2_public_ipv4
- debug: var=ansible_ec2_public_hostname
- ec2_instance_facts:
region: "ap-southeast-2"
filters:
"tag:Name": A01NANISIM20
register: ec2_metadata
These snippets are not giving the details of the insatnce created, instead they give the details of the instance where playbook is run.
- ec2_instance_facts:
region: "ap-southeast-2"
filters:
"tag:Name": A01NANISIM04
register: ec2_metadata
- debug: msg="{{ ec2_metadata.instances }}"
- debug: msg="{{ ec2_metadata.instances[0].public_ip_address }}"
Finally I figured out myself. I didn't realize that ansible is an amalgamation of technologies. Just understood that the output is JSON data and all I need to form is the appropriate tags.
I've been using the ohai_ec2 fact run task based on the region or availability zone as ec2_instance_facts fails for me with a boto3 bug
using https://stackoverflow.com/a/51308298/4389552 let me see which facts I can use
e.g.
{{ ohai_ec2.region }}
# find the region
- name: get the region and availability zone
debug:
msg: "Region is {{ ohai_ec2.region }} and zone is {{ ohai_ec2.availability_zone }}"

Resources