こんにちは。ランチコンダクターです。
先日、第8回若手Webエンジニア交流会 #wakatewebにて 「vagrant-awsにプルリしたらマージされた話」をさせていただきました。
今回は、vagrant-awsの具体的な使い方をまとめてみます。
vagrant-awsとは
通常、VagrantはVirtualBoxのコントローラーとして使われていると思いますが、バージョン1.1からプラグインを使用することにより、様々な仮想化技術に対応した仮想マシンのコントローラーとなりました。
vagrant-awsは、VagrantでAWSを操作することができるようになるプラグインです。図で表すと以下のような感じになります。
AWSにて準備事項
事前準備としてAWS側での準備が必要なのですが、ここでは省略します。
とりあえず、以下を行っておけば最低限は大丈夫だと思います。
- access_key_idをメモっておく
- secret_access_keyをメモっておく
- keypairを作成し、名前をメモっておく
- 指定するsecurity_group名をメモっておく
- sshのprivate_keyのダウンロードを行い、保持
vagrant-aws
事前準備
# vagrant aws プラグインのインストール $ vagrant plugin install vagrant-aws # ダミーのboxファイルを追加(Vagrantの起動にはBoxファイルが必ず必要なため) $ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
vagrant-awsのVagrantfileを解説
VAGRANTFILE_API_VERSION = "2" # 実行するShellScript $script = <<SCRIPT # echo 'Start ShellScript' # タイムゾーンを日本に変更 sudo cp -p /usr/share/zoneinfo/Japan /etc/localtime # AWSのVolumeのリサイズ(デフォルトだと8GBのため) sudo resize2fs /dev/sda1 SCRIPT Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # Box名(vagrant-awsでは使用はしないが指定しなくてはならない) config.vm.box = "dummy" # 同期するフォルダを選択(vagrant-awsでは常に同期される訳ではなく、provisionやupなどのコマンド実行時に同期される) config.vm.synced_folder "./", "/home/ec2-user/vagrant", disabled: true config.vm.provider :aws do |aws, override| # アクセスキー(リポジトリに入れたいので環境変数に保持) aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] # シークレットアクセスキー(リポジトリに入れたいので環境変数に保持) aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] # キー名 aws.keypair_name = 'speee.key' # インスタンスタイプ(http://aws.amazon.com/jp/ec2/pricing/ を参照) aws.instance_type = "t1.micro" # リージョン(東京はap-northeast-1) aws.region = "ap-northeast-1" # アベイラビリティゾーン aws.availability_zone = "ap-northeast-1c" # 使用するAMIのID aws.ami = "ami-c9562fc8" # セキュリティグループ(複数指定でor判定) aws.security_groups = ['web-server-group'] # タグ aws.tags = { 'Name' => 'web-server', 'Description' => '詳細' } # Amazon Linuxの場合は最初からsudoできないので指定しておく aws.user_data = "#!/bin/sh\nsed -i 's/^.*requiretty/#Defaults requiretty/' /etc/sudoers\n" # EBSの指定が可能 aws.block_device_mapping = [ { # デバイス名 'DeviceName' => "/dev/sda1", # 名称 'VirtualName' => "v1", # ボリュームサイズ(GB単位) 'Ebs.VolumeSize' => 10, # ターミネートした際に削除するかどうか 'Ebs.DeleteOnTermination' => true, # EBSのタイプを指定 'Ebs.VolumeType' => 'standard', #'Ebs.VolumeType' => 'io1', # standardでIOPSを指定するとエラーが発生するので注意 #'Ebs.Iops' => 1000 } ] # ----- # ここからはVPCを使用する際の設定 # サブネットID(マネジメントコンソールから取得) #aws.subnet_id = 'サブネットID' # VPC内のローカルIPアドレスを指定 #aws.private_id_address = '192.168.0.33' # 自動的にEIPを割り当てる場合(EIPの取得上限は5個のためそれ以上の指定はエラーとなる) # aws.elastic_ip = true # ELBを指定 # aws.elb = "production-web" # ----- # SSHのユーザー名を指定(Amazon Linuxはec2-user、ubuntuはubuntu、CentOSはroot) override.ssh.username = "ec2-user" # SSHのKeyのパスを指定 override.ssh.private_key_path = "~/.ssh/speeekey.pem" end # シェルを実行 config.vm.provision "shell", inline: $script end
実際に使用する際の変更点は以下になります。
aws.access_key_id:AWSから取得したアクセスキーに変更、もしくは環境変数に設定※1
aws.secret_access_key:AWSから取得したシークレットアクセスキーに変更、もしくは環境変数に設定※1
aws.keypair_name:AWSにて作成したキーペア名に変更※1
aws.instance_type:任意のインスタンスに変更(試すだけならt1.microで問題無し)※1
aws.region:任意のリージョンを指定※1
aws.availability_zone:任意のアベイラビリティゾーンを指定※1
aws.ami:任意のAMIを指定※1
aws.security_groups:AWSにて作成したセキュリティグループを指定※1
aws.tags:タグを指定(タグに意味はありません)
aws.block_device_mapping:マッピングを行うデバイスを指定(EBSなど)
aws.subnet_id:VPCを使用する場合は指定
aws.private_id_address:VPCを使用する場合は指定
aws.elastic_ip:固定IPが必要な時に指定
override.ssh.username:OS毎に指定※1
override.ssh.private_key_path:プライベートKeyを配置しているローカルのPathを指定※1
※1:必須
実行
以下にて起動、破棄が行えます。
# EC2インスタンスの起動 $ vagrant up --provider=aws # EC2インスタンスの破棄 $ vagrant destroy
vagrant実行時にデバッグログの出力を行う方法
以下のように、VAGRANT_LOG=debugをとすることにより、ログが多く出力されるので、問題が起こった際の解決がしやすくなります。
# vagrant up時にデバッグログを出力 $ VAGRANT_LOG=debug vagrant up # vagrant destroy時にデバッグログを出力 $ VAGRANT_LOG=debug vagrant destroy
vagrant-awsをソースから実行するための手順
ソースを取得
$ git clone https://github.com/mitchellh/vagrant-aws $ cd vagrant-aws
Gemfileを以下のように変更
source "https://rubygems.org" gemspec group :development do # We depend on Vagrant for development, but we don't add it as a # gem dependency because we expect to be installed within the # Vagrant environment itself using `vagrant plugin`. gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git" end group :plugins do gem "vagrant-aws", path: "." end
Gemのインストール
$ bundle $ bundle exec rake
あとは先ほどのVagrantfileを配置し、「bundle exec vagrant up --provider=aws」を行えばec2インスタンスが起動されます。
# 起動 $ bundle exec vagrant up --provider=aws # ターミネート $ bundle exec vagrant destroy
ソースコードから実行した時のコマンド一覧(bundle execつけただけ)
# 起動 $ bundle exec vagrant up --provider=aws # 終了 $ bundle exec vagrant destroy # rsync(ローカルからEC2への一方通行のため、注意) $ bundle exec vagrant rsync # provision(rsyncしてからShellやChef等を実行) $ bundle exec vagrant provision # 再起動 $ bundle exec vagrant reload # 停止 $ bundle exec vagrant halt
vagrant-awsのAWSの操作はfogを使用しています。fogだけを使いたいときもvagrant-awsのコードはかなり参考になるとおもいます。
ちなみにvagrant-google(Google Compute Engineを操作)というプラグインもあります。vagrant-googleもfogを使用しているのでコードベースはかなり似ています(作者が同じなので当然ですが)。
Tips
# ※vagrant-awsにてvagrant up後 $ cat .vagrant/machines/default/aws/id i-4ed31657
vagrant-awsを使う時にあると便利なプラグイン
vagrant-ami
このプラグインを使用することにより、vagrant-awsで作成したインスタンスのami化ができるようになります。
# インストール $ vagrant plugin install vagrant-ami
# インスタンスをAMI化 $ vagrant create-ami --name my-ami-name --desc "My AMI" --tags role=test,environment=dev
最後に
Infrastructure as CodeとAWSを使ったImmutable Infrastructureを実現するためには、
AWSのインスタンス起動 → Chef or Puppet or Ansibleを実行 → serverspecにてテストというフローを 繰り返し実行していくことになりますが、このフローを自作するのはそれなりの手間がかかります。
vagrant-awsや、その他のvagrantプラグインを組み合わせると、このフローをVagrantfileで管理でき、 かつ簡単に自動化できます。
また、インターフェイスが同じなので、Vagrantさえ知っていれば学習コストをある程度抑えられるのも 導入コストを抑えられるので良いですね。
機能の便利さの割に使われていないのが勿体無いと思っているので、皆さん、どんどん使いましょう!
※vagrant-awsを使用してserverspecのテストを行う運用方法などについては
以下のスライドが参考になると思います。
DevOps + AWS #jawsug by Naoya Ito
KAIZEN platform Inc. における運用自動化 by Naoya Ito
日本一詳しくなかったらすみませんw
ありがとうございました。