0. Intro

팀에서 릴레이 코딩을 하기로 했어요. 바톤을 넘겨 받아 달리는 계주도 아니고, 프로그램을 그렇게 짜다니... 그럼에도 이를 시도한 까닭은, 각자 개발에서 오는 소통의 부재와 Code의 상향 평준화를 염두에 두었기 때문이었습니다. 릴레이 소설에서 영감을 얻어, 팀원의 동의를 받아 진행하였지만, 처음부터 난관이... 다름아닌, 개발 환경이었습니다.

1. Chef와 Vagrant의 동거

chef는 설정 자동화 도구(Server Configuration Management)입니다.(자세한 내용은 여기 참조) 300대의 서버가 있고, 필요한 프로그램을 모두 설치하려면 얼마나 시간이 걸릴까요? 이 질문에 답할 수 있는 프로그램들이 여럿 있지만,(puppet, chef, etc..) 오늘은 그 중에 하나인 요리사(chef)를 보도록 하겠습니다.

chef는 Ruby로 작성되었다고 하네요. 즉, Ruby를 잘 안다면 좋겠지만, 친해질 겸, 겸사 겸사, 전번 정도 받는 수준으로 접근해 보죠.

1) What do you want from the chef? (필요한 프로그램)

공동의 개발 환경을 서로 다른 VM에서 유지하기 위해서 최소의 필요는 다음과 같았습니다.

  • python3
  • redis database
  • vim
  • emacs
  • git

요리사(chef)에게 이 소프트웨어를 요리해 달라고 부탁하면 됩니다. 요리를 시키기 위해서는, 먼저 요리책을 주어야 합니다..

2) Chef, cookbooks and recipe (요리사, 요리책 그리고 레시피)

chef는 요리책이 필요합니다. 집에 요리책이 없더라도 걱정할 필요는 없습니다. 인터넷에서 다운받으면 되니까요. 누군가가 많은 요리책을 이미 만들어 두었습니다. http://community.opscode.com/cookbooks 에서 필요한 요리책을 가져오시면 됩니다. 이런 방식으로 사용하게 되는데...

git clone http://github.com/opscode-cookbooks/mysql

가끔, 요리책이 없는 경우가 있는데, 이는 요리책을 만들어 주시거나 혹은 다른 방법으로 package를 설치하셔야 합니다. 저의 경우에는, python3를 inline명령으로 apt-get을 이용하여 설치하였습니다.

위처럼, 요리책을 다운 받으실 때는 그 위치에 조금 신경을 쓰셔야합니다. 나중에 Vagrantfile에서 참조할 것이기 때문입니다. 저의 경우에는 다음과 같은 구조로 위치시켰습니다.

vagrant-example
          Vagranffile
     └─ Cookbook
               git
               homesick
               redisio
               ssh_known_hosts
               subversion
               ulimit
               vim
     └─ Site-Cookbooks
               extend_lwrp
               homesick_agent
               root_ssh_agent
               users
     └─ Databags
               ssh_known_hosts
               users

꽤, 많죠. toturial을 따라 하다가, 제가 필요한 것도 추가하고 그러다 보니 너무 늘어났습니다. 그러나, 위의 cookbooks들은 network상에 한 곳에만 위치하고 있으면 됩니다. 꼭 하위 폴더일 필요는 없습니다. 주의하실 점은, homesick의 경우, 주소가 'http://fnichol.github.io/chef-homesick'이므로 폴더의 이름이 'chef-homesick'으로 생긴다는 점입니다. 'chef-'라는 접두어는 빼주셔야 합니다.

3) Vagrant with chef

모든 열쇠는 Vagrantfile에 들어 있습니다. Vagrantfile에서 시작하시면 됩니다. 이미, 훌륭한 선배들이 Vagrant가 chef를 지원할 수 있도록, 모든 조치를 해 두었습니다.

두둥~ Code입니다!

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant::Config.run do |config|
  config.vm.box = "ubuntu"

  config.ssh.forward_agent = true

  config.vm.provision :chef_solo do |chef|

    # instruct 'homesick::data_bag' to install dotfiles for the user 'testuser'
    chef.json = {
      "users" => ['testuser'],
    }

    # contains "users" and "ssh_known_hosts" databags
    chef.data_bags_path = "databags"
    chef.cookbooks_path = ["cookbooks", "site-cookbooks"]

    # stuff that should be in base box
    chef.add_recipe "vim"
    chef.add_recipe "git"
    chef.add_recipe "subversion"

    #chef.add_recipe "ulimit"
    chef.add_recipe "ulimit"
    chef.add_recipe "redisio::install"
    chef.add_recipe "redisio::enable"

    # setup users (from data_bags/users/*.json)
    chef.add_recipe "users::ruby_shadow"
    chef.add_recipe "users::sysadmins"
    chef.add_recipe "users::sysadmin_sudo"

    # homesick_agent and its dependencies
    chef.add_recipe "root_ssh_agent::ppid"
    chef.add_recipe "ssh_known_hosts"
    chef.add_recipe "homesick_agent::data_bag"

    # install python3
    config.vm.provision :shell, :inline => "sudo apt-get install -y python3 python3-setuptools"
    config.vm.provision :shell, :inline => "sudo easy_install3 beautifulsoup4"

    chef.log_level = :debug

  end
end

읽어보시면 생각보다 간단하다는 것을 알 수 있습니다. 이 파일에는 조금의 Logic도 포함되어 있지않아요. 단순히, Assign들만 들어 있습니다. 몇 가지 제가 아는 것만 설명드릴께요. ^^;;;

  • config.vm.box - 해당 VM이 사용하는 Box의 이름입니다.
  • config.vm.box_url - 'vagrant box add'로 box를 다운받지 않으셨더라도, URL을 입력해 주시면, 해당 박스를 사용하게 됩니다.
  • config.vm.provision : chef_solo - 그렇죠. 감이 오시죠. chef를 server, client로 구성한게 아니라, 단독(solo)으로 사용했습니다.
  • chef.json - 이 부분의 package가 설치될 때, parameter를 넘기는 부분입니다.
  • chef.data_bags_path - data bags은 설치되는 pkg에게 넘겨줄 json 파일들입니다. 그 경로를 설정하는 것 입니다.
  • chef.cookbooks_path - 요리책의 경로
  • chef.add_recipe - 요리를 추가합니다. 그래서 add_recipe은 많이 나타나게 됩니다.
  • config.vm.provision :shell, :inline - 감이 오시죠? 맞습니다. 요리책에 없거나 이런 저런 이유로 shell에 자동으로 입력시키고 싶은 부분입니다.
  • chef.log_level - 뭐 이건 다 아실듯.. ^^

가끔, 설치 중에, 404 에러가 나는 경우가 있습니다. 이는 apt-get의 package참조 정보가 오래되어 발생하는 경우가 있었습니다. 그럴 때에는, SSH로 box에 접근하여, 'sudo apt-get update'를 실행시켜 주시고, 다시 'vagrant provision'을 실행시켜 주시면 되겠습니다. Vagrantfile에 넣는 것은, 매 up마다 update가 작동하므로 추천드리지 않습니다.

4) Provisioning (프로비저닝, 번역이......;;;)

Vagrant에서 Provisioning이라고 하면, Vagrantfile을 수정한 이후에 자동적으로 소프트웨어를 설치하는 것을 말합니다. 이는 'vagrant up' 프로세스의 한 부분이라서, up을 수행시키면 자동적으로 수행하게 됩니다. 혹은, 이미 동작중인 VM에 대해서는 'provision' 명령어를 사용하시면 됩니다.

> vagrant up
> vagrant reload
> vagrant provision

> vagrant destroy #delete VM

그리고 정말, 이상하다 싶으시면, 혹은 멘탈 붕괴가 오신다면 'destroy'로 처음부터 다시 가시기를 추천해 드립니다.

2. Reference

 3. Closing

역시, 적는 다는 것은 무지와 대면하는 순간인 것 같습니다. 빈약한 부분이 한 둘이 아니에요ㅜㅜ