Vagrant の使い方まとめ

Vagrant は仮想マシンを実験できる素晴らしいツールです。
毎度毎度やりたいことを自分で掘り起こすのにつらみを感じてきたのでまとめました。
随時まとめていきます。
最近は Otto も出てきたのでそっちに移行したいですが。

ポートフォワーディングの設定

こんな感じでやると http://localhost:8888/ で 8080 でリッスンする仮想マシンにアクセスできます。

  config.vm.network "forwarded_port", guest: 8080, host: 8888

ブリッジしたい

DHCP

  config.vm.network "public_network"

IP 指定したい

サブネットごえするばあいは VM の中にデフォルトゲートウェイを指定してあげる必要があります。

  config.vm.network "public_network", ip: "192.168.0.17"

NIC を指定する

この場合上だけだと vagrant up するたびにブリッジする NIC を聞かれてうざいので、NIC を指定します。

  config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"

Vagrant box を指定する

僕はよく puppetlabs で提供されている
前までは chef で提供されているものを使ってたんですが、なくなりました。
ATLAS で探してみましょう。

puppetlabs | Atlas by HashiCorp

  config.vm.box = "puppetlabs/centos-7.2-64-nocm"

ATLAS ができる前は野良 Vagrant box を以下から拾ってきたり、セキュリティが気になる場合は Packer で自分で作る必要がありました。

A list of base boxes for Vagrant – Vagrantbox.es

スペックを指定したい(VirtualBox)

デフォルトだと 1 CPU の 2 GB の割当なので、コンピューティングリソースをもう少し増強したい場合は以下の様な指定をする。

  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "2", "--ioapic", "on"]
  end

複数の VM を立ち上げる

何も 1 台構成だけが脳じゃありません。
こんな 3 台構成もできる。

  config.vm.define "web" do |instance|
    instance.vm.box = "puppetlabs/centos-7.2-64-nocm"
    instance.vm.network :private_network, ip: "192.168.33.10"
  end

  config.vm.define "ap" do |instance|
    instance.vm.box = "puppetlabs/centos-7.2-64-nocm"
    instance.vm.network :private_network, ip: "192.168.33.11"
  end

  config.vm.define "db" do |instance|
    instance.vm.box = "puppetlabs/centos-7.2-64-nocm"
    instance.vm.network :private_network, ip: "192.168.33.12"
  end

Windows ユーザーが喜ぶ vagrant ssh の代わりに Tera Term を手軽に使える vagrant-teraterm プラグイン

私も 1 行だけコミットした vagrant-teraterm プラグインというのがあります。
vagrant ssh でもできるが、コマンドプロンプト内で Linux に入るという行為自体がキモい。
これ知る前は毎回 SSH のフォワーディングポート調べて Tera Term 手動で立ち上げて SSH してたんですが、
これで毎回フィンガープリントを確認される不自由から開放されます。
でも、正直 Mac のほうが使いやすいですよ。

vagrant plugin install vagrant-teraterm
vagrant up
vagrant teraterm

シェルプロビジョニングをする

Ansible や Chef を使うほどではないが、毎回立ち上げるたびにコマンドコチコチ入力するのも面倒だというときに一番強力なのがシェルプロビジョニングです。

  config.vm.provision "shell", inline: <<-SHELL
    sudo yum -y install epel-release
    sudo yum -y install --eneblerepo=epel nginx
  SHELL

ある程度出来上がった Vagrant の実行イメージを出力する

これはけっこう強力で、例えばLAN内のローカルミラーを参照するように設定したり、
例えば毎回 vagrant up するたびに Nginx や MySQL をインストールするのは正直だるいって時には vagrant package サブコマンドを使う。
Packer でがんばってやらなくてもいいのでお手軽でおススメ。

ある程度まとまった開発環境ができあがったらそれを他の開発者に配布するという使い方もできる。

vagrant package
rename package.box centos-7.2-x86_64-mysql-5.6.box
vagrant box add centos-7.2-x86_64-mysql-5.6 centos-7.2-x86_64-mysql-5.6.box

add し終わったら Vagrantfile の box 名指定するところにそれを指定して vagrant up すれば特定の役割を持った仮想マシンがいろんなミドルウェアを入れるオーバーヘッドがなくなるので楽ちんなのだ。

プライベートな Vagrant box Registry がほしいなあ。。。

参考リンク

  1. Documentation - Vagrant by HashiCorp
  2. 「hbstudy#60 SerfとConsulでシステム運用を楽しくしよう!」に行ってきました&Serf試してみました - 戦場のプログラマー
  3. RedHat 系 Linux のホスト名を設定する - 戦場のプログラマー
  4. vagrant teraterm が便利すぎてしょうがない件 - 戦場のプログラマー
  5. vagrant-digitalocean provider の簡単な使い方 - 戦場のプログラマー
  6. vagrant-digitalocean で vagrant up すると NoMethodError となる件 - 戦場のプログラマー
  7. Macでvagrant-omnibusプラグインのインストール中にnokogiriのインストールでコケるというお話 - 戦場のプログラマー

otto dev コマンドを使ってみた

新年一発目。
HashiCorp の集大成とも言えるべき Otto をインストールしてみた。

Otto とは

若干ググラビリティが低いのが難点。
これはすごく乱暴に言ってしまえば Vagrant の後継となるソフトウェアである。
Vagrant やら Consul やら Vault やら AWS やら GCP といったいろいろなものをシームレスに連携して統一世界を作るためのものらしい。
Mitchell Hashimoto 氏がここまで予見して Consul や Vault といったプロダクトをリリースしていたとしたら脱帽せざるを得ない。

otto 全般について触ってみた結果を載せられたらいいんだけど、何分時間も頭も足りないので全部は解説できない。
なので otto dev サブコマンドで起動、停止するだけの簡単なものを記録として残す。

さて、 otto dev サブコマンドは結論からいうと今のところ Vagrant なしには動かない。
バックエンドで Vagrant を使っている。
今後は Vagrant 自身も必要なくなって otto だけで動くようになってくれるのかな。
そうすると Vagrant の遅さを考えなくて良くなるのだろうか。

プロジェクトの作成

otto のプロジェクトを立ち上げるためには既存のソースだけ使うか、それとも Appfile という JSON 形式のファイルでどのような言語を使うかを指定してやることになる。
私はものぐさなので前者。
おそらく Vagrantfile に記述していたような複数VMを構成したり、秘伝のタレめいたシェルプロビジョニングを使いたい場合は Appfile に記述したのだろう。

ソースの用意

私は次のようなソースを用意した。

<?php
phpinfo();

otto compile

そしてそのディレクトリで otto compile する。
Appfile が見つからなければソースの内容をみてどの言語のプロジェクトか判断してくれるようだ。
この場合、リリースするインフラストラクチャは AWS が選択された。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto compile
==> Loading Appfile...
==> No Appfile found! Detecting project information...
No Appfile was found. If there is no Appfile, Otto will do its best
to detect the type of application this is and set reasonable defaults.
This is a good way to get started with Otto, but over time we recommend
writing a real Appfile since this will allow more complex customizations,
the ability to reference dependencies, versioning, and more.
==> Fetching all Appfile dependencies...
==> Compiling...
Application:    otto-php (php)
Project:        otto-php
Infrastructure: aws (simple)
Compiling infra...
Compiling foundation: consul
==> Compiling main application...
==> Compilation success!
This means that Otto is now ready to start a development environment,
deploy this application, build the supporting infrastructure, and
more. See the help for more information.
Supporting files to enable Otto to manage your application from
development to deployment have been placed in the output directory.
These files can be manually inspected to determine what Otto will do.

ローカル開発環境の立ち上げ

otto dev

満を持して vagrant up に相当するコマンドを叩く。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev
Would you like Otto to install Vagrant?
Otto requires vagrant to be installed, but it couldn't be found on your
system. Otto can install the latest version of vagrant for you. vagrant
will be installed system-wide since it uses system-specific installers.
Would you like Otto to install vagrant for you? Alternatively, you may install
this on your own.
If you answer yes, Otto will install vagrant version 1.8.1.
Please enter 'yes' to continue. Any other value will exit.
Enter a value:
Error building dev environment: Installation cancelled

otto dev は vagrant がインストールされていないと動かないらしい、もしくは otto 全体でそうなんだろうか。
あなたがお望みなら自動でシステムワイドでインストールしてやるぜ?といっているが、ここは yes 以外の適当なキーを押して抜けて自力で Vagrant をインストールする。

また vagrant を Web サイトからいちいちダウンロードするのは果てしなくだるいので、 otto にまかせてしまってもいいのかもしれない。
Mac の場合は Homebrew Cask がインストールされていればコマンド一発でインストールできる。
まあ、 sudo 権限が必要なのでパスワードは要求されるが・・・。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ brew cask install vagrant
==> Downloading https://releases.hashicorp.com/vagrant/1.8.1/vagrant_1.8.1.dmg
######################################################################## 100.0%
==> Verifying checksum for Cask vagrant
==> Running installer for vagrant; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are i
Password:
==> installer: Package name is Vagrant
==> installer: Installing at base path /
==> installer: The install was successful.
🍺  vagrant staged at '/opt/homebrew-cask/Caskroom/vagrant/1.8.1' (6 files, 85M)

仕切り直して改めて otto dev

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev
==> Creating local development environment with Vagrant if it doesn't exist...
Raw Vagrant output will begin streaming in below. Otto does
not create this output. It is mirrored directly from Vagrant
while the development environment is being created.
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
default: URL: https://atlas.hashicorp.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'hashicorp/precise64' is up to date...
==> default: Setting the name of the VM: dev_default_1451618455051_6865
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 4.2.0
default: VirtualBox Version: 5.0
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
default: /vagrant => /Users/wnoguchi/Documents/pjt/otto/otto-php
default: /otto/foundation-1 => /Users/wnoguchi/Documents/pjt/otto/otto-php/.otto/compiled/app/foundation-consul/app-dev
==> default: Running provisioner: shell...
default: Running: inline script
==> default: stdin: is not a tty
==> default: [otto] Installing Consul...
==> default: [otto] Installing dnsmasq for Consul...
==> default: [otto] Configuring consul service: otto-php
==> default: Running provisioner: shell...
default: Running: inline script
==> default: stdin: is not a tty
==> default: [otto] Adding apt repositories and updating...
==> default: [otto] Installing PHP and supporting packages...
==> default: [otto] Installing Composer...
==> default: #!/usr/bin/env php
==> default: All settings correct for using Composer
==> default: Downloading...
==> default:
==> default: Composer successfully installed to: /tmp/composer.phar
==> default:
==> default: Use it: php composer.phar
==> Caching SSH credentials from Vagrant...
==> Development environment successfully created!
IP address: 100.79.109.82
A development environment has been created for writing a PHP app.
Edit files locally on your machine, the file changes will be synced
to the development environment automatically.
To run and view your application, run 'otto dev ssh' to enter the
development environment. You'll be placed directly into the working
directory where you can run "composer", "php", etc.
You can access the environment from this machine using the IP address above.
For example, if you start your app with 'php -S 0.0.0.0:5000', then you can
access it using the above IP at port 5000.

このログメッセージを見ればわかるが、 Consul もインストールされ、PHP ではもはや必須となった Composer までよろしくインストールしてくれている。
composer.json まで入れたらいい感じにインストールしてくれるんだろうか。
仮想マシンUbuntu の precise64 が選択されている。
ここも詳細に指定したいな。

開発環境として 100.79.109.82 という IP が与えられたので、さっそくホスト OS からブラウザでアクセスしてみる。
「データを受信していません」となった。どうも環境の AP サーバは自力で開発環境に入り、立ち上げてやる必要があるらしい。

いつものくせで vagrant ssh としてしまったら

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ vagrant ssh
A Vagrant environment or target machine is required to run this
command. Run `vagrant init` to create a new Vagrant environment. Or,
get an ID of a target machine from `vagrant global-status` to run
this command on. A final option is to change to a directory with a
Vagrantfile and to try again.

vagrant init せえよアホンダラア!!って怒られてしまった。
およそ otto dev ssh とでもするんだろう。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev ssh
==> Executing SSH. This may take a few seconds...
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)
* Documentation:  https://help.ubuntu.com/
New release '14.04.3 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:23:18 2012 from 10.0.2.2
vagrant@precise64:/vagrant$ cd /vagrant/
vagrant@precise64:/vagrant$ ls
phpinfo.php

入れた。

vagrant@precise64:/vagrant$ php -S 0.0.0.0:5000
PHP 5.6.16-2+deb.sury.org~precise+1 Development Server started at Fri Jan  1 03:27:21 2016
Listening on http://0.0.0.0:5000
Document root is /vagrant
Press Ctrl-C to quit.
[Fri Jan  1 03:27:40 2016] 100.79.109.1:51305 [200]: /phpinfo.php
[Fri Jan  1 03:27:41 2016] 100.79.109.1:51306 [404]: /favicon.ico - No such file or directory

そしてブラウザから 5000 番ポートを叩く。

f:id:wnoguchi0727:20160101132031p:plain

見れた。

さらにアクセス元のリモートIPアドレスを取得するサンプルも書いてみた。
開発環境にはすぐに同期される。

<?php
echo $_SERVER['REMOTE_ADDR'];

そしてブラウザで見る。

f:id:wnoguchi0727:20160101133202p:plain

見れた。

じゃあシャットダウン。これもサブコマンドで otto dev halt だろうと予想がつく。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev halt
==> Halting the the local development environment...
==> default: Attempting graceful shutdown of VM...
==> Development environment halted!

シャットダウンできた。

知らない IP アドレスだ…

ipduh によるとこの IP アドレスは

http://ipduh.com/ip/?100.79.109.82

100.79.109.82 is in the 100.64.0.0/10 block which is reserved to be used as Shared Address Space to accomodate the need of Carrier-Grade NAT (CGN) devices. It is anticipated that Service Providers will use this Shared Address Space to number the interfaces that connect CGN devices to Customer Premises Equipment (CPE). [ RFC 6598 ]

Integer: 1682926930

のように Carrier-Grade NAT デバイスが Customer Premises Equipment(CPE) に接続するための共有アドレス空間として 100.64.0.0/10 は予約されているらしい。
グローバル IP アドレス空間をむやみに汚染しているわけではないらしい。

これを見る限り CGN はグローバル IPv4 アドレス枯渇問題をとりあえず回避するために ISP が共有NATアドレス空間を定義したことがことの始まりであり、この RFC 定義空間をよろしく使っているのが otto dev になるようだ。

References

  1. Hashicorp Ottoを読む | SOTA
  2. HashiCorpの新プロダクトNomadとOttoを触ってみた | Developers.IO
  3. Hashicorp社の新しい仮想開発環境”Otto”でAppfileを記述してみた – FPGA開発日記

vagrant teraterm が便利すぎてしょうがない件

Windows 使っていると vagrant up したあとに仮想マシンにアクセスするのにコマンドプロンプトのログに流れた SSH のフォワーディングポートを読んで、 vagrant が自動生成した秘密鍵を指定して Tera Term で接続して・・・っていう流れをやっていたんだけど、さすがに馬鹿らしくなってしまった。
Mac じゃないからコマンドプロンプトvagrant ssh するのも微妙だし・・・。

Vagrant 仮想マシンに接続する TeraTerm マクロを吐き出すプラグイン(Gem) を書いたわけです。
vagrant ssh-configTeraTermvagrant-ssh-config-ttl 初の Gem 製作。

しかしながらそれでも複数VM取り扱ったりするとやっぱり大変。
と思っていたら vagrant-teraterm という素晴らしいプラグインが開発されていました。

  1. tiibun/vagrant-teraterm
  2. Windows – VagrantにTeratermマクロで接続する – Qiita
  3. Vagrant Teraterm pluginを作ってみた – Qiita

インストール

いたって簡単、

vagrant plugin install vagrant-teraterm

設定

デフォルトのインストールパスに Tera Term がインストールされていればとくに設定はいりません。
vagrantteraterm プラグインがよしなにやってくれます。

使い方

vagrant up したら以下のようにすると自動的に TeraTerm が対象の VM に繋いでくれます。

vagrant teraterm

複数VM を立ち上げている場合

以下のように VM 名を指定してあげればいいです。

vagrant teraterm vm1

ちなみに、最初は vagrant teraterm する際にフィンガープリントの検証で引っかかっていたので、 StrictHostKeyChecking no に相当する /nosecuritywarning を孵化するPR 投げて取り込んでもらいました。嬉しい。

蛇足

最近 HashiCorp から Otto という Vagrant の後継となるソフトウェアがリリースされました。
以前は Chef をよく使っていたのですが、 Vagrantfile のシェルプロビジョニングがお手軽すぎてダメ人間になってしまっています。
そしてこれも秘伝のタレ化すると。
その秘伝のタレ化する Vagrantfile をなんとかしてくれるのが Otto らしいです。
これも早めにいじってみたいなあ。

  1. Otto by HashiCorp
  2. Otto – HashiCorp
  3. Hashicorp Ottoを読む | SOTA

vagrant-digitalocean provider の簡単な使い方

次のような Vagrantfile を用意します。

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure('2') do |config|
config.vm.provider :digital_ocean do |provider, override|
override.ssh.private_key_path = '~/.ssh/digitalocean-vagrant'
override.vm.box = 'digital_ocean'
override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
provider.token = ''
provider.image = 'CentOS 6.5 x64'
# San Francisco 1
provider.region = 'sfo1'
provider.size = '512mb'
end
end

前提条件としては

  • Apps & API メニューで Personal Access Tokens を生成すること。Read, Write アクセス付与。
  • Vagrant という名前の秘密鍵が登録されていること。
  • ~/.ssh/digitalocean-vagrant と対になる公開鍵 ~/.ssh/digitalocean-vagrant.pub が存在すること。
  • 選択されているリージョンは San Francisco 1 (slug名になっている)。

ちなみに現在のリージョンとslug名の対応は以下のようになっている。

slug Region Name
nyc1 New York 1
ams1 Amsterdam 1
sfo1 San Francisco 1
nyc2 New York 2
ams2 Amsterdam 2
sgp1 Singapore 1
lon1 London 1
nyc3 New York 3

調べ方はさっきのパーソナルトークンを指定して以下の様な curl コマンドを発行すればいいです。
jq でフィルタリングしてます。

curl -X GET "https://api.digitalocean.com/v2/regions" \
-H "Authorization: Bearer $DIGITAL_OCEAN_TOKEN" \
2>/dev/null | jq '.regions [] | .slug,.name'

EC2 と違って Droplet が存在しているだけで課金対象になるので用が済んだらすぐに

vagrant destroy -f

References

  1. VagrantとSSDなVPS(Digital Ocean)で1時間1円の使い捨て高速サーバ環境を構築する – Glide Note – グライドノート
  2. jq コマンドが強力すぎてヤバい件 | CUBE SUGAR STORAGE
  3. DigitalOcean API

vagrant-digitalocean で vagrant up すると NoMethodError となる件

以下の様なエラーとなります。

% vagrant up --provider=digital_ocean
Bringing machine 'default' up with 'digital_ocean' provider...
==> default: Using existing SSH key: Vagrant
==> default: Creating a new droplet...
/Users/wnoguchi/.vagrant.d/gems/gems/vagrant-digitalocean-0.6.2/lib/vagrant-digitalocean/actions/create.rb:37:in `call': undefined method `first' for nil:NilClass (NoMethodError)
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Users/wnoguchi/.vagrant.d/gems/gems/vagrant-digitalocean-0.6.2/lib/vagrant-digitalocean/actions/setup_key.rb:33:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builder.rb:116:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `block in run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/util/busy.rb:19:in `busy'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builtin/call.rb:53:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builtin/config_validate.rb:25:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builder.rb:116:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `block in run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/util/busy.rb:19:in `busy'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:196:in `action_raw'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:173:in `block in action'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/environment.rb:434:in `lock'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:161:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:161:in `action'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/batch_action.rb:82:in `block (2 levels) in run'

DigitalOcean API V2 は Public Beta なので仕様が変わったためのようです。

Public Beta
Due to the large number of changes to API v2 we have decided to release it as a beta to collect user feedback. Please note that >during this period based on user feedback we may make some large changes which may break compatibility.

DigitalOcean API

このあたりは以下の Issue とプルリクで修正方法が確立されているので早く本家にマージされてほしいです。

とりあえずなんとかしたい方は対処療法的には

~/.vagrant.d/gems/gems/vagrant-digitalocean-0.6.2/lib/vagrant-digitalocean/actions/create.rb

の 37 行目を

          @client.wait_for_event(env, result['droplet']['action_ids'].first)
# ↓
@client.wait_for_event(env, result['links']['actions'].first['id'])

とすればいいです。