読者です 読者をやめる 読者になる 読者になる

mazinlabsのブログ

RubyとかCloudとかその辺の記事を書いたり書かなかったり

「大企業におけるIT芸人としての生き方」というLTをしてきた

ものすごい久しぶりの更新で誰が見てるのかわからないけど元気に生きてます。

更新しようとは思っていたんだけどなかなか個人としてのアウトプットがなかったのですが、 久しぶりにアウトプットがあったので更新してみた。

先月、弊社にインターンシップの学生さんが来られており、 不定期に金曜日のお昼にやっているTechLunchと言う弊社内の技術者向けの勉強会で、 「大企業におけるIT芸人としての生き方」というLTをしてきました。

私の生き方は多くの人に「参考にならない」と言われてるけど、生きていた証として残しておきます。

mooと打つと”スーパー牛さんパワー!”を返すhubot scriptを作ってみた

なんとなくSlackを眺めていて、ふとチャンネルにいるHubotに"moo"と打ったところ反応がなかった。

f:id:mazinlabs:20150713175823p:plain

ないとなるとなんとなく欲しくなってくる。

f:id:mazinlabs:20150713175834p:plain

というわけで作ってみた。

github.com

以下動作サンプル

hubot-moo-script> hubot-moo-script moo
         (__)
         (oo)
   /------\/
  / |    ||
 *  /\---/\
    ~~   ~~
...."Have you mooed today?"...
hubot-moo-script> hubot-moo-script moo moo
         (__)
         (oo)
   /------\/
  / |    ||
 *  /\---/\
    ~~   ~~
...."Have you mooed today?"...
hubot-moo-script> hubot-moo-script moo moo moo
         (__)
         (oo)
   /------\/
  / |    ||
 *  /\---/\
    ~~   ~~
...."Have you mooed today?"...
hubot-moo-script> hubot-moo-script moomoo
         (__)
         (oo)
   /------\/
  / |    ||
 *  /\---/\
    ~~   ~~
...."Have you mooed today?"...

我ながら、しょうもないもの作った。 なんか追加要望があれば聞きます!

追記(7/14):

  1. 動作をhearからrespondに変えました。
  2. Slackに流すと1行目のスペースが削られるので```でくくりました

「AnsibleとServerspecではじめるInfrastructure as Code」というお話をしてきました

先日社内の勉強会で「AnsibleとServerspecではじめるInfrastructure as Code」というお話をさせていただいたので、その資料を貼っておく。

元々はSlideShareを使っていたのだが、最近になってスライドを見終えると別のスライドに飛ばされるのが嫌になったのでSpeakerDeckに乗り換えようとしているところ。

AnsibleSpecの話とかもしようと思ったけど、自分の知識が古いのとあまりメンテがされてなさそうに見えたので今回は保留。 また機械があったらどこかで勉強しなおしてお話するかも?

VagrantでChef Soloのバージョンを指定する方法

あらまし

VagrantでChef soloを使っているとエラーが出た。

ERROR: undefined method `sensitive' for Chef::Resource::Template

ここを見るとどうもChef soloのバージョンが古いようなのでアップデートしようとしたのでその手順をまとめてみた。

流れ

まずエラーの確認。

==> rqbbitmq1: [2014-12-26T06:11:38+00:00] INFO: Forking chef instance to converge...
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] DEBUG: Forked instance now converging
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] INFO: *** Chef 11.8.2 ***
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] INFO: Chef-client pid: 1921
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] DEBUG: Building node object for rabbitmq1

...

[2014-12-26T06:11:39+00:00] ERROR: undefined method `sensitive' for Chef::Resource::Template

sensitiveというメソッドがないというのが原因と言われるが、Chefのドキュメントには載っている。

同じエラーでぐぐってみると以下の記事が見つかった。

ChefのMySQLクックブックでNoMethodError: Undefined Method `sensitive' for Chef::Resource::Executeの対処

そこではChefのsoloのバージョンが古いので上げれば動くようになると書いてあったが、Vagrantでchef soloのバージョンを上げる方法がわからないので調べる。

Vagrantのchef soloについてのドキュメントを見るとversion指定でいける模様。

conf.vm.provision :chef_solo do |chef|
  chef.log_level      = :debug
  chef.json           = load_node_json(conf.vm.hostname)
  chef.cookbooks_path = %w(../ berks-cookbooks)
  chef.version = '11.16.4'
end

実行

VagrantPlugins::Chef::Config::ChefSolo
Bringing machine 'rqbbitmq1' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:

chef solo provisioner:
* The following settings shouldn't exist: version
* The following settings shouldn't exist: version

なんかversionがないと怒られた。 ドキュメントを読み直すとinstallオプションにforceを指定しないといけない模様なので指定してみる。

conf.vm.provision :chef_solo do |chef|
  chef.log_level      = :debug
  chef.json           = load_node_json(conf.vm.hostname)
  chef.cookbooks_path = %w(../ berks-cookbooks)
  chef.install = 'force'
  chef.version = '11.16.4'
end

再度実行

Bringing machine 'rqbbitmq1' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:

chef solo provisioner:
* The following settings shouldn't exist: install, version
* The following settings shouldn't exist: install, version

おかしい・・・動かない・・・ しかたがないのでソースコードを覗くためにGithubVagrantを見に行く。

どうやらこのコミットでversionとinstallが使えるようになったらしい。

versionは1.7.0からということで自分の手元を確認。

% vagrant -v
Vagrant 1.6.5

1.7以前だったのでバージョンアップ

% vagrant -v
Vagrant 1.7.1

これで上記のchef.install='force'chef.version='11.16.4'を指定したVagrantfileで再度実行

   rqbbitmq1: Installing Chef (11.16.4)...

無事に動いた。

結論

  • Vagrantのバージョンが1.7以降であればChef Soloのバージョンを指定してインストールが出来る
  • バージョンを指定したインストールをするために
  • Vagrantfileのprovisionでchef_soloを指定する
  • chef_soloの設定でinstall='force'version='任意'を指定する

参考

VagrantでCloudn Compute VPC (OpenNW)を操作する

背景

VagrantでCloudn Compute Flatは操作できるけど、VPC(OpenNW)が操作できないと周りで聞いたので解決できるかやってみた。

環境

最初に使った環境は以下のとおり

% vagrant -v
Vagrant 1.7.0

手順

vagrant-cloudstack pluginの導入

まず何にも用意がないのでまずはvagrant-cloudstackのプラグインを入れる。

% vagrant plugin install vagrant-cloudstack

無事に入ったことを確認

% vagrant plugin list                                                                                                                        
vagrant-cloudstack (0.10.0)
vagrant-share (1.1.3, system)

Vagrant用のテンプレートの作成 ~ Vagrantfileの作成

CloudnとVagrantを組み合わせて使う方法 を参考にさせてもらう。

が、何故か手元だとCloudmonkeyが動いてくれないので頑張って動かす。

MacでCloudmonkeyが動かなかったのでなんとかしてみた

動いたと思ったら、Cloudmonkeyの設定ファイルが変わっていたので設定の変更。

[core]
profile = server
...
[server]
apikey = your_apikey
secretkey = your_secretkey
url = https://vpcopennw-api.jp-e1.cloudn-service.com/client/api
expires = 600
timeout = 3600
verifysslcert = true

VagrantからCloudStackの操作に必要な情報をCloudmonkeyで拾ってくる。

> list templates templatefilter=self
template:
id = xxxx
name = vagrant  

> list vpcs
vpc:
name = xxx
id = xxxx

> list zones
zone:
name = jp-e1a
id = 80827400-840e-4e14-a0f3-54a998abff82

> list securitygroups
securitygroup:
id = xxxx

> list serviceofferings
serviceoffering:
name = m1.small
id = c6b72b0d-8541-474f-b617-e0051a9b6325

Vagrantfileを作成

Vagrant.configure(2) do |config|
  config.vm.box = "dummy"
  config.ssh.private_key_path = "~/.vagrant.d/insecure_private_key"

  config.vm.provider :cloudstack do |cloudstack, override|
    cloudstack.host       = 'vpcopennw-api.jp-e1.cloudn-service.com'
    cloudstack.path       = '/client/api'
    cloudstack.port       = 443
    cloudstack.scheme     = 'https'
    cloudstack.api_key    = 'xxxxx'
    cloudstack.secret_key = 'xxxxx'

    cloudstack.template_id         = 'xxxx'
    cloudstack.service_offering_id = 'c6b72b0d-8541-474f-b617-e0051a9b6325'
    cloudstack.zone_id             = '80827400-840e-4e14-a0f3-54a998abff82'
    cloudstack.security_group_ids  = ['xxxx']

    cloudstack.name = 'cloudn-openNW-instance'

    # ネットワークの種類と名前を指定
    cloudstack.network_type = 'Advanced'
    cloudstack.network_id   = 'xxxx'

    cloudstack.instance_ready_timeout = 300
  end
end

Vagrantの実行

準備はできたのでいざゆかん!

% vagrant up --provider=cloudstack
...
==> default: Waiting for instance to become "ready"...
==> default: Waiting for SSH to become available...

SSHがつながらなくてここから進まない・・・。 しかしながらWebコンソール上では元気に動いているように見えるので原因を考える。

・・・そうかVPCだから踏み台経由しないとインターネット越しだとつながらないのか。

というわけで、さっき起動したVMVPCの静的NATをかましてそこを踏み台に。

踏み台サーバにVagrantを導入

まずsshでアクセス

% -i ~/.vagrant.d/insecure_private_key vagrant@xxx.xxx.xxx.xx

めんどくさいのでrootに上がっておく。

% sudo su -

Vagrantを落としてくるためにwgetを導入してからVagrantを入手してインストール。 もちろんvagrant-cloudstackもインストールするのだがgccがないとvagrant-cloudstackがインストールできなくて困るのでgccも入れておく。

# yum install -y wget gcc
# wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.7.1_x86_64.rpm
# rpm -ihv vagrant_1.7.1_x86_64.rpm
# vagrant plugin install vagrant-cloudstack

これでVagrantが動く環境ができたので、あとはVagrantfileの用意をしなおす。

# mkdir cloudn-opennw
# cd cloudn-opennw
# vagrant init
# vi Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "dummy"
  config.ssh.private_key_path = "~/.vagrant.d/insecure_private_key"

  config.vm.provider :cloudstack do |cloudstack, override|
    cloudstack.host       = 'vpcopennw-api.jp-e1.cloudn-service.com'
    cloudstack.path       = '/client/api'
    cloudstack.port       = 443
    cloudstack.scheme     = 'https'
    cloudstack.api_key    = 'xxxxx'
    cloudstack.secret_key = 'xxxxx'

    cloudstack.template_id         = 'xxxx'
    cloudstack.service_offering_id = 'c6b72b0d-8541-474f-b617-e0051a9b6325'
    cloudstack.zone_id             = '80827400-840e-4e14-a0f3-54a998abff82'
    cloudstack.security_group_ids  = ['xxxx']

    cloudstack.name = 'cloudn-openNW-instance01' # 名前は上記のものと違うのを指定すること

    # ネットワークの種類と名前を指定
    cloudstack.network_type = 'Advanced'
    cloudstack.network_id   = 'xxxx'

    cloudstack.instance_ready_timeout = 300
  end
end

再挑戦

# vagrant up --provider=cloudstack
...
==> default: Waiting for instance to become "ready"...
==> default: Waiting for SSH to become available...
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if its present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine is booted and ready for use!
==> default: Rsyncing folder: /root/ => /vagrant

無事に起動できたので接続確認

# vagrant ssh
Thanks for using Official Template (CentOS).

====================================================
* Time Zone *
    Default TimeZone is UTC.
    You can change this with
      #sh /root/tzconfigurator.sh

* Stack (Application Set) *
    Default install apps is following.
      - ntp
      - acpiphp
      - password-agent
      - openssh-clients
      - wget
      - telnet
      - rsync

    You can update those apps to latest version with
      #yum update

    If you want to install some stack,
    you can install that with
      #sh /root/package_installer.sh

* To Change this message *
    please edit “/etc/motd”.
====================================================
[vagrant@cloudn-openNW-instance01 ~]$

無事にCloudnのOpenNW上に接続できるインスタンスVagrantから建てられた。

結論

  • VagrantからCloudnのOpenNWにインスタンスを建てることはできる。
  • インターネット越しだと起動までしかできない。
  • VPC内からであれば起動からアクセスまで可能
  • FlatタイプとOpenNWで多少のVagrantfileの変更が必要
  • OpenNWはNWタイプをAdvancedにしてNWのIDが必要
  • アクセス先のURLの変更が必要

おまけ

vagrant-cloudstackソースコードを眺めたけど、VPCを作る機能はなさそうだった。 というわけで、Vagrantを使う際は予めVPCとサブネットを作り、静的NATをしたインスタンスを用意した上でそのインスタンスからやってください。

参考

Ansible Configuration Fileのtransport=smartについて

今年の夏ぐらいからChefあらAnsibleに乗り換えてまあまあ使ってきました。 Chefと比較した場合のAnsibleの利点として、エージェントレスで動作するということが挙げられます。

このエージェントレスでの動作ですが、簡単に言うと毎回SSH(他のプロトコルも利用可能)でアクセスして接続先のホストでコマンドを発行して任意の操作を実行しているわけです。

しかし、タスクごとに毎回SSHのセッションを張るのでタスクが多くなってくると意外と遅い。

そこで設定transport=smartの出番です。というかこれデフォルトだとsmartらしい。

まずSSHのControlPersistについて軽く説明。 ControlePersistはOpenSSHの5.6から搭載された機能で、SSHの多重化接続の永続化をしてくれる機能らしい。 つまり、ControlPersistで指定した場合、永続化されたセッションを使うのでアクセスが早くなるという仕組みになっている。 また、ControlPersistはタムアウト設定を指定することも可能なので1mとすると1分間アクセスがない場合は自動的にセッションが切れる。

で、話をtransport=smartに戻す。 transport=smartSSHのControlPersistが利用可能(OpenSSH 5.6以降)な場合はOpenSSHを利用し、ControlPersistが使えない場合はPythonSSHライブラリであるparamikoを使うという設定らしい。

まぁ、実を言うとOpenSSH 5.6以降がデフォルトで入ってるのはEnterprise Linux 6というかRHELの6とかCentOSの6なんでそれ以外だとControlPersistが有効になっているはず。 それでも遅いなと思う人や1分以上処理に時間が掛かる(パッケージインストール等)をする人は、設定ファイルのssh_argsで以下のように設定すると幸せになれるかも。

ssh_args = -o ControlMaster=auto -o ControlPersist=30m

公式的には30分がおすすめらしい。

結論

  • 設定ファイルにtransport=smartを明示しなくてもデフォルトでsmartが適用されている
  • OpenSSH 5.6以上を使うとAnsibleのタスクが早くなる
  • Enterprise Linux 6(RHEL6, CentOS6)はデフォルトだとOpenSSH 5.6以下なので自力で何とかする
  • 処理に時間が掛かるタスクがある場合はssh_argsControlPersist=30mを設定しておく

参考

MacでCloudmonkeyが動かなかったのでなんとかしてみた

cloudmonkeyで遊んでみようとしたら、エラーが出て動かなかったのでなんとかしてみた。

まずはcloudmonkeyのインストール

% sudo pip install cloudmonkey

そして実行するとエラーはこんな感じにでてくる。

% cloudmonkey
Traceback (most recent call last):
  File "/usr/local/bin/cloudmonkey", line 5, in <module>
    from pkg_resources import load_entry_point
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 2603, in <module>
    working_set.require(__requires__)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 666, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 565, in resolve
    raise DistributionNotFound(req)  # XXX put more info here
pkg_resources.DistributionNotFound: requests

なんかrequestsのパッケージが見つからない的なことを言っているのでいれてみる。

% sudo pip install requests
Requirement already satisfied (use --upgrade to upgrade): requests in /Library/Python/2.7/site-packages
Cleaning up...

すでに入っている。。。

とりあえずググるとこんなのが出てくる。

pip - DistributionNotFoundエラーの対処方法 - Qiita

pipをアップグレードしてみる。

% sudo easy_install --upgrade pip

これでも動かない。

さらにぐぐる

python - No module named pkg_resources - Stack Overflow

これで動いた。

% pip install --upgrade setuptools
% pip install --upgrade distribute
% cloudmonkey
Selected profile (local) does not exist, using defaults
Missing configuration was set using default values for keys:
`profile = local, asyncblock = true, paramcompletion = true, history_file = /Users/Mahito/.cloudmonkey/history, cache_file = /Users/Mahito/.cloudmonkey/cache, log_file = /Users/Mahito/.cloudmonkey/log, color = true, prompt = 🐵 > , display = default` in /Users/Mahito/.cloudmonkey/config
☁ Apache CloudStack 🐵 cloudmonkey 5.3.0. Type help or ? to list commands.

Using management server profile: local

(local) 🐵 >

どうも入ってたrequestsかdistributeのバージョンが古かったのかなという気がする。

何はともあれ動いてよかった。