Si bien Vagrant ofrece múltiples opciones sobre cómo puede aprovisionar su máquina, existe un patrón de uso estándar, así como algunos puntos importantes comunes a todos los aprovisionadores que es importante conocer.

Configuración

Primero, cada aprovisionador se configura dentro de su Vagrantfile usando el config.vm.provision llamada al método. Por ejemplo, el Vagrantfile a continuación habilita el aprovisionamiento de shell:

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "shell", inline: "echo hello"
end

Cada aprovisionador tiene un tipo, como "shell", utilizado como primer parámetro de la configuración de aprovisionamiento. Seguir eso es básico key/ valor para configurar ese aprovisionador específico. En lugar de básico key/ value, también puede usar un bloque Ruby para una sintaxis que se parezca más a una asignación de variable. Lo siguiente es efectivamente el mismo que el ejemplo anterior:

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "shell" do |s|
    s.inline = "echo hello"
  end
end

El beneficio de la sintaxis basada en bloques es que con más de un par de opciones puede mejorar enormemente la legibilidad. Además, algunos aprovisionadores, como el aprovisionador Chef, tienen métodos especiales que se pueden llamar dentro de ese bloque para facilitar la configuración que no se puede hacer con el key/ value, o puede usar esta sintaxis para pasar argumentos a un script de shell.

los attributes que se pueden configurar en una sola línea son los attributes que se establecen con el = estilo, como inline = "echo hello" encima. Si el estilo es más bien una llamada a función, como add_recipe "foo", entonces esto no se puede especificar en una sola línea.

También se puede nombrar a los proveedores (desde 1.7.0). Estos nombres se usan cosméticamente para la salida, así como también para la configuración del aprovisionador (que se describe más adelante). A continuación, se muestra un ejemplo de nombres de aprovisionadores:

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "bootstrap", type: "shell" do |s|
    s.inline = "echo hello"
  end
end

Nombrar a los aprovisionadores es simple. El primer argumento para config.vm.provision se convierte en el nombre, y luego un type La opción se utiliza para especificar el tipo de aprovisionador, como type: "shell" encima.

Aprovisionadores en ejecución

Los aprovisionadores se ejecutan en tres casos: el inicial vagrant up, vagrant
provision
, y vagrant reload --provision.

A --no-provision la bandera se puede pasar a up y reload si no desea ejecutar aprovisionadores. Asimismo, puedes pasar --provision para forzar el aprovisionamiento.

los --provision-with El indicador se puede usar si solo desea ejecutar un aprovisionador específico si tiene varios aprovisionadores especificados. Por ejemplo, si tiene un shell y un aprovisionador Puppet y solo desea ejecutar el shell, puede hacerlo vagrant provision --provision-with shell. Los argumentos para --provision-with puede ser el tipo de aprovisionador (como “shell”) o el nombre del aprovisionador (como “bootstrap” de arriba).

Ejecutar una vez, siempre o nunca

De forma predeterminada, los aprovisionadores solo se ejecutan una vez, durante la primera vagrant up desde el ultimo vagrant destroy, a menos que el --provision se establece la bandera, como se indicó anteriormente.

Opcionalmente, puede configurar aprovisionadores para que se ejecuten en cada up o reload. Solo no se ejecutarán si el --no-provision bandera se especifica explícitamente. Para hacer esto, configure el run opción a “siempre”, como se muestra a continuación:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo hello",
    run: "always"
end

También puede configurar run: para "never" si tiene un aprovisionador opcional que desea mencionar al usuario en un “mensaje de publicación” o que requiere alguna otra configuración antes de que sea posible, llame a esto con vagrant provision --provision-with bootstrap.

Si está utilizando el formato de bloque, debe especificarlo fuera del bloque, como se muestra a continuación:

Vagrant.configure("2") do |config|
  config.vm.provision "bootstrap", type: "shell", run: "never" do |s|
    s.inline = "echo hello"
  end
end

Varios proveedores

Múltiple config.vm.provision Los métodos se pueden utilizar para definir varios aprovisionadores. Estos aprovisionadores se ejecutarán en el orden en que están definidos. Esto es útil por una variedad de razones, pero más comúnmente se usa para que un script de shell pueda arrancar parte del sistema para que otro aprovisionador pueda hacerse cargo más tarde.

Si define aprovisionadores en múltiples niveles de “alcance” (como globalmente en el bloque de configuración, luego en una definición de múltiples máquinas, luego tal vez en una anulación específica del proveedor), entonces los alcances externos siempre se ejecutarán antes de cualquier ámbito interno. Por ejemplo, en el Vagrantfile a continuación:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo foo"

  config.vm.define "web" do |web|
    web.vm.provision "shell", inline: "echo bar"
  end

  config.vm.provision "shell", inline: "echo baz"
end

El orden de los aprovisionadores será repetir “foo”, “baz”, luego “bar” (¡tenga en cuenta que el segundo podría no ser el esperado!). Recuerde: ordenar es de fuera hacia dentro.

Con varios aprovisionadores, utilice el --provision-with la configuración junto con los nombres para obtener un control más preciso sobre lo que se ejecuta y cuándo.

Anulación de la configuración del aprovisionador

Advertencia: ¡Tema avanzado! La anulación del proveedor es un tema avanzado que realmente solo se vuelve útil si ya está utilizando anulaciones de múltiples máquinas y / o proveedores. Si recién está comenzando con Vagrant, puede omitir esto de manera segura.

Al usar funciones como anulaciones específicas de proveedores o de múltiples máquinas, es posible que desee definir aprovisionadores comunes en el alcance de configuración global de un Vagrantfile, pero anular ciertos aspectos de ellos internamente. Vagrant te permite hacer esto, pero tiene algunos detalles a considerar.

Para anular la configuración, debe asignar un nombre a su proveedor.

Vagrant.configure("2") do |config|
  config.vm.provision "foo", type: "shell",
    inline: "echo foo"

  config.vm.define "web" do |web|
    web.vm.provision "foo", type: "shell",
      inline: "echo bar"
  end
end

En lo anterior, solo se repetirá la “barra”, porque la configuración en línea sobrecargó el aprovisionador externo. Esta sobrecarga solo es efectiva dentro de ese ámbito: la VM “web”. Si hubiera otra VM definida, todavía haría eco de “foo” a menos que ella misma también sobrecargara el aprovisionador.

Tenga cuidado con los pedidos. Al anular un aprovisionador en un subámbito, el aprovisionador se ejecutará en ese punto. En el siguiente ejemplo, la salida sería “foo” y luego “bar”:

Vagrant.configure("2") do |config|
  config.vm.provision "foo", type: "shell",
    inline: "echo ORIGINAL!"

  config.vm.define "web" do |web|
    web.vm.provision "shell",
      inline: "echo foo"
    web.vm.provision "foo", type: "shell",
      inline: "echo bar"
  end
end

Si desea conservar el orden original, puede especificar el preserve_order: true bandera:

Vagrant.configure("2") do |config|
  config.vm.provision "do-this",
    type: "shell",
    preserve_order: true,
    inline: "echo FIRST!"
  config.vm.provision "then-this",
    type: "shell",
    preserve_order: true,
    inline: "echo SECOND!"
end