Install Bundler gem with rbenv when provisioning (Chef + Vagrant) - 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?

Related

How to reuse Vagrant parameter in Chef

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)

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 using Ruby 1.9.3 as default

Hey all i am trying to build a vagrant vm. i am using chef-solo for provisioning and chef-rbenv to manage my versions. so in the vagrantfile i specify
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "cookbooks"
chef.add_recipe "ruby_build"
chef.add_recipe "rbenv::system"
chef.add_recipe "rbenv::vagrant"
...
chef.json = {
"rbenv" => {
"rubies" => [ "1.9.3-p327" ],
"global" => "1.9.3-p327",
"gems" => {
"1.9.3-p327" => [
{ "name" => "bundler" }
]
}
}
}
end
so that the default ruby version will be 1.9.3-p327, but it crashes
Error executing action `install` on resource 'rbenv_ruby[1.9.3-p327] (system)'
and if i dont specify the version in the vagrant file(as seen above), and go with the default rbenv that chef builds so that i can install it once i am in the vm. then i get this
vagrant#precise64:/vagrant$ rbenv install 1.9.3-p327
Downloading yaml-0.1.4.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/36c852831d02cf90508c29852361d01b
Installing yaml-0.1.4...
BUILD FAILED
...
it works when i run sudo rbenv install 1.9.3-p327 but then when running anything i have to prefix it with sudo even ruby -v
vagrant#precise64:~$ ruby -v
ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux]
vagrant#precise64:~$ sudo ruby -v
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin12.3.0]
how can i get it installed with chef-solo. i have tried all week and cant get it working at all.
The json requires you to specify for chef the rbenv location that your installing ruby to. since the recipes call that you install rbenv on a system level and then a user lvl in this case vagrant.
chef.add_recipe "rbenv::system"
chef.add_recipe "rbenv::vagrant"
So i went and changed the json to this:
chef.json = {
'rbenv' => {
'user_installs' => [
{
'user' => 'vagrant',
'rubies' => ['1.9.3-p327'],
'global' => '1.9.3-p327',
'gems' => {
'1.9.3-p327' => [
{ 'name' => 'bundler' },
{ 'name' => 'rake' }
]
}
}
]
}
}
Also the current rbenv cookbook often has bugs so its good to reference the latest taged version of the cookbook in the cheffile.
cookbook 'rbenv', git: 'git://github.com/fnichol/chef-rbenv.git', ref: "v0.7.2"
like so.

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