How to reuse Vagrant parameter in Chef - vagrant

I'm struggling to understand how to pass current vagrant configuration to chef.
For example during Vagrant provisioning I have this configuration:
config.vm.provider :aws do |aws, override|
override.ssh.username = "ubuntu"
...
end
...
config.vm.provision :chef_solo do |chef|
chef.json = {
username: "ubuntu"
}
...
end
Now how can I reuse the ssh username in chef-solo provisioning?
I would like be able to write something like this:
config.vm.provision :chef_solo do |chef|
chef.json = {
username: config.ssh.username
}
end
Any help highly appreciated :)

This solutions seems very valid to me:
username = "ubuntu"
config.vm.provider :aws do |aws, override|
override.ssh.username = "#{username}"
...
end
...
config.vm.provision :chef_solo do |chef|
chef.json = {
username: "#{username}"
}
...
end
(thanks to Alvaro Miranda Aguilera how suggested this piece of code in Vagrant forum)

Related

Guest OS Type invalid for Windows 10 in Packer

We are trying vagrant for creating windows 10 virtual box image for one of our projects internally. As part of it, I got windows 10 64 bit disc image and did some research on creating custom image using our own OS disc. Hashicorp has Packer application along with vagrant which helps in creating virtual box using custom images.
Using packer, I have created my json file, template file, validated it and ran build command to create a virtual box, but the build fails at guest OS type and couldnt figure out what is the correct guest OS type name for windows 10. I am attaching my json file, template file, build logs for your reference. Any idea can be greatly appreciated!!
Windows-10.json
{
"builders": [
{
"type": "virtualbox-iso",
"iso_url": "{{user `iso_url`}}",
"iso_checksum_type": "{{user `iso_checksum_type`}}",
"iso_checksum": "{{user `iso_checksum`}}",
"headless": false,
"boot_wait": "2m",
"ssh_username": "vagrant",
"ssh_password": "vagrant",
"ssh_wait_timeout": "2h",
"shutdown_command": "shutdown /s /t 10 /f /d p:4:1 /c \"Packer Shutdown\"",
"guest_os_type": "windows-10",
"disk_size": 61440,
"vboxmanage": [
[
"modifyvm",
"{{.Name}}",
"--memory",
"2048"
],
[
"modifyvm",
"{{.Name}}",
"--cpus",
"2"
]
]
}
],
"post-processors":[
{
"type": "vagrant",
"keep_input_artifact": false,
"output": "windows_10_{{.Provider}}.box",
"vagrantfile_template": "windows10.template"
}
],
"variables": {
"iso_url":
"C:/ABC/Vagrant/Windows_10/SW_DVD5_Win_Pro_10_1511.1_64BIT_English_MLF_X20-93914.iso",
"iso_checksum_type": "md5",
"iso_checksum": "bd09dc56c51a6ce137b8c0eb7c4369ea",
"autounattend": "./answer_files/10/Autounattend.xml"
}
}
My windows 10 template looks like below
Windows10.template
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">= 1.6.2"
Vagrant.configure("2") do |config|
config.vm.define "vagrant-windows-10"
config.vm.box = "windows_10"
config.vm.communicator = "winrm"
# Admin user name and password
config.winrm.username = "vagrant"
config.winrm.password = "vagrant"
config.vm.guest = :windows
config.windows.halt_timeout = 15
config.vm.network :forwarded_port, guest: 3389, host: 3389, id: "rdp", auto_correct: true
config.vm.network :forwarded_port, guest: 22, host: 2222, id: "ssh", auto_correct: true
config.vm.provider :virtualbox do |v, override|
#v.gui = true
v.customize ["modifyvm", :id, "--memory", 2048]
v.customize ["modifyvm", :id, "--cpus", 2]
v.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
end
config.vm.provider :vmware_fusion do |v, override|
#v.gui = true
v.vmx["memsize"] = "2048"
v.vmx["numvcpus"] = "2"
v.vmx["ethernet0.virtualDev"] = "vmxnet3"
v.vmx["RemoteDisplay.vnc.enabled"] = "false"
v.vmx["RemoteDisplay.vnc.port"] = "5900"
v.vmx["scsi0.virtualDev"] = "lsisas1068"
end
config.vm.provider :vmware_workstation do |v, override|
#v.gui = true
v.vmx["memsize"] = "2048"
v.vmx["numvcpus"] = "2"
v.vmx["ethernet0.virtualDev"] = "vmxnet3"
v.vmx["RemoteDisplay.vnc.enabled"] = "false"
v.vmx["RemoteDisplay.vnc.port"] = "5900"
v.vmx["scsi0.virtualDev"] = "lsisas1068"
end
end
Windows10.json has been successfully validated and when am running packer build, below is the error i get
packer build windows10.json
virtualbox-iso output will be in this color.
==> virtualbox-iso: Downloading or copying Guest additions
virtualbox-iso: Downloading or copying:
file:///C:/Program%20Files/Oracle/VirtualBox/VBoxGuestAdditions.iso
==> virtualbox-iso: Downloading or copying ISO
virtualbox-iso: Downloading or copying: file:///C:/ABC/Vagrant/Windows_10/SW_DVD5_Win_Pro_10_1511.1_64BIT_English_MLF_X20-93914.iso
==> virtualbox-iso: Creating virtual machine...
==> virtualbox-iso: Error creating VM: VBoxManage error: VBoxManage.exe: error: Guest OS type 'windows-10' is invalid
==> virtualbox-iso: VBoxManage.exe: error: Details: code
VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee IUnknown
==> virtualbox-iso: VBoxManage.exe: error: Context: "CreateMachine(bstrSettingsFile.raw(), bstrName.raw(), ComSafeArrayAsInParam(groups), bstrOsTypeId.raw(), createFlags.raw(), machine.asOutParam())" at line 273 of file VBoxManageMisc.cpp
==> virtualbox-iso: Deleting output directory...
Build 'virtualbox-iso' errored: Error creating VM: VBoxManage error:
VBoxManage.exe: error: Guest OS type 'windows-10' is invalid
VBoxManage.exe: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee IUnknown
VBoxManage.exe: error: Context: "CreateMachine(bstrSettingsFile.raw(), bstrName.raw(), ComSafeArrayAsInParam(groups), bstrOsTypeId.raw(), createFlags.raw(), machine.asOutParam())" at line 273 of file VBoxManageMisc.cpp
==> Some builds didn't complete successfully and had errors:
--> virtualbox-iso: Error creating VM: VBoxManage error: VBoxManage.exe: error: Guest OS type 'windows-10' is invalid
VBoxManage.exe: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee IUnknown
VBoxManage.exe: error: Context: "CreateMachine(bstrSettingsFile.raw(), bstrName.raw(), ComSafeArrayAsInParam(groups), bstrOsTypeId.raw(), createFlags.raw(), machine.asOutParam())" at line 273 of file VBoxManageMisc.cpp
==> Builds finished but no artifacts were created.
See the documentation Packer docs guest_os_type. Just run VBoxManage list ostypes and you will find that you should use Windows10_64.

Install Bundler gem with rbenv when provisioning (Chef + Vagrant)

I'm using Vagrant + Chef to provision an Ubuntu16.04 vm for rails development. I would like to install Bundler with Chef (using rbenv) but for some reason it fails with the following message: "undefined method `clear_sources' for Custom resource rbenv_gem from cookbook rbenv".
Any ideas?
Thanks!
The content of my Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-16.04"
config.vm.network :forwarded_port, guest: 3000, host: 3000
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.add_recipe "apt"
chef.add_recipe "ruby_build"
chef.add_recipe "rbenv::user"
chef.add_recipe "rbenv::vagrant"
chef.json = {
rbenv: {
user_installs: [{
user: 'vagrant',
rubies: ["2.3.1"],
global: "2.3.1" ,
gems: {
"2.3.1" => [
{ name: "bundler" }
]
}
}]
}
}
end
end
Cheffile:
site "https://supermarket.getchef.com/api/v1"
cookbook 'apt'
cookbook 'build-essential'
cookbook 'ruby_build', '~> 1.0.0'
cookbook 'rbenv', git: 'https://github.com/aminin/chef-rbenv'
You should use the official chef-rbenv cookbook, your issue was probably fixed by #110.
BTW. Any particular reason for not using test-kitchen?

Multiple EC2 instances using Vagrant

I'm trying out Vagrant to provision an environment with multiple EC2 instances in AWS (using vagrant-aws plugins) and using a JSON config file for Vgrant to read from. Below is the JSON file:
macp-3:vagrant-aws sans$ cat scripts/aws.json
{
"env": "dops",
"access_key": "XXXXXXXXXXXXXXXX",
"secret_key": "hfgy5ejfkprg2432432beqo2r",
"region": "eu-west-1",
"availability_zone": "a",
"subnet_id": "subnet-0b766860",
"security_groups": [
"sg-53t48c34",
"sg-11668f7e",
"sg-4a6c8525",
"sg-75168c1e"
],
"ssh_username": "ubuntu",
"keypair": "Xdops_testKey",
"ssh_private_key": "/Users/sans/.ssh/id_rsa",
"ec2s": {
"dops-agg-001": {
"ami_id": "ami-838675f7",
"instance_type": "m3.medium",
"elastic_ip": "ture",
"tags": {
"Name": "dops-agg-001",
"Role": "sql-aggr",
"ServiceType": "database",
"NopeType": "mem_master",
"CostCentre": "QA"
}
},
"dops-nag-001": {
"ami_id": "ami-838675f7",
"instance_type": "m3.medium",
"elastic_ip": "ture",
"tags": {
"Name": "dops-nag-001",
"Role": "monitoring",
"ServiceType": "controller",
"NopeType": "nagios",
"CostCentre": "QA"
}
}
}
}
This is the Vagrantfile that I've come up with:
# -*- mode: ruby -*-
# vi: set ft=ruby :
aws_cfg = (JSON.parse(File.read("scripts/aws.json")))
Vagrant.configure("2") do |config|
config.vm.box = "dummy"
config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
aws_cfg['ec2s'].each do |node|
node_name = node[0]
node_value = node[1]
# Node specific configuration
config.vm.define node_name do |config2|
ec2_tags = node_value['tags']
# Spining up EC2 instances
config2.vm.provider :aws do |ec2, override|
ec2.access_key_id = aws_cfg['access_key']
ec2.secret_access_key = aws_cfg['secret_key']
ec2.keypair_name = aws_cfg['keypair']
ec2.region = aws_cfg['region']
ec2.availability_zone = aws_cfg['region']+aws_cfg['availability_zone']
ec2.subnet_id = aws_cfg['subnet_id']
ec2.security_groups = aws_cfg['security_groups']
#
ec2.ami = node_value['ami_id']
ec2.instance_type = node_value['instance_type']
ec2.elastic_ip = node_value['elastic_ip']
#
ec2.tags = {
'Name' => ec2_tags['Name'],
'Role' => ec2_tags['Role'],
'ServiceType' => ec2_tags['ServiceType'],
'NopeType' => ec2_tags['NopeType'],
'CostCentre' => ec2_tags['CostCentre']
}
#
override.ssh.username = "ubuntu"
override.ssh.private_key_path = "/Users/sans/.ssh/id_rsa"
end
# Final Puppet provisioning
#config2.vm.provision :puppet do |ppt|
# ppt.options = "--verbose --debug"
# ppt.manifests_path = "puppet/manifests"
# ppt.manifest_file = "nodes.pp"
# ppt.module_path = "puppet/modules"
#end
end
end
end
It's working okay but trying to spin up the boxes in parallel, instead of one-by-one:
macp-3:vagrant-aws sans$ vagrant up --provider=aws
Bringing machine 'dops-agg-001' up with 'aws' provider...
Bringing machine 'dops-mon-001' up with 'aws' provider...
[fog][WARNING] Unable to load the 'unf' gem. Your AWS strings may not be properly encoded.
==> dops-mon-001: HandleBoxUrl middleware is deprecated. Use HandleBox instead.
==> dops-mon-001: This is a bug with the provider. Please contact the creator
==> dops-agg-001: HandleBoxUrl middleware is deprecated. Use HandleBox instead.
==> dops-mon-001: of the provider you use to fix this.
....
....
I believe there are some problem with looping in the Vagrantfile? Can anyone tell me what's going wring here? Best!
This question has been answered in a Google Group.
Solution:
--[no-]parallel - Bring multiple machines up in parallel if the provider supports it.

Vagrant Vhost with a FQDN (Full Qualified Domain Name)

Take a domain name like:
development.mysite.com
I want to setup a vhost with Vagrant that would allow me to access this location in my browser.
From what I can tell, it won't let me use port 80, so even if I change my hosts file to something like:
127.0.0.1 development.mysite.com
It still won't find it.
Does anyone have an idea?
UPDATE
VagrantFile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "hashicorp/precise32"
# Networking
config.vm.network "forwarded_port", guest: 80, host: 8000
config.vm.network "private_network", ip: "192.168.33.10"
# Synced folders
config.vm.synced_folder ".", "/var/www"
# Provisioning
config.vm.provision :shell, :inline => "apt-get update --fix-missing"
config.vm.provision :shell do |shell|
shell.inline = "mkdir -p /etc/puppet/modules;
(puppet module install example42/puppi; true)
(puppet module install example42/apache; true)
(puppet module install example42/php; true)
(puppet module install puppetlabs/stdlib; true)
(puppet module install puppetlabs/mysql; true)
(puppet module install saz/vim; true)"
end
config.vm.provision "puppet" do |puppet|
puppet.facter = {
"fqdn" => "development.eatologie.com",
"hostname" => "www",
"docroot" => '/var/www/html/'
}
puppet.manifests_path = "puppet"
puppet.manifest_file = "site.pp"
end
end
Puppet site.pp
###########################
# Eatologie Puppet Config #
###########################
# OS : Linux #
# Database : MySQL 5 #
# Web Server : Apache 2 #
# PHP version : 5.4 #
###########################
# Vim
class { 'vim': }
# Puppi
class { 'puppi': }
# Apache setup
class { "apache":
puppi => true,
puppi_helper => "myhelper",
}
apache::vhost { $fqdn :
docroot => $docroot,
server_name => $fqdn,
priority => '',
template => 'apache/virtualhost/vhost.conf.erb',
}
apache::module { 'rewrite': }
# PHP Extensions
class {"php":}
php::module { ['xdebug', 'mysql', 'curl', 'gd']:
notify => Service['apache2']
}
# MySQL Server
class { '::mysql::server':
root_password => 'abc123',
}
mysql::db { 'eatdb':
user => 'admin',
password => 'abc456',
host => 'localhost',
grant => ['all'],
charset => 'utf8',
}
# Eatologie Setup
file { $docroot:
ensure => 'directory',
}
$writeable_dirs = ["${docroot}cache/", "${docroot}cache/css/", "${docroot}cache/css/js/"]
file { $writeable_dirs:
ensure => "directory",
mode => '0777',
require => File[$docroot],
}
As far as I can see, this is the relevant part in your Vagrantfile:
# Networking
config.vm.network "forwarded_port", guest: 80, host: 8000
config.vm.network "private_network", ip: "192.168.33.10"
It means that your Vagrantbox is accessible at ip 192.168.33.10 and port 8000. So, your hosts file should say
192.168.33.10 development.eatologie.com
instead of
127.0.0.1 development.mysite.com
With that change, you should be to access your site at development.eatologie.com:8000
For more info, also take a look at the Vagrant documentation pages for forwarded ports and private networking. For the private networking part take into account that, if you assign a static IP to your Vagrant box (as you did in your setup), you have to be sure the IP is not taken by another device on your local network.

Vagrant File Chef Attributes

I am trying to configure my Vagrant file to have some chef attributes, but I must be doing something wrong because the chef recipes are using the defaults instead of my the attributes I am trying to set. Here is my config section of my vagrant file:
config.vm.provision :chef_solo do |chef|
chef.json = {
:mysql => {
:server_root_password => 'password'
},
:nodejs => {
:version => '0.6.14',
:dir => '/usr/local',
:npm => '1.1.13'
}
}
chef.cookbooks_path = "config/env/cookbooks"
chef.add_recipe "apt"
chef.add_recipe "mongodb::10gen_repo"
chef.add_recipe "mongodb"
chef.add_recipe "mysql::client"
chef.add_recipe "mysql::server"
chef.add_recipe "nodejs"
chef.add_recipe "nodejs::npm"
#chef.add_recipe "mymc_service"
end
Is my Ruby wrong or is there a better way to do this?
I'm brand new to Vagrant, Ruby, and Chef, but this is what worked for me:
config.vm.provision :chef_solo do |chef|
chef.json = {
"mysql" => {
"server_root_password" => "password"
}
}
chef.add_recipe "mysql" # etc
end
I recently ran into this same issue. While Mike's answer did not solve my problem, possibly due to the newer Vagrant/Chef versions, it pointed me in the right direction. The following is what i had to do for MySQL server to work:
config.vm.provision :chef_solo do |chef|
chef.json = {
:mysql => {
:server_root_password => "password",
:server_repl_password => "password",
:server_debian_password => "password"
}
}
chef.add_recipe "mysql::server"
end

Resources