tkak's tech blog

This is my technological memo.

TerraformのGoogle Cloud providerを試してみた。

先日参加したgcp ja night #28 - connpassで、 Google Cloud Platformを$500分無料で使えるクーポンをいただいたので、 Terraform by HashiCorpGoogle Cloud providerを試してみた。

Terraformは、Vagrantとかインフラ便利ツールを作っているHashicoap社の新作。 インフラの状態をDSL形式で定義できて(Infrastructure as Code)、CLIからインフラの状態を変更することができる。

ChefやPuppetとは守備範囲が違って、VM作ったり、バランサの設定したり、DNSを登録したりする作業を自動化する。 守備範囲的には、Chef-metalとかAWS CloudFormationとかとかぶる感じ。

いろんなクラウドサービスを、同じフォーマットのファイルで管理することができるのが大きな強み。 今巷でバズってるMicroservices的な考えで、数多あるクラウドサービスを一元管理できるってなんて夢のツールだろう。

Terraformは、v0.2.2を使用。

すでに試している方がいるので、それも参考に。

Terraform 0.2 で Google Compute Engine を試してみた (初級編) - Qiita

試してみたファイルはGithubに。

tkak/terraform-demo · GitHub

準備

Google Developers Consoleからaccount.jsonとclient_secrets.jsonをダウンロードする。初めて使うので、どこからファイルをダウンロードすればいいかわからなくて少しはまった。古いDashboardに画面遷移する必要があった。

account.json

Google Cloudのアカウント証明書。

"APIs & auth" -> "Credentials"のページ、"OAuth"の"Generate new JSON key"ボタンからダウンロード。もしまだOAuth Client IDを作ってなかったら、"Create new Client ID"ボタンから新しく作成してからJSONファイルを作成する。

client_secrets.json

Google Cloud APIsを利用するためのクライアント情報。

"APIs & auth" -> "APIs"のページ、歯車マークのボタンから別ページに遷移して、"API Access"のページ、"Download JSON"からダウンロードする。

2つのファイルは適当に作業ディレクトリ配下に。

$ ls
account.json client_secrets.json

instanceの作成。

まず試しにinstanceを一つ作ってみる。

作業ディレクトリにtfファイルを作成する。

$ vim google_compute.tf
provider "google" {
    account_file = "./account.json"
    client_secrets_file = "./client_secrets.json"
    project = "tkakfrkw"
    region = "asia-east1-a"
}

resource "google_compute_instance" "default" {
    name = "test"
    machine_type = "f1-micro"
    zone = "asia-east1-b"

    disk {
        image = "debian-7-wheezy-v20140814"
    }

    network {
        source = "default"
    }
}

planでこれから行う作業の確認。

$ terraform plan
Refreshing Terraform state prior to plan...


The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ google_compute_instance.default
    disk.#:                     "" => "1"
    disk.0.image:               "" => "debian-7-wheezy-v20140814"
    machine_type:               "" => "f1-micro"
    metadata_fingerprint:       "" => "<computed>"
    name:                       "" => "test"
    network.#:                  "" => "1"
    network.0.internal_address: "" => "<computed>"
    network.0.name:             "" => "<computed>"
    network.0.source:           "" => "default"
    tags_fingerprint:           "" => "<computed>"
    zone:                       "" => "asia-east1-b"

applyで実際の処理を実行。

$ terraform apply
google_compute_instance.default: Creating...
  disk.#:                     "" => "1"
  disk.0.image:               "" => "debian-7-wheezy-v20140814"
  machine_type:               "" => "f1-micro"
  metadata_fingerprint:       "" => "<computed>"
  name:                       "" => "test"
  network.#:                  "" => "1"
  network.0.internal_address: "" => "<computed>"
  network.0.name:             "" => "<computed>"
  network.0.source:           "" => "default"
  tags_fingerprint:           "" => "<computed>"
  zone:                       "" => "asia-east1-b"
google_compute_instance.default: Creation complete

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate

showでインフラの状態を確認。

$ terraform show terraform.tfstate
google_compute_instance.default:
  id = test
  disk.# = 1
  disk.0.image = debian-7-wheezy-v20140814
  machine_type = f1-micro
  metadata_fingerprint = iyTlDGmC25M=
  name = test
  network.# = 1
  network.0.internal_address = 10.240.150.255
  network.0.name = nic0
  network.0.source = default
  tags_fingerprint = 42WmSpB8rSM=
  zone = asia-east1-b

f:id:keepkeptkept:20141005150747p:plain

できてる、できてる。

ちなみに、terraform.tfstateファイルはバイナリファイル。v0.3.0からはjsonになるっぽい。

$ file terraform.tfstate
terraform.tfstate: data

instanceの削除

instanceを削除してみる。

instanceの部分をコメントアウト

$ vim google_compute.tf
provider "google" {
    account_file = "./account.json"
    client_secrets_file = "./client_secrets.json"
    project = "tkakfrkw"
    region = "asia-east1-a"
}

/*
resource "google_compute_instance" "default" {
    name = "test"
    machine_type = "f1-micro"
    zone = "asia-east1-b"

    disk {
        image = "debian-7-wheezy-v20140814"
    }

    network {
        source = "default"
    }
}
*/

plan, apply, show。

$ terraform plan
efreshing Terraform state prior to plan...

google_compute_instance.default: Refreshing state... (ID: test)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

- google_compute_instance.default

$ terraform apply
google_compute_instance.default: Refreshing state... (ID: test)
google_compute_instance.default: Destroying...
google_compute_instance.default: Destruction complete

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

$ terraform show
The state file is empty. No resources are represented.

JSON形式で試す

tfファイルはJSON形式でも定義できるので、拡張子.tf.jsonのファイルを用意する。上のtfファイルと同じ処理をするJSONは以下の通り。

$ vim google_compute.tf.json
{
    "provider": {
        "google": {
            "account_file": "./account.json",
            "client_secrets_file": "./client_secrets.json",
            "project": "tkakfrkw",
            "region": "asia-east1-a"
        }
    },

    "resource": {
        "google_compute_instance": {
            "default": {
                "name": "test",
                "machine_type": "f1-micro",
                "zone": "asia-east1-b",

                "disk": {
                    "image": "debian-7-wheezy-v20140814"
                },

                "network": {
                    "source": "default"
                }
            }
        }
    }
}

plan, apply, showしてみたが特に問題なく実行できた。JSON形式対応してくれるのはかなりいい機能だと思う。 他のサービスからJSON出力させて、botにterraformを実行させるみたいなこともできそう。

まとめ

ここ最近Terraformっぽいツールが欲しいと思っていて自作しようとしてたところに、彗星のごとくMichell Hashimoto先生の新作が降ってきた。最近ではAWS以外にもGoogleMicrosoft、Degital Oceanなどのクラウドサービスがよくなってきていて、ハイブリッドにクラウドを利用する時代がきているのかもしれない。そんな時代にあった良いツールを出してくるHashimoto先生はさすがだと思った。

Packer + ChefDK + Docker(kitchen-docker)で、Chef Cookbookの開発環境整備を楽にする。

ChefのCookbookを書き始めるには結構準備することが多くて、Cookbookの開発環境を作るのがなかなかつらい。手元のPCにVirtualBoxVagrantを用意し、rbenvやBundlerの使い方を学び、必要なgemをインストールする。Chefだけでも学習コストが高いのに、周辺のツールを使いこなすのにさらに学習コストがかかる。しかも、社内にはWindowsユーザとMacユーザが混在してるので、その辺を仮想環境を使ってうまく抽象化したい。

そんな動機から、Packer + ChefDK + Docker(kitchen-docker)で、気軽にChefのCookbook開発を始められる環境を作ってみた。これでCookbook開発が捗る!(詳細はgithubを参照。)

今更Chef Cookbookベストプラクティス

去年Chefが大流行して今更Chefの話を書くのも恥ずかしい気がするけど、@kajikenからリクエストがあったので、僕が思うChefのCookbookのベストプラクティスを書いてみる。

Berkshelf way

まずはBerkshelf について。BerkshelfはCookbookの依存関係を解決してくれる便利ツール。基本的にCookbookはプロジェクトとは別なリポジトリで管理して、プロジェクトごとに必要なCookbookをBerkshelfで取ってきて使うのがいいと思う。Cookbookのバージョン管理を厳密にできるので、毎回同じサーバ環境が構築できる。あと、人が作ったCookbookを使い回せるので、車輪の再発明しなくてすむ。素晴らしい。

ただ、Berkshelfはバージョンが3系になって、Berkshelf用のAPIサーバを立てないといけないので、僕は未だに2系を使ってる。Chefを使う人や管理するCookbookが多くなってきたらAPIサーバをたてたほうがいいと思う。

あと、これはちょっとしたTipsになるけど、Berksfileはrubyのファイルになってるので、cookbookごとにgitのブランチを指定するよりも、こんな感じできれいにかくことができる。

# before
cookbook 'mysql', git: 'https://github.com/tkak/hoge.git'
cookbook 'nginx', git: 'https://github.com/tkak/fuga.git'
cookbook 'vim', git: 'https://github.com/tkak/piyo.git'


# after
def oreno_cookbook(name, options = {})
  cookbook(name, {
    git: "https://github.com/tkak/#{name}.git"
  }.merge(options))
end

oreno_cookbook 'hoge'
oreno_cookbook 'fuga'
oreno_cookbook 'piyo'

Cookbookの粒度

基本的に一つのCookbookは一つのリポジトリで管理するべき。馬鹿でかいCookbookを作ったりするとメンテナンスが大変になることが多いので避けた方がいい。ただ、一つのCookbookにどこまで処理を盛り込めばいいのか、Cookbookの粒度について時々迷うことがある。とりあえず、最初から大きなCookbookにするのではなく、最低限の機能を持つCookbookを何個か作って、そのあとそれらをまとめたCookbookを作ればいいと思う。

Cookbookをタイプ別にわけるとこんな感じになる。

Element Cookbook

最低限の機能、それ自体で完結するCookbook。

Library Cookbook

recipeが存在しない、Definitions, LWRPs, Librariesで構成されたCookbook。

Wrapper Cookbook

他のCookbookをラッピングするCookbook。

Role Cookbooks

Roleを定義するためのCookbook。基本的にRoleは使わない、バージョン管理ができないから。代わりにRole Cookbookを使う。

# oreno_app/recipes/base.rb
include_recipe "hoge"
include_recipe "fuga"
include_recipe "piyo"

# oreno_app/metadata.rb
name             'oreno_app'
maintainer       'tkak'
maintainer_email 'hoge@mail.com'
license          'All rights reserved'
description      'role cookbook'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.0.1'
depends          'hoge'
depends          'fuga'
depends          'piyo'

Cookbookの名前

Cookbookの名前は、-(ハイフン)を使わない。-だとLWRPがうまく動かないっていう地雷があるので、代わりに_(アンダースコア)を使ってる。あと、名前は動詞ではなく名詞になるようにしてる。

chef-repoの構成

oreno-chef-repo/
├── Berksfile
├── Gemfile
├── README.md
├── conf
├── cookbooks
│   ├── fuga
│   ├── hoge
│   └── piyo
├── data_bags
├── environments
└── site-cookbooks
    ├── oreno_app
    └── oreno_db

http://shibayu36.hatenablog.com/entry/2014/08/04/073000chefリポジトリ構成はこんな感じ。特にcookbookssite-cookbooksは、Berkshelfで取ってきたCookbookかそうでないかの違いで分けてる。cookbooksにはBerkshelfで取ってきたcookbooks、site-cookbooksには自分のアプリ用のcookbooksを配置する。Berkshelfのデフォルトでは、.cookbooks配下にCookbookが置かれるが、cookbookの場所を明確にしておきたいのであえてberks install --path cookbooksでインストールしている。

CookbookのTestについて

CookbookのTestはServerspecを使ってる。深淵な理由でTest-kitchenは使ってない。ProxyとかProxyとかProxyとか。CIは、Jenkins + Vagrant + Chef + Foodcritic + Serverspecでまわしてる。よくある感じ。

アプリケーションレイヤーのCookbookはDockerを使って開発するのがいいと思ってはいるが、まだVMを多用している。毎回VMの起動に時間がかかるので早くコンテナを導入したい反面、OSのカーネルに依存するような部分のCookbookに関しては地道にVMを使うしかないのかなぁ、なんて感じてる。適材適所で使うのは全然ありだと思う。

まとめ

2、3年前くらいからChefを使い初めたんだけど、何度Cookbookを書き直したか分からない…w 試行錯誤してようやく今の形に落ち着いた感じ。これからChefを導入する人やCookbookを書き直す人の参加になれば幸いです。もう少し知見ある気がするけど、疲れたので今日はこの辺で。でわでわ。

あ、Chefの使い方とかかなり詳しく知りたい時は、「Chef活用ガイド」がオススメです。かなり細かくChefについて書いてあります。ちょっとした国語辞典並みの厚さですがw よかったらぜひ手に取ってみてください。

Chef活用ガイド コードではじめる構成管理

Chef活用ガイド コードではじめる構成管理

VagrantでVMware vSphere(ESXi)上のVMを操作する「vagrant-vsphere」を試してみた。

Vagrantのproviderは、VirtualBoxAWSなど様々ありますが、VMware vSphere(ESXi)用のvagrant-vsphereを試してみたので備忘録として残しておきます。

Installation

まずは、vagrant-vsphere pluginのインストールから。githubのREADMEに書いてますが一応。

$ vagrant plugin install vagrant-vsphere

Prepare dummy box

次にダミー用のboxイメージを作成します。vsphereを使う場合は、virtualboxとは違ってローカルにboxイメージは置きません。

$ cd ~/.vagrant.d/gems/gems/vagrant-vsphere-0.8.2/example_box/

example_boxディレクトリ配下にmetadata.jsonファイルがあるので、それをtarコマンドで固めます。

$ cat ./metadata.json
{
  "provider": "vSphere"
}

$ tar cvzf dummy.box ./metadata.json

作ったboxは、適当なディレクトリに配置します。例えばプロジェクトのrootに置く場合。

$ ls
Vagrantfile
Vagrantfile.virtualbox
Vagrantfile.vsphere
dummy.box
cookbooks/
nodes/
roles/
conf/
...
...

Prepare a template in vShpere

次に、VMのひな形になるboxを用意します。以下のリンクを参考に、vSphere上にクローン用のテンプレートイメージとCustomization Specificationを作成します。

Vagrant up

準備が終わったのでVMを作成します。 Vagrantfileはこんな感じで用意します。

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

Vagrant.configure("2") do |config|
  config.vm.box = 'dummy'
  config.vm.box_url = './dummy.box'
  config.vm.synced_folder ENV["SYNCED_FOLDER"], "/vagrant"
  config.vm.network 'private_network', ip: 'x.x.x.x'
  config.ssh.host = 'x.x.x.x'

  config.vm.provider :vsphere do |vsphere|
    vsphere.host = 'HOST NAME OF YOUR VSPHERE INSTANCE'
    vsphere.data_center_name = 'YOUR DATACENTER'
    vsphere.compute_resource_name = 'YOUR COMPUTE RESOURCE'
    vsphere.resource_pool_name = 'YOUR RESOURCE POOL'
    vsphere.data_store_name = 'YOUR DATA STORE'
    vsphere.template_name = 'YOUR VM TEMPLATE'
    vsphere.name = 'NEW VM NAME'
    vsphere.user = 'YOUR VMWARE USER'
    vsphere.password = ENV["VSPHERE_PASSWORD"]
    vsphere.insecure = true
    vsphere.template_name = 'YOUR TEMPLATE NAME'
    vsphere.customization_spec_name = 'YOUR CUSTOMIZATION SPEC'
  end

end

ENV["SYNCED_FOLDER"]とENV["VSPHERE_PASSWORD"]は、Vagrantfileに直接書きたくないので、環境変数にしてます。 VMを作成する時に指定する感じです。

$ export SYNCED_FOLDER=/your/path
$ VSPHERE_PASSWORD=**** vagrant up --provider=vsphere
$ vagrant ssh

あとは普通に、vagrant sshvagrant destroyとか動きます。vagrant自体の細かい使い方は省略します。

Wrap up

vagrant-vsphereを試してみました。vSphere上のVM作成をコマンドラインからやりたいときに便利です。 (fogのvsphere providerも試してみたんですが、うまく動かなかったのでこっちにしました。)

今では、Chef cookbookのCI環境用に使ってます。 このplugin自体あんまり使ってる事例とかがなくて、試行錯誤しながらとりあえず動くところまではできたのでよかったです。 同じように困っている人がこのブログがお役にたてれば幸いです。ではでは。

References

Proxy環境下でDockerを使う。

Proxy環境下でDockerを使ってみたのでメモ。

使った環境はこんな感じ。

Dockerデーモンを起動するときに、環境変数でproxyの設定をする。

# http_proxy=http://hoge:1234 docker -d &

起動スクリプトからDockerを起動するときは、/etc/sysconfig/dockerファイルでproxyの設定を行う。

# cat > /etc/sysconfig/docker
export http_proxy="http://hoge:1234/"
# service docker start

追記2 (Jul 10, 2014)

CentOS 7.0編

  • OS: CentOS 7.0 1406 x86_64
  • Kernel: 3.10.0-123
  • Docker: 1.0.0-1
# cp /usr/lib/systemd/system/docker.service /etc/systemd/system/
# vi /etc/systemd/system/docker.service
...
...
Environment=‘http_proxy=http://hoge:1234/’  ## ExecStartの上に追記
ExecStart=/usr/bin/docker -d --selinux-enabled -H fd://
…
...
# systemctl daemon-reload
# systemctl restart docker

追記 (Jul 5, 2014)

Ubuntu 14.04編

  • OS: Ubuntu 14.04 amd64
  • Kernel: 3.13.0-24-generic
  • Docker: 1.1.0
$ sudo sh -c "echo 'export http_proxy=http://hoge:1234/' >> /etc/default/docker"
$ sudo service docker restart

個人的#ChefConf2013まとめ。

f:id:keepkeptkept:20130429101710j:plain

最近日本でも何かと話題になっているconfiguration management toolのchefですが、やっぱり海外のほうがDevOpsが進んでますね。
今回のカンファレンスは、導入事例とかベストプラクティスな感じの話が多かったです。

個人的に面白かったセッションを5つ、ログとして残しておきます。

#ChefConf 2013

Scaling Configuration Management

つい最近facebookでPrivate Chefを導入したとかニュースになってましたが、
初日のメインセッションでfacebookのchef導入事例の話をしてました。

facebookのサーバ管理メンバーが、目指すところは以下な感じです。規模感がすごいですね。

  • 4 people
  • Tens of thousands of heterogeneous systems
  • Service owners own/adjust relevant settings

主にscalabilityなchefをどうやって実装するかについて話してました。

■node.save()問題

facebookでは15分ごとにconvergenceを実行してChef Serverにnode情報を送っているらしいんですが、15,000台ものnodeを管理するとなると、その通信データ量は馬鹿にならないみたいです。

そこで、

  • 簡単にできる解決方法としてはohaiのpluginを無効にする方法があるが、ohaiのdataは欲しい。
  • ただし、chef serverにnode情報はなくてもいい。
  • つまり、node.save()機能を使うけど、サーバに送信しなければおk

ということで、
解決方法 = whitelist_node_attrs
opscode-cookbooks/whitelist-node-attrs · GitHub

このcookbookを使って、node.save()機能の送信するデータを制限して、結果的にサーバに送信するデータを1kb以下になるようにしたらしいです。

■method_missing問題

nodeのメソッドを使おうとしてそのメソッドの定義がない場合、
Chefは勝手にアトリビュートを作ってそこにハッシュ値を入れてしまうようです。

node.foo('bar')
  • Ruby: "If there a method foo()?"
  • Chef: "If not, is there an attribute foo?", "If not, create; assign bar"
  • OK for...
node['foo'] = 'bar'
node.foo = bar
  • But imagine
node.has_key('foo')  # want has_key?()

そこで、以下のようなメソッドを作ったみたいです。

class Chef::Node
  def method_missing(method, *args)
    Chef::Log.warn(“FB Chef Tweak: Not assuming missing method is an attr!”)
    Object.send(:method_missing, method, args)
  end
end
■sysctlのcookbook

facebookで使っているsysctlのcookbookの例を紹介してました。

  • fb_sysctl/attributes/default.rbにすべてのdefaultのパラメータを定義
  • fb_sysctl/recipes/default.rbに、templateリソースを定義
  • fb_sysctl/templates/default/sysctl.erbは、3行
# Generated by Chef, do not edit directly!
<%­ node['fb']['fb_sysctl'].keys.sort.each do |key| %>
<%= key %> = <%= node['fb']['fb_sysctl'][key] %>
<%­ end %>

そのcookbookをさらにDBサーバのcookbookを作って、database/recipes/default.rbの中でattributeをオーバーライドして使うそうです。

node.default['fb']['fb_sysctl']['kernel.shmmax'] = 19541180416
node.default['fb']['fb_sysctl']['kernel.shmall'] = 5432001
■Open Source Chef (OSC)と Opscode Private Chef (OPC)の性能比較

OSCよりもOPCのほうが性能いいらしいです。
詳細は、スライドにグラフとか掲載しているのでそっちを参考にしてください。

OSCのほうは、カスタマイズして使っていて、scaleのために、Chef Serverのsearchとdatabags機能を使ってないらしいです。

Client監視用に取得する情報

  • Last exception seen
  • success/failure of run
  • number of resources
  • time to run
  • time since last run
  • other system info

Server sideの監視

  • stats(postgres, authz[OPC], etc)
  • Errors(nginx, erchef, etc)
  • more...

server side の監視のためのutilsをgithubに公開してます。
facebook/chef-utils · GitHub


Cookbook refactoring & abstracting logic to Ruby(gems)

/etc/hostsを設定するcookbookを例に、リファクタリングの話をしていました。

最初は一般的な、attributes, recipes, templatesの構成ですが、どんどんリファクタリングをしていって、最終的にはcookbookをgemにするところまでやっててすんごいなぁと思いました。そこまでする必要があるかどうかは、賛否が分かれるところです。

1. attributes, recipes and templates
2. attributes -> data bags
2. Provider and Resources for simple
3. Libraries for speed and test
4. pure ruby (gem) for multi-environment

最終的なhostsfile cookbookは、githubに公開しています。
customink-webops/hostsfile · GitHub


Writing a Knife Plugin for your shiny new VMWarevCloud Director

VMWarevCloud Director用のknifeプラグインを作ったという話でした。
個人的にknifeのpluginよりも、中で使っているFogというMulti-Cloud Service Libraryが気になりました。
特にvmwareAPIrubyでたたけるので、まじですごいです。すんごい使えそうです。
ちなみに、vagrantのaws pluginもこのfog使ってます。

Fog - Multi-Cloud Service Library
fog - The Ruby cloud services library

opscode/knife-vcloud · GitHub

rlane/rbvmomi · GitHub


The Berkshelf Way

Berkshelf作った人が、berkshelfの話をしてくれました。
プレゼンテーションの仕方がうまくて面白くて、楽しんで聞けました。

■berkshelfの名前の由来

もともとは、bookshelfにしようと思ったけど、googleで検索しても他のものが検索されるので、berkshelfにしたらしいです。berkはアメリカで有名なネタ画像をもとにしたらしいです。

■berkshelfを使ったcookbookの使い方

roleは使わないで、cookbookをラップするcookbookを作ってroleの代わりにする使い方がいいらしいです。
roleは、バージョン管理できないし、パッケージとして配布できないし、namespaceが厳密ではないし、組織レベルのデータしか扱えないから。

■testについて

testはvagrantを使って、berkshelfのvagrant pluginがあるので、それを使ってテストしてるそうです。

How A Mouse Became a Chef - Disney

  • Chris Putonen -- Senior Manager, System Engineering at The Walt Disney Co.
  • Brian Scott -- Staff Systems Engineer at The Walt Disney Company
  • Steven Wagner -- Staff Systems Engineer at The Walt Disney Company

Disneyのchef導入事例の話です。
導入するときの話から、かなり具体的なcookbookの書き方やテストについてまで、とてもためになりました。

  • トップダウンでchefを導入していった。
  • Devsのアジャイルが進んでいって、Opsもそれについていかなくてはならない
  • Picking a tool + Changing our culture
  • start small and simple, lean start approach
  • pluginも自分たちで作っている。例、knife-servicedesk, ohai network_location
  • f5とNexusなどネットワーク機器もchefで管理
  • ChefのTest環境、Remy、Test as a Serviceを提供しようとしている。
  • ChefのTest環境は、jenkinsとvagrantとopnstackを使ってる。virtual boxよりもopnstackのほうが早い。

アフィリエイトソンに参加してきた。

Web APIを使ったECサイトを開発してアフィリエイト収入で小遣い稼ぎをしましょうというコンセプトのアフィリエイトソンなるイベントに参加して来ました。

【楽天・ヤフー・リクルート3社共催】第1回アフィリエイトソン -開発して稼ごうお小遣い!-(4/5,6) | 集客ならイベントアテンド

いやぁ、チームで開発するって楽しいですね。
日頃会社ではOps側の仕事が中心なので、Devの人と一緒に開発ができるなんてとても新鮮な経験をさせていただきました。特に今回perlで開発したんですが、perlフレームワークとか全然知らなくて、とても得るものが多かったです。

学んだこと、ちょっと残しておきます。

Perlの開発環境

今回ノープランでハッカソンに参加したので、Perlの開発環境を整えるところからスタートしました。
事前にやっておけよっていう話ですが...^^;

perlbrew+perl

まずperlbrewとperlをいれます。
perlbrewは複数のバージョンのperlを切り替えるためのツールです。rubyでいうrenv+ruby-buildとかrvmとかと同様のものです。
defaultでは、~/perl5/perlbrewにインストールされます。

$ curl -kL http://install.perlbrew.pl | bash
  • .zshrc にsource ~/perl5/perlbrew/etc/bashrcを追加する。
$ source .zshrc
$ perlbrew init
$ perlbrew install perl-5.16.2 --as perl-5.16
$ perlbrew switch perl-5.16.2

この辺を参考にしました。
安定的な Perl アプリケーション運用のための perlbrew 運用テクニック - tokuhirom's blog.

cpanm+carton

次にcpanmとcartonをいれます。
cpanmは、CPAN::Shellの次世代版みたいなもので、より省メモリで動作するそうです。
cpanmについてはここを参考にしました。
perlモジュールのinstallにcpanmを使う|perl|@OMAKASE

$ perlbrew install-cpanm

cartonは、rubyでいうbundlerのようなものです。
プロジェクトごとにモジュールをわけたり、モジュールのバージョンを環境ごとにあわせたりすることができるので、便利です。
モジュールは、project/local/lib/perl5/配下にインストールされます。
cartonについてはここを参考にしました。
cpanm ってなんですか? carton ってなんですか?利点はなんですか? - tokuhirom's blog.

$ cpanm Carton
$ cat cpanfile
requires 'Plack', 0.9980;
requires 'Starman', 0.2000;
$ carton install
$ ls carton.lock ## installに成功するとできる。
$ carton exec -Ilib -- plackup -p 8080 myapp.psgi

carton でインストールされたモジュールで実行できるものは、carton exec で実行できます。
オプションは、"--"のあとに指定します。

Webサーバとフレームワーク

今回perlで開発したのでPlackとAmon2を使いました。

$ carton exec plackup app.psgi -- --port 8080 -R

memo
PSGIという仕様の実装版がPlack。
plackupでサーバを起動します。
起動するときにapp.psgiファイルを指定します。
--portでポートを指定することができます。
-Rで、実行配下のファイルの更新をチェックして、サーバの動作に反映してくれます。

フレームワークのAmon2に関してはまだあまり知らないので、後日追記します。

MongoDB

今回DBまわりは、MongoDBを使いました。
MongoDBは、クエリにJSONファイルを使えるので、テーブル設計とか意識せずにとりあえずデータをなんでも突っ込んでおけて便利です。スタートアップとかに向いてるみたいです。

セットアップはここを参考にしました。
Installing MongoDB — MongoDB Manual 2.4.1

あとがき

残念ながら、昨日一日ではサービスをリリースすることはできなかったんですが、
隙をみてなんとかリリースするところまでは持って行きたいです。
そして、お小遣い稼ぎできたらなぁなんて考えてます。

開発もできて小遣い稼ぎもできるなんてなんて素晴らしいイベントだろう。
もし次回があればまた参加したいですね!