mizoguche.info

VagrantでAWSのインスタンスのプロビジョニング

AWS 触って慣れたいんで、Jenkins と GitLab が入ったプライベートな開発環境を AWS につくってました。

で、 t1.micro で Jenkins 動かしてたら CPU 利用率が 100% 近くに張り付いたまま反応しなくなったので、思い切って m1.small なインスタンスを立ち上げました。奮発しすぎ感あるけど、使わな勿体無い感出して自分を追い込む作戦。

あんまり使ってなかったので、この際と思って Vagrant 使ってイチから環境を作りなおしました。

やったこと

  1. 必要になりそうなプラグインのインストール
  2. CentOS でレシピの設定
  3. AWSで立ち上げる

必要になりそうなプラグインのインストール

ざっくり調べて必要になりそうなVagrantのプラグインを入れます。Chef と Berkshelf はもともと入ってる感じです。

$ vagrant plugin install vagrant-omnibus
$ vagrant plugin install vagrant-berkshelf
$ vagrant plugin install vagrant-aws

CentOS でレシピの設定

必要な cookbook を書いた Berksfile をつくって、下記のような Vagrantfile をつくります。

VAGRANTFILE_API_VERSION = 2
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "centos64"
  config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v0.1.0/centos64-x86_64-20131030.box"

  config.vm.provider :virtualbox do |vb|

    vb.customize ["modifyvm", :id, "--memory", "1024"]

    vb.customize ["modifyvm", :id, "--natdnsproxy1", "off"]
    vb.customize ["modifyvm", :id, "--natdnshostresolver1", "off"]

  end

  config.omnibus.chef_version = :latest
  config.berkshelf.enabled = true

  config.vm.provision :chef_solo do |chef|
    chef.verbose_logging = true

    chef.cookbooks_path = "cookbooks"
    chef.data_bags_path = "data_bags"

    chef.json = {
          rbenv: {
                  rubies: ["2.1.0"],
                  global: "2.1.0",
                  gems: { "2.1.0" => [ {name: "bundler"} ] }
                 },
          ...
        }
    chef.run_list = [
              "ruby_build",
              "rbenv::system",
              ...
            ]
  end

end

chef.jsonnode/ .json の attributes、chef.run_list に run_list をそれぞれ設定して、$ vagrant up すると勝手に $ berks install とかもやってくれてます。ログ見てる限り。

下記の部分は$ bundle installのタイムアウト対策です。ネットワーク不調を解消できそう。

  vb.customize ["modifyvm", :id, "--natdnsproxy1", "off"]
  vb.customize ["modifyvm", :id, "--natdnshostresolver1", "off"]

これやったら $ bundle install がタイムアウトしなくなりました。60分経っても終わらないっておかしいと思ってた。

AWSで立ち上げる

で、下記の感じで AWS 用の設定を追加して$ vagrant up --provider=awsするだけで AWS のインスタンスが立ち上がります。簡単すぎて怖い!

  config.vm.box = "dummy"
  config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id     = "アクセスキー"
    aws.secret_access_key = "シークレット"
    aws.keypair_name = "キーペア名"
    aws.instance_type = "m1.small"
    aws.region = "ap-northeast-1"
    aws.ami = "イメージ名"
    aws.security_groups = [ 'セキュリティグループ名' ]

    override.ssh.username = "ec2-user"
    override.ssh.private_key_path = "~/.ssh/キーペアファイル名"
  end

  config.ssh.pty = true

AWS なんでボックスのイメージとかいらないんですけど、 config.box を設定しないと Vagrant さんが死んじゃうそうなので、ダミーのボックスを設定する必要があるそうです。

sudo: sorry, you must have a tty to run sudo

最初、プロビジョニングが始まったら sudo: sorry, you must have a tty to run sudo と言われて死んでたのですがこれは /etc/sudoersDefaults requiretty て設定が原因だったのでちょこちょこ書き換えたイメージを作ってプロビジョニングしてました。が、そんな必要はなかった

あんまりクラッキング対策になってないよなーと思って調べてるうちに、 Vagrantfileconfig.ssh.pty = trueてしたらいいよ的なことが stackoverflowにありました。さすが我らが stackoverflow さん。

ちなみに config.ssh.pty というパラメータが追加されたのは2013年12月リリースの Vagrant のバージョン 1.4.0 からだそうで、ドキュメントにもまだ載ってないよって言ってはる。だから stackoverflow の回答者たちはこういう情報どうやって知ってるんだっていういつものアレです。

まとめ

ローカルの CentOS でレシピと設定をテストして、AWS のインスタンス立ち上げるという一連の流れを、仮想環境を抽象化することで便利すぎる感じに仕上がってます。

まぁ結局レシピの設定とテストが一番時間かかるんですけどね!