Get property (name, ID...) of currently processed VM and use it somewhere

Hi,

I’m trying to make Vagrantfile as simple and as native as possible. I want to take machine name and use it e.g. as a hostname, but as simple as possible in multi-machine config, so without making the whole doend block on define directive. Considering it’s possible to use thing like config.vm.hostname as a variable in other places if defined, is it possible to get machine name, possibly ID and creation timestamp maybe?

I’ve tried googling, digging the official Vagrant Google Group discussion list, searching and asking on Reddit - no luck. Everywhere I get the very same answer: “if you want to make Vagrant VM hostname or provider-specific label, please do…”. Is there an easy/affordable way to use some VM properties as other variables’ content?

Corresponding Reddit thread which shows my problem and listing.

Thanks in advance.

Hey!

If you have a multi-guest environment you can just use a variable to define the guest name and use it as a hostname:

Vagrant.configure("2") do |config|
  guest_name = "test"

  config.vm.define guest_name do |guest|
    guest.vm.hostname = guest_name
  end
end

A Vagrantfile can run and support the ruby language, so if you have a variable or a set of data (say inside a Hash), you should be able to use it just like you would a regular ruby script. There is not a supported way to define multiple guests without using a ruby block to do so. However I believe the code above is as simple as you can get for solving your issue!

You can read more about that in the docs here: https://www.vagrantup.com/docs/multi-machine#defining-multiple-machines

And that’s what I wanted to avoid. I know very well that I can manually assign hostname or provider-specific label - every Google search leads me to similar result. I assumed, however, that config.vm.define "machine1" directive inherits adjacent/parent properties, so there should be such simple possibility of using machine name in hostname - rather than defining block, even embedded in a loop in case of several machines. Or am I wrong?

All you are seeing when you use the config.vm.define option internally is a method that takes a string name (in your case "machine1") and a block of options for a config. When you’re inside that block, you’re setting options, and you don’t have access to the passed in parameter. You can think of this “block” like a key=>value hash. So no, there’s really not a good way to obtain the parameter name inside the define block here because it’s outside the scope of what that block has access to. Your best bet is to define is as a variable and use it this way in your Vagrantfile.

OK, so what we know:

  1. The .define block takes an arbitrary argument (name)
  2. The .define block takes a set of options.

In the Vagrantfile, we can either:

  • set these options in each of specified machines’ definitions
  • set these options in the main Vagrant.configure and its descendant blocks (like config.vm.provider ones), relying on configuration inheritance between parent/child blocks

Then where does Vagrant know the machine name from, considering that Vagrant uses it when spinning up and later listing items in CLI or accessing via SSH/RDP? Of course I can define the hostname inside of the .define block, but isn’t it overcomplicated?

Yes, I know I can make a loop, and some conditions inside of it. But ideally I’d define several machines which inherit several directives and variables - even if some of these directives/variables say “take the Vagrant VM name and assign it to hostname” - and change them in doend block only if I’d want them to. It’s simply easier and more intuitive.

Does it qualify for humble bug report instead of / in addition to the whole conversation, maybe? :wink: