はじめに
- 前回に引き続き capistrano と chef-solo でシリーズ第二弾
- せっかくなんで EC2 インスタンスもやってみた
- セットアップ後の確認には前回と同様に
serverspec
を使う - とりあえずメモ
こんな感じで
以下のような事を出来るようにした。
将来的には...
等にも対応する予定。
レシピ
以下のようなレシピでいけた。
require 'aws-sdk' require 'yaml' # Please set AWS access_key and secret_access_key and region. config = YAML.load(File.read("config/deploy/config.yml")) AWS.config(config) # set :local_home, ENV['HOME'] set :remote_home, "/tmp" set :chef_local_dir, "#{local_home}/chef-repo" set :chef_remote_dir, "#{remote_home}/chef" set :user, "#### please set ssh user (ex ec2-user" set :key, "#### please set ssh-key path (ex path/to/key" set :ami, "#### plase set ami" set :instance_type, "#### please set instance type (ex t1.micro" set :vpc_subnet, "#### please set vpc's subnet" set :security_group, "#### please set security group id" set :key_name, "#### please set key name" set :tag_name, "#### please set tag's value name" # servers = AWS.ec2.instances.select {|i| i.tags[:Name] == "#{tag_name}" && i.status == :running}.map(&:dns_name) role :servers, *servers # namespace :ec2 do desc "Launch EC2 instances." task :launch do inst = AWS.ec2.instances.create({ :image_id => "#{ami}", :instance_type => "#{instance_type}", :subnet => "#{vpc_subnet}", :security_group_ids => "#{security_group}", :key_name => "#{key_name}", }) AWS.ec2.tags.create(inst, 'Name',:value => "#{tag_name}") end task :status do puts "#{servers}" end end # namespace :chef do task :init, :roles => :servers do run "#{try_sudo} apt-get update" run "#{try_sudo} apt-get -y install sudo curl rsync" run "#{try_sudo} curl -L https://www.opscode.com/chef/install.sh | sudo bash" end task :sync, :roles => :servers do run "mkdir -p #{chef_remote_dir}/chef-repo/" find_servers_for_task(current_task).each do |server| if ( "#{server.port}" == nil ) `rsync -avz #{chef_local_dir}/ -e "ssh -i #{key} -p #{server.port}" #{user}@#{server.host}:#{chef_remote_dir}/chef-repo/` else `rsync -avz #{chef_local_dir}/ -e "ssh -i #{key}" #{user}@#{server.host}:#{chef_remote_dir}/chef-repo/` end end end task :deploy, :roles => :servers do find_servers_for_task(current_task).each do |server| run "#{try_sudo} chef-solo -j #{chef_remote_dir}/chef-repo/nodes/localhost.json -c #{chef_remote_dir}/chef-repo/solo.rb" end end end
もろもろ、無駄が多いのは否めないがソースはこちら。
ポイントは...
config = YAML.load(File.read("config/deploy/config.yml")) AWS.config(config)
YAML
形式で AWS
のキー等の接続情報を書いて外出しにした。これは config/deploy.rb
に書いても良いと思われるがコード管理のリポジトリにアップしたくない場合に外部ファイルに持てばコミットしないような設定(.gitignore
とか)で不意のアップを防げる。
desc "Launch EC2 instances." task :launch do inst = AWS.ec2.instances.create({ :image_id => "#{ami}", :instance_type => "#{instance_type}", :subnet => "#{vpc_subnet}", :security_group_ids => "#{security_group}", :key_name => "#{key_name}", }) AWS.ec2.tags.create(inst, 'Name',:value => "#{tag_name}") end
servers = AWS.ec2.instances.select {|i| i.tags[:Name] == 'chefsetup' && i.status == :running}.map(&:dns_name)
上記で Chef-solo
を実行するインスタンスのホストを取得する。
deploy.rb
上記のレシピ以外でも deploy.rb
に以下の設定をする。
require "capistrano/ext/multistage" require "capistrano_colors" # default_run_options[:pty] = true ssh_options[:keys] = ["/path/to/key"]
使い方
ec2:launch
上記のレシピを hogehoge.rb
で保存した場合には以下のようにしてインスタンスを作って起動する。
cap hogehoge ec2:launch
ec2:status
作成したインスタンスが起動しているかを確認するには以下のようにする。
cap hogehoge ec2:status
後は前回と同じように chef:init
や chef:sync
と chef:sync
でセットアップしていくことになる。
demo
インスタンスを作成
cap aws-setup ec2:launch
確認
インスタンスが出来たかどうだか確認してみよーはいつものように aws-cli
を利用する。
aws ec2 describe-instances \ --filters "Name=tag-value,Values=setup" \ |jq '@sh "\(.Reservations[].Instances[] | [.InstanceId,.PublicIpAddress,.PrivateIpAddress, .Tags[0].Value])"'
以下のようにインスタンスの IP 等が確認出来た。
せっかくなので ec:status
も使ってみる。
まあ、こんな感じで...
インスタンスにて Chef-solo を使ってセットアップする
前回と同様に chef:init
で Chef-solo
の実行に必要なアプリケーションのセットアップ、chef:sync
でローカルの chef-repo
を rsync
を使ってインスタンスにアップロード、最後に chef:deploy
で Chef-solo
が実行される。
おおっ。嬉しい瞬間。
とりあえず
長くなってしまったので次回はセットアップしたらちゃんと確認ということで serverspec
を使って cookbook
が適用されているかを確認する。