Edited at

knifeコマンドが面倒すぎるので「knife-helper」というpluginを作ったのでチュートリアル(knife-zero,knife-ec2で)

More than 3 years have passed since last update.

タイトルの通り、作りました。

詳しい経緯などはコチラをどうぞ。


どんなPlugin?

Chef Server及びknife-zeroを使う場合に、knifeコマンドがまともに使えるようにするまでの下準備と、実際に使う時のコマンドが複雑で到底覚えられないというのがツライ。

なので、それを解決するために2つのサブコマンドを提供します。


  1. 最低限の事前準備を行うhelper initコマンド


  2. yamlで定義したショートカットコマンドを実行するhelper execコマンド


チュートリアル

ちなみに、このチュートリアルで使用したファイル群は以下にあります。

https://github.com/marcy-terui/knife-helper-example


導入

普通のRubyプロジェクト的にbundlerを使う形で進めます。

以下のような、Gemfileを用意します。


Gemfile

source "https://rubygems.org"

gem "chef"
gem "knife-helper"
gem "berkshelf"
gem "knife-ec2"
gem "knife-zero"


インストールします。

$ bundle


initコマンド実行

以下のコマンドを実行します。

今回は、knife-zeroを使用するため、ローカルモードで動かしたいので、-lあるいは--localオプションを指定します。

また、Berkshelfを使用するため-Bあるいは--berksオプションを指定します。1

ちなみに、Librarian-Chefを使用する場合は-Lまたは--librarianオプションを指定します。

$ bundle exec knife helper init -l -B

すると、以下の様なChefの設定を定義する.chef/knife.rbと、ショートカットコマンドを定義するための.knife.helper.ymlBerksfileが生成されます。2


.chef/knife.rb

local_mode true

cookbook_path ["./cookbooks", "./site-cookbooks"]
chef_repo_path "./"

cookbook_path,chef_repo_pathはオプションで変えられます。

cookbook_path-cchef_repo_path-rです。


.knife.helper.yml

---

settings:
command_base: /Users/marcy/github/knife-helper-example/vendor/bundle/ruby/2.1.0/bin/knife

commands:
- name: default
command:
condition:
options:


exec_pathは環境ごとに自動で設定されます。

複数人で使用する場合はbundle exec knifeにしておくと良いかもしれません。3


command_baseは環境ごとに自動で設定されます。

複数人で使用する場合、bundle execで実行するよう-bまたは--bundleオプションを付けると以下のようになり、環境ごとのpathの差異に関係なく実行できるようにしておくとよいでしょう。

settings:

command_base: bundle exec knife


ショートカットコマンドの定義

.knife.helper.ymlにショートカットコマンドを定義します。

ERBテンプレートとなっているため、Rubyコードの埋め込みも可能です。


.knife.helper.yml

---

settings:
command_base: /Users/marcy/github/knife-helper-example/vendor/bundle/ruby/2.1.0/bin/knife

commands:
- name: create
command: ec2 server create
options:
aws-access-key-id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
aws-secret-access-key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
region: ap-southeast-1
flavor: t2.micro
image: ami-68d8e93a
tags: Name=knife-helper-example
ssh-key: knife-helper-example
subnet: subnet-3dc43e58
security-group-ids: sg-713bc314
ssh-user: ec2-user
identity-file: ~/.ssh/knife-helper-example.pem
template-file: template.erb
associate-public-ip:
- name: bootstrap
command: zero bootstrap ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com
options:
node-name: knife-helper-example
environment: test
hint: ec2
ssh-user: ec2-user
identity-file: ~/.ssh/knife-helper-example.pem
sudo:
- name: converge
command: zero chef_client
condition: chef_environment:test
options:
ssh-user: ec2-user
identity-file: ~/.ssh/knife-helper-example.pem
attribute: ec2.public_ipv4
sudo:



各keyの説明


key名
説明

name
サブコマンド名(実行時はこれを指定する)

condition
search機能を使う場合の条件

options
オプション。Hash形式でkeyがオプション名、valueが値。value指定が必要ないオプションはkeyのみ記述する。

optionsは必ずしもロング名ではなく、1文字名で書いても良いですが、yamlの見た目的にだいぶ残念な感じになりますw


ノード作成

knife-ec2でサーバノードを調達します。

今回はChef Serverへ繋がず、knife-zeroからbootstrapしたいので、bootstrapアクションを差し替えるためのテンプレートファイルを用意しておきます。


template.erb

bash -c '

sudo yum -y update
'


先ほど定義したcreateショートカットコマンドを利用します。

knife helper exec ショートカット名で実行できます。

$ bundle exec knife helper exec create

Instance ID: i-ad186e60
Flavor: t2.micro
Image: ami-68d8e93a
Region: ap-southeast-1
Availability Zone: ap-southeast-1b
Security Group Ids: sg-713bc314
Tags: Name: knife-helper-example
SSH Key: knife-helper-example

Waiting for EC2 to create the instance.............
Subnet ID: subnet-3dc43e58
Tenancy: default
Public DNS Name: ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com
Private IP Address: 172.31.3.169

Waiting for sshd access to become available..........done
Doing old-style registration with the validation key at ...
Delete your validation key in order to use your user credentials instead

Connecting to ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com

<snip>

Instance ID: i-ad186e60
Flavor: t2.micro
Image: ami-68d8e93a
Region: ap-southeast-1
Availability Zone: ap-southeast-1b
Security Group Ids: sg-713bc314
Tags: Name: knife-helper-example
SSH Key: knife-helper-example
Root Device Type: ebs
Root Volume ID: vol-e85021e6
Root Device Name: /dev/xvda
Root Device Delete on Terminate: true
Subnet ID: subnet-3dc43e58
Tenancy: default
Public DNS Name: ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com
Private IP Address: 172.31.3.169
Environment: _default

できました。


knife-zeroからbootstrap

とりあえず、後で使うために仮のEnvironmentを定義しておきます。

$ bundle exec knife environment create test

ショートカットコマンドからboottrapを実行します。

$ bundle exec knife helper exec bootstrap

Doing old-style registration with the validation key at ...
Delete your validation key in order to use your user credentials instead

Connecting to ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com
ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com Installing Chef Client...

<snip>

ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com Chef Client finished, 0/0 resources updated in 4.994025311 seconds


レシピを流す

とりあえず、Community cookbookのnginxでも流してみることにします。

Berksfileを以下のように書き換えます。


Berksfile

source "https://supermarket.chef.io"

cookbook "nginx"


cookbookを収集します。

$ bundle exec berks vendor cookbooks

ノードのrun_listに追加します。

$ bundle exec knife node run_list add knife-helper-example recipe[nginx]

では、ショートカットコマンドから実行します。

$ bundle exec knife helper exec converge

52.74.50.188 Starting Chef Client, version 12.2.1
52.74.50.188 resolving cookbooks for run list: ["nginx"]

<snip>

52.74.50.188 Running handlers:
52.74.50.188 Running handlers complete
52.74.50.188 Chef Client finished, 22/25 resources updated in 32.196846458 seconds

よく焼けたようですね。


ちなみに

knife helper exec-pまたは--printオプションをつけると、実行はせずに実行されるコマンドを出力します。

どんなコマンドになるか?

$ bundle exec knife helper exec create -p

/Users/marcy/github/knife-helper-example/vendor/bundle/ruby/2.1.0/bin/knife ec2 server create --aws-access-key-id AKIAIIKXXXXXXX --aws-secret-access-key XXXXXXXXXXXXXXXXXXXXXX --region ap-southeast-1 --flavor t2.micro --image ami-68d8e93a --tags Name=knife-helper-example --ssh-key knife-helper-example --subnet subnet-3dc43e58 --security-group-ids sg-713bc314 --ssh-user ec2-user --identity-file ~/.ssh/knife-helper-example.pem --template-file template.erb --associate-public-ip

$ bundle exec knife helper exec bootstrap -p
/Users/marcy/github/knife-helper-example/vendor/bundle/ruby/2.1.0/bin/knife zero bootstrap ec2-52-74-50-188.ap-southeast-1.compute.amazonaws.com --node-name knife-helper-example --environment test --hint ec2 --ssh-user ec2-user --identity-file ~/.ssh/knife-helper-example.pem --sudo

$ bundle exec knife helper exec converge -p
/Users/marcy/github/knife-helper-example/vendor/bundle/ruby/2.1.0/bin/knife zero chef_client 'chef_environment:test' --ssh-user ec2-user --identity-file ~/.ssh/knife-helper-example.pem --attribute ec2.public_ipv4 --sudo

こんな複雑なコマンドを少しでも簡単に、使いやすく、使い回ししやすいようにとknife-helperを作った次第です。

より良い方法等あれば、フィードバックいただけると幸いです。





  1. インストールがクソ重くてヘイト溜まるけど、慣れたのとなんだかんだデファクトの地位を確立してる感あるので不本意ながら 



  2. 2015.04.09現在 



  3. オプション化 するかもしました