Menu

Category

Archive

logo


EC2インスタンスをVagrantで起動して、Chef Soloでプロビジョニング

2015-08-16 15:00:00 +0900
  • このエントリーをはてなブックマークに追加

今回はAWSのEC2インスタンスをVagrantで起動します。 さらに、Chef Soloと連携させて、Nginxを起動させてみたいと思います。

Vagrant側の準備

まずは、VagrantのAWSに関するプラグインのインストール。

1
$ vagrant plugin install vagrant-aws

そして、EC2のインスタンスを起動する際に仮に使うboxのインストール。すぐに終わります。

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

AWS側の準備

AWSでは、1. セキュリティグループの作成、2. キーペアの作成、3. アクセスキー・シークレットキーの取得の3つ作業があります。

1. セキュリティグループの作成

まずは、AWSでセキュリティグループの作成します。既存のものを使ってもよいでしょう。今回はこのChef周りの勉強のために作りなおしました。

AWSのコンソール上で、 EC2 を選び、左のメニューにある Security Group を選択します。

セキュリティグループ対しては、適当に名前と説明を記述します。 このセキュリティグループの名前をのちのち Vagrantfile で指定します。

2. キーペアの作成

次に、AWSでキーペアの作成します。

AWSのコンソール上で、 EC2 を選び、左のメニューにある Key Pairs を選択します。 そして、キーペアも作成し、ダウンロードして、適当な場所に保存しておきます。 今回は、 ~/.ssh/chef_guide.pem としました。

このpemファイルに対して、

1
$ chmod 600 ~/.ssh/chef_guide.pem

としてアクセス権を変更しておきましょう。

3. アクセスキー・シークレットキー

最後に、もしない場合は、AWSのサービスを外部から使用するため、アクセスキー・シークレットキーを取得します。 最近は、これらの値を取得するのにルート権限ではなく、 IAM(Identity and Access Management) でユーザーを作る必要があるようです。 IAM > Users > kzykbys と各ユーザーのうち、権限があるユーザーの Security Credentials という欄からアクセスキー・シークレットキーを作成・取得してください。

ローカル環境の準備(環境変数の設定)

上記で作成したアクセスキー・シークレットキーはかなり重要なものです。 不用意にバージョン管理システムで管理等をするのは危険です。 そのため、これらの値は、環境変数等に保存して、それらを参照するようにしましょう。

1
2
3
4
export AWS_ACCESS_KEY_ID=abc
export AWS_SECRET_KEY=abc
export AWS_KEYPAIR_NAME=chef_guide
export AWS_ACCESS_KEY_ID=$HOME/.ssh/chef_guide.pem

私の場合は、~/.bash_profile にこのように記述して読み込みます。

1
$ source ~/.bash_profile

Vagrantfile

そして、EC2のインスタンスをVagrantから起動する最後の仕上げのVagrantfileの編集です。 今まで作った値等を設定しているのがわかると思います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  ssh_username = "ec2-user"
  region = "ap-northeast-1"
  ami = "ami-b1fe9bb0"
  instance_type = "t1.micro"

  config.vm.box = "dummy"
  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 = ENV['AWS_KEYPAIR_NAME']

    override.ssh.username = ssh_username
    override.ssh.private_key_path = ENV['AWS_PRIVATE_KEY_PATH']

    aws.region = region
    # aws.elastic_ip = true ← これがあるとダメだった
    aws.security_groups = ["chef_guide"]

    # User-data
    aws.user_data = "#!/bin/sh\nsed -i 's/^.*requiretty/#Defaults requiretty/' /etc/sudoers\n"
    # タグを指定(任意)
    aws.tags = aws.tags = { "Name" => "test-chef6", "env" => "dev"}
    # AMIを指定。起動したいリージョンにあるAMI
    aws.ami = ami
    # インスタンスタイプを設定
    aws.instance_type = instance_type
  end
end

EC2インスタンスの起動

そして、ついにEC2のインスタンスを起動します。 Vagrantfileがあるディレクトリで、

1
2
3
$ vagrant up --provider=aws
or
$ VAGRANT_LOG=info vagrant up --provider=aws

とすれば完了です!AWSのコンソール上で、インスタンスが立ち上がっているのが確認できると思います。すごい! エラーが出た時には2つ目のコマンドのように、ログを出力させればだいたいわかると思います。

私がハマった箇所としては、

1
==> default: Waiting for SSH to become available...

の部分のログで、SSHが通らなかったです。原因は、上で解説したように *.pem にアクセス権を変更していなかったり、セキュリティグループの名前のタイプミスでした。

また、上記の ==> default: Waiting for SSH to become available... はちょっと長い時間かかります。僕はこれが長くてエラーだと勝手に思い何度も奮闘しましたが、2~5分くらい待つと普通に起動しました。ちょっとせっかちでした。 最後に載せている参考文献によると10分して、このログが次へ進まなかったら、エラーだろうということです。

1
2
3
4
==> default: Waiting for instance to become "ready"...
==> default: Waiting for SSH to become available...
==> default: Machine is booted and ready for use!
==> default: Rsyncing folder: /Users/kzykbys/Vagrant/chef-aws/ => /vagrant

のように最後まで出力されていれば大丈夫のはず。

Chef Solo (knife soloによるクックブックの適応)

上記までで、とりあえずEC2インスタンスをコマンドラインからVagrant経由で起動することはできました。 次にやりたいのはChef Soloと連携させて、適宜ミドルウェア等を反映させていくことです。 今回は、前回と同じくnginxを起動させてブラウザでアクセスしてみます。 やっていることも前回とほぼ同じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ knife solo init .
$ vagrant ssh-config --host ec2-chef >> ~/.ssh/config
$ knife solo prepare ec2-chef
$ knife cookbook create nginx -o site-cookbooks

# site-cookbooks/nginx/recipesの編集
include_recipe "yum-epel"

package "nginx" do
  action :install
end

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

# Berksfileの編集
cookbook 'yum-epel'

# ec2-chef.jsonの編集
{
  "run_list": [
    "recipe[yum-epel]",
    "recipe[nginx]"
  ],
  "automatic": {
    "ipaddress": "ec2-chef6"
  }
}

そして、最後にクックブックを適応させれば完了です!

1
$ knife solo cook ec2-chef

これで、VagrantからEC2インスタンスを起動して、Chefによりnginxのインストール・起動が成功しているはずです! AWSのコンソールから該当インスタンスのパブリックIPを確認して、ブラウザでアクセスするとnginxの初期画面が見れるはずです。

Chef Solo (Vagrantからクックブックの適応)

knife solo は、前回の記事と同じ方法でした。 今回はVagrantのProvisionerを使い、Chefのクックブックを適応させる方法も試してみました。

まずは、Vagranfileを編集します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  ssh_username = "ec2-user"
  region = "ap-northeast-1"
  ami = "ami-b1fe9bb0"
  instance_type = "t1.micro"

  # Chef Clientの最新版を利用可能にする
  config.omnibus.chef_version = :latest

#  config.berkshelf.berksfile_path = "./Berksfile"
#  config.berkshelf.enabled        = true

  config.vm.box = "dummy"
  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 = ENV['AWS_KEYPAIR_NAME']

    override.ssh.username = ssh_username
    override.ssh.private_key_path = ENV['AWS_PRIVATE_KEY_PATH']

    aws.region = region
    # aws.elastic_ip = true ← これがあるとダメだった
    aws.security_groups = ["chef_guide"]

    # User-data
    aws.user_data = "#!/bin/sh\nsed -i 's/^.*requiretty/#Defaults requiretty/' /etc/sudoers\n"
    # タグを指定(任意)
    aws.tags = aws.tags = { "Name" => "test-chef7", "env" => "dev"}
    # AMIを指定。起動したいリージョンにあるAMI
    aws.ami = ami
    # インスタンスタイプを設定
    aws.instance_type = instance_type
  end

  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["./cookbooks", "./site-cookbooks"]
    chef.json = {
    }
    chef.run_list = %w[
      recipe[yum-epel]
      recipe[nginx]
    ]
  end
end

vagrant-omnibusというプラグインを使用し、該当ノードに最新のChefを自動でセットアップされるようにしました。 また、config.vm.provision :chef_solo の行で、今までNodeオブジェクトに記載していたものを指定しています。

そして、vagrant-omnibus のインストール(一度のみ)します。

1
$ vagrant plugin install vagrant-omnibus

そして、コミュニティクックブックのインポートをします。

1
$ berks vendor cookbooks

このインポートも vagrant-berkshelf のようなプラグインを使えば良さそうですが、上手く行かなかったのでとりあえず、手動でインポートしました。

後は、下記のようにvagrant upしたり、適宜クックブックを適応させれば、knife solo と同じようにnginxがインストール・起動しているはずです。

1
2
$ vagrant up provision
$ vagrant provision

参考

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)