LoginSignup
18
19

More than 5 years have passed since last update.

VagrantによるEC2インスタンスの作成

Posted at

1.はじめに

過去2回の記事はiOSのCoreLocationをメインに記事を書いていましたが、やはりアプリと連携するサーバーも欲しい!というわけで久しぶりにVagrat+Chefによるサーバー構築の記事でも。
本稿では、Vagrant+vagrant-awsプラグインを使ってEC2インスタンスを作り、且つ、Chefを利用してプロビジョンを行ないたいと思います。

  • 本稿範囲:
    • Vagrant+vagrant-awsプラグインによるEC2インスタンスの作成
    • Chefによるプロビジョン(Apache+Tomcat7のinstallとajpによる連携)
  • 対象読者:Vagrant、Chef Solo、AWSについて多少の知識のある方
  • 開発環境:OS X Mavericks v10.9.4

  • Vagrant:Ver 1.6.2

  • Chef:Ver 11.12.4

  • vagrant-aws:Ver 0.5.0

2. 何故、VagrantでEC2インスタンスを管理するのか?

VagrantでEC2のインスタンスの管理を行なう理由とは何でしょうか。
既にAWSには、GUIベースの立派な管理コンソールが存在します。
敢えて、Vagrantfileを書いたり、Recipeを書いたりと面倒くさい事をする理由は何なのでしょうか?
それはやはり、インスタンス作成の手順を誰もが再利用できる形で残し、共有できる事にあるのではないでしょうか。
例えば、AWSの管理コンソールからインスタンスを作ろうとすると管理コンソールを操作する人のスキルによって結果にぶれが生じます。
たとえ同じ人が同じEC2インスタンスを構築するにしても操作ミスから微妙に違ったインスタンスを作ってしまう可能性もあります。
が、コードという形で残して共有しておけば誰がやっても常に同じ結果を得る事が出来る訳です。
EC2インスタンスを作成するうえでの属人性の排除、これがVagrantによるEC2インスタンスの管理する最大の理由になるのかなと思います。

3. 事前準備 - AWS

VagrantやChefの設定ファイルを書き始める前にいくつか済ませておくべき事があります。
まずは、AWSのアカウントを作成しコンソールにログインして、予め作成しておくべきものを作成しておきましょう。
VagrantによるEC2インスタンス管理を行なうことは、AWS管理コンソールから直接操作を行なうのと比較して、どのようなメリットがあるのか。

3.1. AWSアカウントを作る

AWSアカウントをお持ちでない場合は、AWSアカウントを作ります。
http://aws.amazon.com/jp/

3.2. Access Key ID + Secret Access Key

AWSにSignInしたら画面右上にあるメニューから、「Security Credentials」を選択します。
「Your Security Credentials」という見出しの画面へ遷移しますので、「Access Keys (Access Key ID and Secret Access Key)」を開いて「Create New Access Key」ボタンを押下してAccessKeyを作成します。
この時、「Access Key ID」と「Secret Access Key」を控えておきます。
security_credentials.png

3.3. EC2管理コンソール

EC2管理コンソール画面へ遷移し、Asia Pacific(Tokyo)を選択します。
ec2_m_console.png

3.4. Key Pair作成

画面左のメニューから「NETWORK & SECURITY -> Key Pairs」を選択します。
「Create Key Pair」ボタンを押下するとダイアログが開きますので適当なKey pair nameを入力して、Createします。
key_pair.png

秘密鍵ファイルがDownloadされますので、どこか適当な場所に保管しておきましょう。
(例えば、"~/.ssh/"の下などに。)

3.5. Security Group作成

EC2管理コンソール左側のメニューから「NETWORK & SECURITY -> Security Groups」を選択します。
「Create Security Group」ボタンを押下するとダイアログが開きますので「Security group name」、「Description」を入力します。
ダイアログの「Security group rules」のInboudタブを選択しAdd Ruleをします。
SSHとHTTPによるアクセスを許可するので、この2つを追加します。
security_groups.png

4. Vagrant

4.1. vagrant-awsプラグインをインストール

まずはvagrant-awsプラグインをインストールします。
これはVagrantからAWSプロバイダを使用するのに必要なプラグインです。
ターミナルから、以下のようにコマンドを打ちます。

$ vagrant plugin install vagrant-aws

4.2. dummy boxの追加

プラグインをインストールしたら次は、dummyのboxを追加します。
ターミナルから以下のようにコマンドを打ちます。

$ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

4.3. Vagrantfileの編集

適当なディレクトリを作成してvagrant initとコマンドを打ち、Vagrantfileを作り以下のように編集します。
(Access Key IDやSecret Access Key、key pair name等は上述の手順で作成したものに適宜置き換えて下さい。)

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.box = "dummy"  # 追加したdummy boxを使用

    config.vm.provider :aws do |aws, override|
        aws.access_key_id = "xxxxxxxxxx"  # 手順3.2.で作ったAccess Key ID
        aws.secret_access_key = "xxxxxxxxxxxxxxxxxxxxx"  # 手順3.2.で作ったSecret Access Key
        aws.keypair_name = "xxxxxxxxxx"  # 手順3.4.で作ったKey Pair Name

        aws.region = "ap-northeast-1"   # Tokyoリージョン
        aws.ami = "ami-29dc9228"        # AMIのID
        aws.instance_type = "t2.micro"

        aws.security_groups = ["xxxx"]  # 手順3.5.で作ったSecirity Group Name
        aws.tags = {"Name" => "vagrant-test"} # 任意のタグ名

        override.ssh.username = "ec2-user"  # SSHでログインする際のユーザー名
        override.ssh.private_key_path = "~/.ssh/xxxxxxxxxx.pem" # 手順3.5.のKey Pair作成時にダウンロードした秘密鍵ファイルのパス
    end
end

4.4. 環境変数を利用する

上述のVagrantfileだとaws.access_key_idやaws.secret_access_keyがファイル内にべた書きされていました。
とりあえずの技術検証のみであれば、これでもさして問題ではないでしょうが実際に運用するのであればべた書きは避けたいところ。
環境変数にべた書きしたくない情報を持たせておく事も可能です。~/.bash_profile等に以下のように書き加えてみる方法もあります。
一例としてAWS_ACCESS_KEY_IDとAWS_SECRET_KEYを環境変数へ持つようにします。

~/.bash_profile
export AWS_ACCESS_KEY_ID=xxxxxx
export AWS_SECRET_KEY=xxxxxxxxxxxxxxxxxxx

この場合、Vagrantfileは以下のように書きます。(一部抜粋)

aws.access_key_id = ENV['AWS_ACCESS_KEY_ID']
aws.secret_access_key = ENV['AWS_SECRET_KEY']

5. EC2インスタンスを作る

ここまででVagrantからEC2インスタンスを起動する為に必要な作業は一通りできています。
それでは、実際にVagrantからEC2インスタンスを起動します。

5.1. vagrant up

それでは、vagrant upしてみましょう。awsプロバイダを使用するので--provider=awsとします。

$ vagrant up --provider=aws

 :
 :
(省略)
 :
 :
==> default: Rsyncing folder: /Users/nakagawadaisuke/test-vagrant-aws/ => /vagrant
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mkdir -p '/vagrant'

Stdout from the command:



Stderr from the command:

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

しばらく待っていると最後に何やらエラーが出ました、が、EC2インスタンスの起動は出来ています。
EC2管理コンソールからインスタンスが起動しているか確認しましょう。
aws.tags = {"Name" => "vagrant-test"}で、指定したタグ名のインスタンスが起動していますか?

5.2. SSHでログイン

次にvagrant sshでログインできるか試してみます。

$ vagrant ssh

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/
9 package(s) needed for security, out of 28 available
Run "sudo yum update" to apply all updates.
$ 

このような感じで無事にログインできましたでしょうか?

5.3. sudoersファイルの編集

ログインしたついでに、vagrant up時に出ていたエラーを解消しましょう。

sudo付きのコマンドを発行したもののsudoコマンドの設定制限に引掛かっているのが原因です。
sudoersファイルを編集し、原因の1行をコメントアウトします。

$ sudo visudo

Defaults    requiretty  # この行をコメントアウト

6. Chef - インフラ自動構築のコードを書く

せっかくなので立ち上げたEC2インスタンスをプロビジョンしてみましょう。
Vagrantは、プロビジョナーとしてChefとPuppetを使用する事ができます。
今回はChefを使用してプロビジョンを行ないます。

6.1. vagrant-omnibusプラグインのインストール

Chefを使用してプロビジョンを行ないます、のでvagrant-omnibusプラグインをインストールします。
このプラグインは、仮想マシン起動時にChefが存在しなければChef(Client)をインストールしてくれます。

EC2からログアウトして、ターミナルから以下のようにコマンドを打ちます。

$ vagrant plugin install vagrant-omnibus

6.2. Apache用Cookbookの作成

まずはApache用にCookbookを作ります。
Vagrantfileが置いてあるディレクトリで以下のようにコマンドを打ちます。

$ knife cookbook create apache -o cookbooks

それではレシピを書いていきます。

cookbooks/apache/recipes/default.rb
package "httpd" do
  action :install    # httpdパッケージをinstall
end

service "httpd" do
  action [ :enable, :start ]    # httpdを有効にし開始する
  supports :status => true, :restart => true, :reload => true # サポートするアクションの定義
end

6.3. Tomcat用Cookbookの作成

こちらもApacheと同様にCookbookを作ります。

$ knife cookbook create tomcat7 -o cookbooks

そして、recipeを書きます。

cookbooks/tomcat7/recipes/default.rb
package "tomcat7" do
    action :install    # tomcat7パッケージをinstall
end

service "tomcat7" do
    action [ :enable, :start ]    # tomcat7を有効にし開始する
    supports :status => true, :restart => true, :reload => true    # サポートするアクションの定義
end

package "tomcat7-docs-webapp" do
    action :install    # 動作確認用にドキュメントWebappもinstallしておく
end

7. provision

前項でApachとTomcatをinstallして起動するのみのcookbookとrecipeを作りました。
それでは実際に動かしてみましょう。

7.1. Vagrantfileの追記

Vagrantからプロビジョンするよう、Vagrantfileを修正していきます。

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.box = "dummy"
    config.omnibus.chef_version = :latest    # [追記]vagrant-omnibusでChefをInstall

    config.vm.provider :aws do |aws, override|
        aws.access_key_id = ENV['AWS_ACCESS_KEY_ID']
        aws.secret_access_key = ENV['AWS_SECRET_KEY']
        aws.keypair_name = "xxxxxxxxxx"

        aws.region = "ap-northeast-1"
        aws.ami = "ami-29dc9228"
        aws.instance_type = "t2.micro"

        aws.security_groups = ["xxxx"]
        aws.tags = {"Name" => "vagrant-test"}

        override.ssh.username = "ec2-user"
        override.ssh.private_key_path = "~/.ssh/xxxxxxxxxx.pem"
    end

    # [追記]ここから
    config.vm.provision :chef_solo do |chef|
        chef.add_recipe "apache"
        chef.add_recipe "tomcat7"
    end
    # [追記]ここまで
end

7.2. ApacheとTomcatのインストールと起動

$ vagrant provision

何やら色々と出力されますが、ファイルの同期、Chefのインストール、Apacheのインストールと起動、Tomcatのインストールと起動とやっているようです。
それでは、Apacheが正しく動作しているかWEBブラウザから確認します。
アドレスバーに「http://(EC2インスタンスIPアドレス)/」と入力してHTTPリクエストを投げます。
(EC2インスタンスIPアドレスは、EC2管理コンソールから確認できます。)
以下のようにApacheの画面が表示されれば成功です。

apche.png

8. ApacheとTomcatを連携させる

次にajpを使用して、ApacheとTomcatを連携させます。

8.1. Apacheの設定ファイルをtemplateとして追加

Chefのtemplateを使用して新しくconfファイルを作り、配布します。
Cookbookのtemplate/default/の下に拡張子をerbとしてテンプレートファイルを設置します。

cookbooks/apache/templates/default/ajp.conf.erb
<Location />
    ProxyPass ajp://localhost:8009/docs/
</Location>

8.2. templateを使用するようrecipeを修正

次に、recipeにいくつか書き加えます。
書き加えた箇所を要約すると「template/default/ajp.conf.erb を /etc/httpd/conf.d/ajp.confへ置くこと、置いたらhttpdをreloadせよ。」ということになります。

cookbooks/apache/recipes/default.rb
package "httpd" do
  action :install
end

service "httpd" do
  action [ :enable, :start ]
  supports :status => true, :restart => true, :reload => true
end

#[追記]ここから
template "/etc/httpd/conf.d/ajp.conf" do # 「template/default/ajp.conf.erb」を「/etc/httpd/conf.d/ajp.conf」へ置け
  owner "root"
  group "root"
  mode 0644
  notifies :reload, 'service[httpd]' # テンプレートを置いたら、httpdの:reloadアクションを呼び出せ
end
#[追記]ここまで

8.3. Tomcatのserver.xmlをtemplateとして追加

Tomcatがport8080に応答しないよう、server.xmlから該当の箇所をコメントアウトしてtemplateファイルとして設置します。
(Security Groupがport8080の通信を許可していないので、実際にport8080の通信が届く事はないが、気持ち悪いので一応やっておく。)

cookbooks/tomcat7/templates/default/server.xml.erb
<!--    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" /> -->

8.4. server.xml.erbを使用するようrecipeを修正

こちらもApacheと同様に作成したtemplateを使用するようにrecipeを書き換えます。
やっている事は、Apacheで追記したrecipeと同様です。

cookbooks/tomcat7/recipes/default.rb
package "tomcat7" do
    action :install
end

service "tomcat7" do
    action [ :enable, :start ]
    supports :status => true, :restart => true, :reload => true
end

package "tomcat7-docs-webapp" do
    action :install
end

#[追記]ここから
template "/etc/tomcat7/server.xml" do    # 「templates/default/server.xml.erb」を「/etc/tomcat7/server.xml」へ置け
  owner "tomcat"
  group "tomcat"
  mode 0664
  notifies :restart, 'service[tomcat7]'  # テンプレートを置いたらtomcat7をの:restartアクションを呼び出せ
end
#[追記]ここまで

8.5. 再びprovision

ターミナルから以下のコマンドを打ちます。
今度は追加したtemplateをuploadし、notifiesで指定したアクションが呼び出されている様が出力されます。

$ vagrant provision

それでは、動作確認をしてみましょう。
WEBブラウザから、先程のURLへリクエストを投げます。
ApacheはTomcatのdocsコンテキストへAJPで連携します。
以下のようにTomcatのdocsアプリの画面が表示されれば成功です。

tomcat.png

8.6 停止、破棄

ずいぶん長くなってしまいました、お疲れ様でした。
最後にVagrantからEC2インスタンスを停止させましょう。(起動しっぱなしだと課金されていきますので。)

$ vagrant halt
==> default: Stopping the instance...

EC2管理コンソールからインスタンスの状態が"stopped"になっている事を確認しましょう。

ちなみに、破棄する時はdestroyです。

$ vagrant destroy

9. さいごに

実際に書き始めてみところ、かなりのボリュームになってしまい説明の浅い箇所がところどころ出来てしまいました。
判りにくい箇所がありましたら申し訳ございません。
VagrantによるEC2インスタンスの起動とChefによるプロビジョンについて、ざっくりとした感覚が伝わればよいと思います。
参考にさせていただいた文献を以下にまとめましたのでよく判らないところがあれば、これらの書籍を読んでいただければ更に理解が深まるでしょう。

9.1. 参考文献

  • 実践 Vagrant - O'REILLY
  • Chef実践入門 - 技術評論社
18
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
19