Private, versioned Vagrant boxes hosted on Amazon S3.
From the command line:
$ vagrant plugin install vagrant-s3auth
- Vagrant, v1.5.0+
vagrant-s3auth will automatically convert S3 box URLs
s3://bucket.example.com/path/to/metadata
to URLs signed with your AWS access key:
https://s3.amazonaws.com/bucket.example.com/path/to/metadata?AWSAccessKeyId=
AKIAIOSFODNN7EXAMPLE&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D
This means you can host your team's sensitive, private boxes on S3, and use your developers' existing AWS credentials to securely grant access.
If you've already got your credentials stored in the appropriate environment variables:
# Vagrantfile
Vagrant.configure('2') do |config|
config.vm.box = 'simple-secrets'
config.vm.box_url = 's3://example.com/secret.box'
end
AWS credentials are read from the standard environment variables
AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
.
If you need to obtain credentials from elsewhere, drop a block like the following at the top of your Vagrantfile:
creds = File.read(File.expand_path('~/.company-aws-creds')).lines
ENV['AWS_ACCESS_KEY_ID'] = creds[0].split
ENV['AWS_SECRET_ACCESS_KEY'] = creds[1].split
Simply point your box_url
at Amazon S3:
Vagrant.configure('2') do |config|
config.vm.box = 'simple-secrets'
config.vm.box_url = 'https://s3.amazonaws.com/bucket.example.com/secret.box'
end
Note that your URL must be of the form
https://s3.amazonaws.com/bucket/resource
For buckets outside "US Standard", use the region-specific s3 endpoints made available by AWS:
https://s3-us-west-1.amazonaws.com/bucket/resource # use region-specific s3 endpoints
Other valid forms of S3 URLs (bucket.s3.amazonaws.com/resource.box
, etc.) will
not be detected by vagrant-s3auth.
As shorthand, s3://
URLs will be automatically transformed. This is equivalent
to the above:
Vagrant.configure('2') do |config|
config.vm.box = 'simple-secrets'
config.vm.box_url = 's3://example.com/secret.box'
end
Note: Simple box URLs must end in .box
, or they'll be interpreted as
metadata boxes.
Boxes on Vagrant Cloud have support for versioning, multiple providers, and a GUI management tool. If you've got a box version on Vagrant Cloud.
Then just configure your Vagrantfile like normal:
Vagrant.configure('2') do |config|
config.vm.box = 'examplecorp/secrets'
end
Metadata boxes were added to Vagrant in 1.5 and power Vagrant Cloud. You can host your own metadata and bypass Vagrant Cloud entirely.
Essentially, you point your box_url
at a JSON metadata file
that tells Vagrant where to find all possible versions:
# Vagrantfile
Vagrant.configure('2') do |config|
config.vm.box = 'examplecorp/secrets'
config.vm.box_url = 's3://example.com/secrets'
end
"s3://example.com/secrets"
{
"name": "examplecorp/secrets",
"description": "This box contains company secrets.",
"versions": [{
"version": "0.1.0",
"providers": [{
"name": "virtualbox",
"url": "https://s3.amazonaws.com/example.com/secrets.box",
"checksum_type": "sha1",
"checksum": "foo"
}]
}]
}
Note: box URLs in metadata JSON must use the
s3.amazonaws.com/bucket.example.com/resource.box
URL form, or it won't get
auto-signed.
To sum up:
-
Only the
box_url
setting can use thes3://
shorthand. URLs entered on the Vagrant Cloud management interface and in JSON metadata must use the full HTTPS URL. -
The full HTTPS URL must be of the form
https://s3.amazonaws.com/bucket.example.com/resource.box
, or it won't be signed properly. -
Metadata box files must not end in
.box
. -
Actual box files must end in
.box
.
The beauty of Vagrant is the magic of "vagrant up
and done." Making your users
install a plugin is lame.
But wait! Just stick some shell in your Vagrantfile:
unless Vagrant.has_plugin?('vagrant-s3auth')
# Attempt to install ourself. Bail out on failure so we don't get stuck in an
# infinite loop.
system('vagrant plugin install vagrant-s3auth') || exit!
# Relaunch Vagrant so the plugin is detected. Exit with the same status code.
exit system('vagrant', *ARGV)
end