VMware Cloud Community
emacintosh
Hot Shot
Hot Shot
Jump to solution

VRA 8.1 - Adding/Removing NICs Before Provisioning

Does anyone know if it's possible to add/remove nics before provisioning starts...kinda like changing the blueprint on the fly?

In our environment, we have several different network configurations depending on what type and where a server is being built.  It could have 1-3 nics of varying port group needs.  We'd prefer to use one blueprint with one form and drive the logic from there.  But I can't figure out a way to manipulate the blueprint for those different cases - there is no count property on a network, so we can't set that to 0 to "remove" a nic.  And passing in an array of networks from a hidden input on the form may not be doable because we don't know any of the network Ids - which that array seems to need.

Can we manipulate the number of nics during Network Configure or Network Provision events?  Meaning, can we add in new nics or remove nics during those phases?  Or during some other event topic before provisioning kicks off?

We are are aware that we can make changes after the server is built during the post provisioning, but that would be the least optimal approach I think.  So really just looking for options before that.  For example, a blueprint with no networks attached, and then build them on the fly - either via inputs or during some events.  Or build a blueprint with 3 networks and remove 1 or more along the way if needed.

Any help is appreciated, thanks.

Reply
0 Kudos
1 Solution

Accepted Solutions
emacintosh
Hot Shot
Hot Shot
Jump to solution

So far this seems promising.  Each network object has a count property set to 0 or 1.  They also each have a deviceIndex.  I don't believe this property has any meaning on the Network object itself (it's not in the list of properties when you click on one), but we can use it when mapping the network objects to the networks array on the vsphere machine, where that property does have meaning.

The map_by() function seems to be able to loop through an array, and run a "function" on each item, e.g. return an object like we do here.  Those results are put into a new array, effectively creating our array of network objects on the machine object.

So in this case, the array consists of each of our network objects.  For each one we create an object with a property of network with a value of the nic's id, as well as a property called deviceIndex set to the deviceIndex of the Network object.  For example, the following

resources:

  vSphereVM2:

    type: Cloud.vSphere.Machine

    properties:

      networks: '${map_by(resource.Nic0[*] + resource.Nic1[*] + resource.Nic2[*],nic => {"network":nic.id, "deviceIndex":nic.deviceIndex})}'

  Nic0:

    type: Cloud.vSphere.Network

    properties:

      count: 1

      deviceIndex: 0

  Nic1:

    type: Cloud.vSphere.Network

    properties:

      count: 1

      deviceIndex: 2

  Nic2:

    type: Cloud.vSphere.Network

    properties:

      count: 1

      deviceIndex: 1

would result in a networks array that would like this:

resources:

  vSphereVM2:

    type: Cloud.vSphere.Machine

    properties:

      networks:

          - network: <Nic0's ID>

             deviceIndex: 0

          - network: <Nic1's ID>

            deviceIndex: 2

          -network: <Nic2's Id>

            deviceIndex: 1

Now to toggle a NIC "off", simply set its count property to 0 and it will be ignored during the mapping.  The deviceIndex is used here to force the order that we want the NICs to be added - otherwise, we may not configure them correctly.

Our goal will be to set the counts and indexes automatically based on the form input, which should be easy enough hopefully.

View solution in original post

Reply
0 Kudos
9 Replies
aenagy
Hot Shot
Hot Shot
Jump to solution

emacintosh

Does this help?

Introducing Blueprint Expressions in Cloud Assembly --> see Leveraging a “Zero” Count

https://blogs.vmware.com/management/2019/02/blueprinting-expressions-in-cloud-assembly.html

Reply
0 Kudos
emacintosh
Hot Shot
Hot Shot
Jump to solution

I think it could, but I would need to know where that count property might exist for the nics.  The network objects on the vsphere machine object don't have a count a property, so I can't set them to 0, which is what I thought would be a great way to go. 

Do you happen to know of another place where a count property could help drive the network configuration?

Reply
0 Kudos
aenagy
Hot Shot
Hot Shot
Jump to solution

emacintosh

No, sorry.

Reply
0 Kudos
emacintosh
Hot Shot
Hot Shot
Jump to solution

I think I was mistaken about the count property.  I may have been looking to put the count on the list of networks defined on the vm, not the count property on the network itself.  There are some other threads out here about people trying to do similar for both disks and networks, and they're using the undocumented map_to_object function in the blueprint (the function is only mentioned in an example in the release notes).

So I am headed down the same path now and will share my results here once I have a better idea of if/how this will work.

Reply
0 Kudos
emacintosh
Hot Shot
Hot Shot
Jump to solution

So far this seems promising.  Each network object has a count property set to 0 or 1.  They also each have a deviceIndex.  I don't believe this property has any meaning on the Network object itself (it's not in the list of properties when you click on one), but we can use it when mapping the network objects to the networks array on the vsphere machine, where that property does have meaning.

The map_by() function seems to be able to loop through an array, and run a "function" on each item, e.g. return an object like we do here.  Those results are put into a new array, effectively creating our array of network objects on the machine object.

So in this case, the array consists of each of our network objects.  For each one we create an object with a property of network with a value of the nic's id, as well as a property called deviceIndex set to the deviceIndex of the Network object.  For example, the following

resources:

  vSphereVM2:

    type: Cloud.vSphere.Machine

    properties:

      networks: '${map_by(resource.Nic0[*] + resource.Nic1[*] + resource.Nic2[*],nic => {"network":nic.id, "deviceIndex":nic.deviceIndex})}'

  Nic0:

    type: Cloud.vSphere.Network

    properties:

      count: 1

      deviceIndex: 0

  Nic1:

    type: Cloud.vSphere.Network

    properties:

      count: 1

      deviceIndex: 2

  Nic2:

    type: Cloud.vSphere.Network

    properties:

      count: 1

      deviceIndex: 1

would result in a networks array that would like this:

resources:

  vSphereVM2:

    type: Cloud.vSphere.Machine

    properties:

      networks:

          - network: <Nic0's ID>

             deviceIndex: 0

          - network: <Nic1's ID>

            deviceIndex: 2

          -network: <Nic2's Id>

            deviceIndex: 1

Now to toggle a NIC "off", simply set its count property to 0 and it will be ignored during the mapping.  The deviceIndex is used here to force the order that we want the NICs to be added - otherwise, we may not configure them correctly.

Our goal will be to set the counts and indexes automatically based on the form input, which should be easy enough hopefully.

Reply
0 Kudos
rohitnegi89
Contributor
Contributor
Jump to solution

the nic.id option in map_by() function is not working correctly. 

The problem here is that it attaches networks to the VM which are not even selected while adding networks as resources in BP.

For example:

1.  networks: '${map_by(resource.NIC0[*].id + resource.NIC1[*].id + resource.NIC2[*].id,nic => {"network":nic.id, "assignment":"static"})}'

---- Here "nic.id" doesn't attach NIC0.id to first network and NIC1.id to the second network etc. 

2. One of them may attach correctly sometimes but the others are like randomly picking networks from my cloud account.

Solution:

I want to make sure that the correct network gets assigned whenever the VM is provisioned, like only those that i select.

I tried this solution below but its not working and giving error:

networks: '${map_by(resource.NIC0[*].id + resource.NIC1[*].id + resource.NIC2[*].id,nic => {"network":resource.NIC0.id, "assignment":"static"})}'

errorCannot have multiple NICs connected to the same network

 

 

Can you please help me here. It would be a great..

Reply
0 Kudos
emacintosh
Hot Shot
Hot Shot
Jump to solution

Admittedly, this thread was more about creating a variable number of nics in one template than configuring them correctly (and there may be better ways to accomplish this now, although we still use this approach).

 

If you want to configure the right networks during provision, I guess we'd need to know how you are selecting the network exactly.  I think using network profiles with tagging is the approach to use if you can, although I've seen others who just want to select a network complain about that approach.

 

In our case, we get random networks at provision time and configure them correctly afterward.  Since 8.x was new at the time, we found an approach that worked for us.  However, we've since discovered the networkSelectionIds property that is available during Network Configure and may use that to select the correct network in the future.  I believe our SDN may be too complicated to choose it directly on the form.

rohitnegi89
Contributor
Contributor
Jump to solution

Any Idea on how can I get that networkSelectionID property while provisioning. 

Reply
0 Kudos
emacintosh
Hot Shot
Hot Shot
Jump to solution

This is my understanding, but we haven't actually tried to implement it yet so I'm not positive.  There may be other posts out here that are more helpful or someone can correct what I get wrong.  I'd also like to mention that this seems unnecessarily complex just to configure the right network.  So if you can get it done with network profiles and tagging, that's probably the way to go. 

 

If you subscribe the Network Configure event topic, which happens before provisioning, then you have the ability to review that field and modify it.  There are some good resources on how that works if you're not familiar, but essentially the field will be available as part of the input of the vro workflow or abx action tied to the subscription.  You can then create an output of the workflow/action with that field modified.  Then, during provisioning, vRA will select the network to use based on what's in this field. 

 

I believe that field contains vRA's IDs for each network.  If I recall correctly, it's a 3-dimensional array.  This event fires once for a deployment.  So the first element of the array would reference the machines on your template.  The second element would refer to the nics on that machine.  And the third element would be network id.  For example networkSelectionIds[0][1][0] would be the first network id that could be used for the 2nd nic of the first machine.

 

And so when that topic is fired, whichever networks vRA determines to be options for a nic on a machine will be passed through.  Again, I think this is determined by network profiles and tagging (still a fuzzy on how best to do that).  And so if you do nothing, then I think vRA chooses one of those networks for you.  But if you want, you can subscribe to the event, review those ids, provide whatever logic you want and send back an updated networkSelectionIds with the network(s) you choose. 

 

So for example, if you have two machines on a template and each has two nics,  And maybe the first machine has a couple networks that are valid for each nic, but the second machine has exactly one for each nic.  Then your networkSelectionIds field that you send back to vRA might look something like this:

 

[
	[
		["73d22d7e-1d94-44bb-b48e-00952ef7f47f","6074eeb4-13a6-4b3d-82e7-dfcbd6bc9c63"], // first machine, first nic
		["3835f69c-dba2-4d89-b86b-74ad407124c0","bb546048-3d9c-456b-a493-862f146e9bd5"] // first machine, second nic
	
	],

	[
		["2c908e88-6bbc-4218-958d-3ad986eb5356"], // second machine, first nic
		["fbd9e221-455d-4d2f-a1b5-777263e4e194"] // second machine, second nic
	]
]

 

 

So again, this is just my understanding without ever having done it, so I could be (way) off here.  And if you can configure vRA in a way that the only networks available for a nic are the ones that you want, then you shouldn't have to jump through all of these hoops.  I hope this is at least a bit helpful.

Reply
0 Kudos