What is a suitable strategy for provisioning Chef Server through code? Background


I am tasked with setting up a Chef server on our Azure Cloud for a new DevOps automation project. 
We are using the Resource Manager model for Azure, in case it's relevant.
We will likely use free versions of Chef i.e. Chef Automate is not an option.


Objective

I am new to Chef and Azure, but I would like to try to do it the "right" way from the start. Specifically: Given the Chef server will eventually become an indispensable part of the DevOps infrastructure I want to make it provisionable through code.

To move toward achieving these objectives I have explored the following options. 

Option 1: Chef to provision Chef Server

Use Chef Server cookbooks and Chef solo to provision Chef server.

In such a scenario, my main question is: how do I create the Chef server VM and make Chef Solo discover it?

Option 2: Use Azure CLI + RM Templates


Manually create Azure VM 
Manually install Chef server
Save it as an image and Azure RM template
Use Azure CLI to provision from the RM Template and Image.


I am angling toward this option, but I have some anecdotal opinions from teammates, that Azure RM Templates wll not be declarative. Are they? 

Option 3: Use Vagrant  + Azure Provider + Chef Solo


(This option is primarily because I am comfortable with Vagrant)
The main advantage of this option is that I think it will eliminate the question I had in Option 1. Is my assumption here correct?
However, I think this option does not work for a permanent infrastructure like Chef Server, I think Vagrant is more useful when you have disposable cloud-based virtualized environments. Is my understanding here correct?


Note: Obviously these are not the only 3 options. Please help with any strategies I might have missed.
'Suitable' can honestly be whatever works for you. I personally feel its perfectly reasonable to do a manual install of Chef server. It is the CM tool to help provision the rest of your fleet. You will not be setting up Chef server over and over again. You do it once, and then never again, in theory.

That theory breaks down however, in respect to server outages. Eventually, one day, your Chef server will go down. If you are running Chef in HA mode, or you have a very good backup system that allows you to restore the entire server, then you are fine. I don't know what it is for Azure, but with Amazon, you can take nightly snapshots of the entire server and simply restore from the AMI if the server ever goes "hard down".

Let's pretend that you don't run Chef in HA, or you aren't very confident in your backup system, or you just want to tinker... my recommendation would be to leverage Terraform w/provisioner scripts, or Packer with Terraform.

You can get the basics of Chef server setup with some simple commands that only need to be run once. This is perfect for Terraform and it's provisioner scripts. Obviously, it runs the provisioner scripts only once (during server creation) and that's all you need for Chef. If something happens to your Chef server, Terraform can rebuild it from scratch. Although, you'll have to re-key your local client and tie all your instances to the new Chef server. This is a huge headache and I would not recommend ever doing that if you can avoid it. :P