Full-stack Engineer's blog

Flexible provisioning tool "Itamae" - manage infrastracture as code

日本語 | English


Chef and Ansible are well known provisioning tools, but here is another option I want to share, which is "Itamae". As a background we use itamae, our team was using chef and chef-server. I don't think it's rare case that the cookbooks get messy. After all, we felt chef is too strict to cover our provisioning requirement.

On the other hand, Itamae is flexible architecture like Ansible, besides it is much capable of managing many types of servers. As you can see after, for now, our itamae practice contains provisioning function and deploy function in 1 repository. But don't take this wrong way, we are ready to separate them if it's needed.


Itamae by itamae-kitchen
Itamae is a flexible powerfull provisioning tool.
Especially, when it comes to migration of chef, there are some good aspects.

  • Written in Ruby (same language)
  • Similar notation of methods (low learning cost)
  • Only client server needs itamae command (This is biggest advantage)
    (Node servers do NOT need itamae command)
  • Flexible architecture
  • Easy to write and add plugins

Our itamae practice

As I said earlier, our itamae practice contains provisioning function and deploy function in 1 repository.


We basically followed to Official Best-Practice.

|-- entrypoint.rb
|-- cookbooks    <----  installations, common stuff
|   |-- apache
|   |-- cron
|   |-- fluentd
|   `-- git
|-- nodes 
|   `-- servers    <----  each server's provisioning json
|   |   |-- bar.json
|   |   `-- foo.json
|   `-- release_hogehoge.json    <----  project basis, deploy etc...
`-- roles     <---- specific procedure,  deploy procedure etc... 
    |-- compile_hogehoge.rb
    `-- release_hogehoge.rb

roles is json format in chef. And If the node server is hosthoge0001 and use nodes/sample.json, command is going to be like this.

$ itamae ssh -h hosthoge0001 --node-json nodes/sample.json entrypoint.rb


In entrypoint.rb, set configuration such as running environments and host groups. Then the configuration is passed to cookbooks and roles which run after.

node["recipes"] = node["recipes"] || []
host_name = node[:hostname] 
host_group = host_name[/(.+)([0-9]){4}/, 1 ]   # hostname without number  ex.) hogehoge0001 -> hogehoge
proxy_host = "bar"
proxy_port = "1234"

# running environment
if host_name.index("-dev") != nil then
    env = "dev"
elsif host_name.index("-test") != nil then
    env = "test"
    env = "product"

    common: {
        host_name:  host_name ,
        host_group:  host_group ,
        proxy_host: proxy_host,
        proxy_port: proxy_port,
        env:    env

node["recipes"].each do |recipe|
  include_recipe recipe

Found troubles during the operation

Just one possible reason of troubles is CentOS5.x, and there are two troubles I found.


As usual notation,

git "/home/hoge/foo" do
    repository  "https://hogehoge.com/bar/foo.git" 
    user        "hoge"
    cwd         "/home/hoge"
    revision    "master"

But this doesn't work. So then, we took another approach.

execute "git checkout piyo" do
    user "hoge"
    cwd "/home/hoge/bar"
    command "/usr/local/bin/git checkout piyo"


As usual notation,

user "useradd #{setting[:username]}" do
    action      :create
    username    setting[:username]
    home        setting[:home]
    password    setting[:password]
    shell       setting[:shell]
    create_home setting[:create_home]

But this doesn't work. And after all, I couldn't find any substitute code of using sbin commands (root authority commands) like this.


What I want to say is chef is NOT bad, I'm somewhat in trouble in itamae as well. In appropriate usage, chef works better than itamae. Works good or works bad is just depends how to use.