The Zurich release has arrived! Interested in new features and functionalities? Click here for more

Ajay81
Kilo Contributor

 

Connecting to AWS

  1. Login to AWS Server (AWS CLI should be installed)

  2. From CMD run the below commands to download the JSON

    aws configure – to set the default values for region,output format,access key and secret access key

    AWS Access Key ID [None]:

    AWS Secret Access Key [None]:

    Default region name [None]: us-west-2

    Default output format [None]: json

     

    Select the region and run the next commands to download the data.

    aws ec2 describe-regions - to get Region

    aws ec2 describe-availability-zones – to get availability zones

    aws ec2 describe-vpcs- to get VPCs

    aws ec2 describe-subnets – to get Subnet

    aws ec2 describe-network-interfaces – to get Network Interfaces

    aws ec2 describe-volumes – to get Storage Volumes

    aws ec2 describe-instances- to get VM Instances

    cmdb_ci_compute_template table

    for each command add ' > filename.json ' to store in JSON file.

     

    In ServiceNow

  3. In ServiceNow load the above JSON script (can be written in Scheduled Job)

  4. Copy the content from JSON file and paste it as value for “jsn” variable in script.

  5. Run the Jobs by clicking 'Execute Now' or copy the script and run it in Scripts – background.

     

  6. Scheduled Jobs for loading data:

    Example:

    cmdbVmInstance -for VM Instance. Use output of 'aws ec2 describe-instances'

     

  7. Scheduled Jobs for adding the relations between CI

    Relationship table- cmdb_rel_ci

    Example:

    cmdbRelStorageVolume_VmInstanceType - Use output of 'aws ec2 describe-instances'

     

To load the CI:

Example: to load all the VM instances to 'cmdb_ci_vm_instance' table

 

var jsn={

// paste the JSON here.

}

 

var len=jsn.Reservations.length;;

var arr=[];

var name;

for(var i=0;i<len;i++)

{

var instance =jsn.Reservations[i].Instances[0];

arr.push(instance.InstanceId); // for the delete operation in later part

 

// state values are different in ServiceNow from AWS .So change it to corresponding state

var instanceState='';

if(instance.State.Name=='running')

instanceState='on';

 

if(instance.State.Name=='stopped')

instanceState='off';

 

 

// if the VM instance exists in ServiceNow CMDB, then update it if any changes are there in JSON.

 

var cmdbUpdate=new GlideRecord('cmdb_ci_vm_instance');

cmdbUpdate.addQuery('object_id',instance.InstanceId);

cmdbUpdate.query();

if(cmdbUpdate.next())

{

if(instance.PublicIpAddress)

{

 

if(cmdbUpdate.state!=instanceState||cmdbUpdate.ip_address!=instance.PublicIpAddress)

{

cmdbUpdate.state=instanceState;

cmdbUpdate.ip_address=instance.PublicIpAddress;

cmdbUpdate.update();

}

}

}

 

// else. If the VM Instance is not in CMDB, insert instance to CMDB.

 

else{

var cmdbInsert=new GlideRecord('cmdb_ci_vm_instance');

cmdbInsert.initialize();

 

// To get the name of the Instance- name is inside an array in JSON, so loop it to get the value

 

for(var j=0;j<instance.Tags.length;j++)

{

If(instance.Tags[j].Key=='Name')

name=instance.Tags[j].Value;

}

cmdbInsert.name=name;

cmdbInsert.state=instanceState;

cmdbInsert.vm_inst_id=instance.InstanceId;

cmdbInsert.object_id=instance.InstanceId;

cmdbInsert.ip_address=instance.PublicIpAddress;

cmdbInsert.insert();

}

}

 

To delete Instances which are not in the JSON but present in the ServiceNow CMDB:

Since the JSON is for a particular region, we need to query the Instances of that region.

 

Since the region information is not present in JSON, take the zone and slice the last character to get the region name.

var arrayUtil = new ArrayUtil();

var zone=jsn.Reservations[0].Instances[0].Placement.AvailabilityZone;

var dataCenter=zone.slice(0, -1);

 

// fetch all VM instances from ' cmdb_rel_ci' table with exact relationship type(for the region and VM instance) and parent class 'cmdb_ci_vm_instance' and child as the above region(dataCenter)

 

var cmdbDelete=new GlideRecord('cmdb_rel_ci');cmdbDelete.addQuery('type','5f985e0ec0a8010e00a9714f2a172815').addCondition('child.name',dataCenter). addCondition('parent.sys_class_name','cmdb_ci_vm_instance');

cmdbDelete.query();

while(cmdbDelete.next())

{

 

// check if the 'arr' array contains the VM instance fetched from ServiceNow ,If not delete the VM Instance from CMDB

 

if(!arrayUtil.contains(arr,cmdbDelete.parent.object_id))

{

var cmdbTableDelete= new GlideRecord('cmdb_ci_vm_instance');

cmdbTableDelete.addQuery('object_id',cmdbDelete.parent.object_id);

cmdbTableDelete.query();

if(cmdbTableDelete.next())

{

cmdbTableDelete.deleteRecord();

 

// after deleting the VM Instance , delete all the records in the relationship table which contains that instance.

 

var rel=new GlideRecord('cmdb_rel_ci');

rel.addQuery('parent',cmdbTableDelete.sys_id).addOrCondition('child',cmdbTableDelete.sys_id);

rel.query();

while(rel.next())

{

rel.deleteRecord();

}

 

To add the Relationship between CI :

Insert the relationship data to 'cmdb_rel_ci' table which contains Parent,Child and relationship-type. Find the

JSON which has the details of both the CI and use that to add relationship.

Example: VM Instance and Storage Volume

 

var jsn={

//paste the appropriate JSON

}

 

var len=jsn.Reservations.length;

var name;

var parentName;

var childName;

var relation;

var vId;

 

for(var i=0;i<len;i++)

{

var instance =jsn.Reservations[i].Instances[0];

var id=instance.InstanceId;

 

// get the name of the instance from Tags array in JSON

for(var j=0;j<instance.Tags.length;j++)

{

if(instance.Tags[j].Key=='Name')

name=instance.Tags[j].Value;

}

 

// Get the Parent CI(sys_id) - for this example VM Instance is the parent. Fetch each Instance

from ' cmdb_ci_vm_instance'

 

var vm= new GlideRecord('cmdb_ci_vm_instance');

vm.addQuery('object_id',id);

vm.query();

if(vm.next())

{

parentName=vm.sys_id;

}

 

// get the Child (sys_id )- for this Storage Volume is the Child

//A VM Instance can contain many Storage Volumes .So one to many relationship exits. The Storage Volume details will be in 'BlockDeviceMappings' array in Instance JSON. Loop through the the array to get the Child

 

for(var k=0;k<instance.BlockDeviceMappings.length;k++)

{

vId=instance.BlockDeviceMappings[k].Ebs.VolumeId;

var storageVolume= new GlideRecord('cmdb_ci_storage_volume');

storageVolume.addQuery('volume_id',vId);

storageVolume.query();

if(storageVolume.next())

{

childName=storageVolume.sys_id;

 

// after getting Parent and Child ,check if a Relation exists in table for the parent, child and exact Relationship Type. If exists then Ignore and 'Continue' to the next loop. For Instance and Storage Volume Relationship Type is ' Use End Point To::Use End Point From'

 

var cmdbRelExists=new GlideRecord('cmdb_rel_ci');

cmdbRelExists.addQuery('parent',parentName).addCondition('type','e7490a74532221007c949096a11c08b2').addCondition('child',childName).addCondition('child.sys_class_name','cmdb_ci_storage_volume');

cmdbRelExists.query();

if(cmdbRelExists.next())

{

continue;

}

 

// If the exact Relation does not exist ,but the Storage Volume is mapped to a different VM Instance ,then update record with the new instance as in JSON.

 

var cmdbRel=new GlideRecord('cmdb_rel_ci');

cmdbRel.addQuery('type','e7490a74532221007c949096a11c08b2').addCondition('child',childName).addCondition('child.sys_class_name','cmdb_ci_storage_volume').addCondition('parent.sys_class_name','cmdb_ci_vm_instance');

cmdbRel.query();

if(cmdbRel.next())

{

if(cmdbRel.parent!=parentName)

{

cmdbRel.parent=parentName;

cmdbRel.update();

}

 

// If there is no Storage Volume and VM Instance relation exists, then insert the new relation

 

else

{

var relInsert=new GlideRecord('cmdb_rel_ci');

relInsert.initialize();

relInsert.parent=parentName;

relInsert.child=childName;

relInsert.setDisplayValue('type','Use End Point To::Use End Point From');

relInsert.insert();

}}

 

 

Version history
Last update:
‎04-22-2019 04:42 AM
Updated by: