Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@marcy-terui

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

タイトルの通り、作りました。
詳しい経緯などはコチラをどうぞ。

どんな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. オプション化 するかもしました 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What are the problem?