LoginSignup
4
4

More than 5 years have passed since last update.

Chef Provisioningを使ってUbuntuのVSO Agentサーバをプロビジョニングしてみる

Last updated at Posted at 2015-09-10

Chef Provisioningを使ってUbuntuのVSO Agentサーバをプロビジョニングしてみる

Visual Studio Onlineのビルド機能は結構イケてる。想像もしていなかったが、実はWindows系だけではなく、UbuntuとかMacなどのビルドもできたりする。

SnapCrab_Microsoft Visual Studio Online ‎- Microsoft Edge_2015-9-10_23-21-10_No-00.png

ただし、Ubuntuでビルドしたい場合、Visual Studio Online(以下VSO)のエージェントを入れたビルドサーバーを作る必要がある。本番でAgentを入れたビルドサーバーをいちいちつくるのは面倒だ。
そこで、今回、AzureとChef-Provisioningを使って実際にあるプロジェクトのビルドサーバーを自動でプロビジョニングするコードを書いてみた。

SnapCrab_Microsoft Visual Studio Online ‎- Microsoft Edge_2015-9-10_23-20-51_No-00.png

今回題材につかっているのはHOL - Parts Unlimited MRP App Continuous Integration with Visual Studio Online Build
にあるこのプロジェクトをVSOをつかってビルドする手順をUbuntuのバーチャルマシンを払い出すところから自動化してみることにした。

SnapCrab_Parts Unlimited MRP! ‎- Microsoft Edge_2015-9-11_1-6-10_No-00.png

1. 事前準備

さて、事前準備としてはAzure CLIがインストールされて、設定されている必要がある。この詳細は次のページに書いておいたので参考にされたい。

Azure CLIとChefを始めるためのSubscription関係まとめ

ほかにはGitが必要だ。この手順はWindows10で作成したが、コマンドラインのコマンドはMacも同じなので、読みかえていただければMacでも動作すると思われる。

Git for Windows

2. ChefDKのインストール

これもWindows10の手順だが、ChefDKをインストールしたい。

まずその前にWindowsでもコマンドラインでごそごそといろいろ入れられるツールChocolateyをぶち込んでおいて、それでChefDKも入れてみよう。

2.1. Chocolatelyをダウンロードする

Chocolateyのページにいくつかの方法が載っている。私はcmd.exeを管理者モードで動かして、次のコマンドを打つ方法を採用した。

 @powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

2.2. ChefDKのインストール

このツールを入れておくと、次のようにコマンドラインでいろいろなアプリケーションをインストールできる。たまにバージョンが古いものしかない場合もあるので注意が必要だ。Chocolateyのページでバージョンがご希望のものか検索してみよう。
SETXコマンドでパスを永続的に設定できるようだ。入れただけだとパスは通らない様子。

> choco install chefdk -y
> SETX /M PATH "%PATH%;c:\opscode\chefdk\bin"
> SETX /M PATH "%PATH%;c:\opscode\chefdk\embedded\bin"
> SET PATH=%PATH%;c:\opscode\chefdk\bin;c:\opscode\chefdk\embedded\bin"

2.3. Chef-Provisioning-Azureのインストール

次にChef-Provisioning-Azureのドライバをぶち込む。

> chef gem install chef-provisioning-azure

これで準備完了。ちなみに、本日2015/9/10にアップデートがかかって、Ubuntuのユーザ名の指定が失敗するバグが解決されているので、ぜひアップデートされたい。
以前にインストールしている人は次のコマンドでアップデート可能だ。

> chef gem update chef-provisioning-azure

3. Chefのレシピとプロビジョニング用のコードを書く

3.1. サンプルコードとその実行

さて、今回のコードはすべてGitHubにあげておいたので、皆様もクローンして、ちょっと変えたらいつでも動作するだろう。

Visual Studio Online Build Agent Machine for Ubuntu

Gitがインストールされているなら、次のコマンドで取得できる

> git clone https://github.com/TsuyoshiUshio/vsoagentserver.git

ぜひ楽しんでください。そのままだと、私のサーバーとかぶってしまうので、provisioning.rbと、attributes/defailt.rbを適当に変更して動かしてみてください。
provisioning.rbのvm_name, cloud_service_nameあたりを変えるだけで動くだろう。

ちなみにプロビジョニングさせるコマンドは次の通り。

> cd vsoagentserver
> chef-client --local provision.rb

[chef-client](https://docs.chef.io/chef_client.html)

ここでは割愛するがHOL - Parts Unlimited MRP App Continuous Integration with Visual Studio Online Buildにあるとおり、
VSO側の手順が存在するので、それを実施したのちサーバーにログインし次のコマンドを打つ。ちなみにサーバーのパスワードは、provision.rbに書いてあるのでこれも変えておくとよい。

> ssh azureuser@pendricachefdemo01.cloudapp.net
> cd myagent
> node agent/vsoagent

ちなみにこのサンプルコードを作成するにあたっては、ChefDKをインストールしたのち

> chef generate repo partsmrp
> cd partsmrp
> git init
> git add .

といった手順でテンプレートを生成したところから、始まる。これから、書き換えた部分のみを簡単に解説していく。

3.2. コードの解説

3.2.1. Provisionファイル

Chef Provisionは、既に存在するマシンにプロビジョニングをするだけではなく、マシンの生成事態も、コードで実施できるイケメンだ。
様々なドライバが存在するが、Azureの場合はchef-provisioning-azureだ。
これは先ほどの手順ですでにインストール済みである。
 次のコードはリポジトリのトップにあるprovisioning.rbだ。これが今回の起点となるコードだ。中身をみてみよう。

machine_optionsに様々なVMを上げるときのオプションが書いている。これらを指定できる。大体みていただければなんとなくお分かりかと思うが、
ポイントのみ解説したい。:passwordと:vm_userは各セクションが違うので注意。:vm_userは指定しないとデフォルトはubuntuになる。これはVMへsshログインするときのユーザに
なっている。vm_sizeで指定できる値はNew D-Series Virtual Machine Sizesで確認可能。
:locationで指定可能な値はazure vm location listコマンドで確認できる。そして、machineリソースでmachine_optionsで指定した内容でマシンを起動する。
次のポイントはrecipeでVM起動後に実行されているレシピを指定しているところにある。ちなみに今はclassicVMにしか対応していない。

またvm_sizeの小さいものはSmallが指定できてエコノミーだが、プロビジョニングするときに遅すぎてタイムアウトしたりするケースがあったので、多少強力なマシンにしている。
プロビジョニング後に小さなものに変えると安くていいだろう。

require 'chef/provisioning/azure_driver'
with_driver 'azure'

machine_options = {
  :bootstrap_options => {
    :cloud_service_name => 'pendricachefdemo01',
    :storage_account_name => 'pendricachefdemo01',
    :vm_size => "Standard_D11",
    :vm_user => "azureuser",
    :location => 'East Asia'
  },
  :image_id => 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_2-LTS-amd64-server-20150706-en-us-30GB',
  :vm_name => "penchefdemo01",
  :password => "P2ssw0rd"
  }
  machine 'penchefdemo01' do
    machine_options machine_options
    recipe 'vsoagent'
    converge true
  end

3.2.2. VSO agent cookbookのレシピ

レシピは、起動したVMに対してツールをインストールするなどの指定をする。今回のコードは次の通り。

cookbooks/vsoagent/recipes/default.rb

これもコードを切り取って少しづつ解説したい。基本的にChefのいいところは冪等性を保証してくれているところだ。
つまり、何回プロビジョニングしても同じ状態になってくれる。例えば前回途中までしかいかなかったとすると、途中までの分はうまくスキップ
してくれたりして、常に同じ状態になってくれる。これは地味に便利だ。ところで、本当はpackageのインストールの周りはまとめることができる。なぜまとめてないかというと、まとめるとしょぼいマシンをつかったときにタイムアウトが発生したからだ orz

execute "add-apt-repository ppa:openjdk-r/ppa" do
  user "root"
end

execute "apt-get update" do
  user "root"
end

package "gradle" do
  action :install
end

package "openjdk-8-jdk" do
  action :install
end

package "openjdk-8-jre" do
  action :install
end

package "mongodb" do
  action :install
end

execute "curl --silent --location https://deb.nodesource.com/setup_0.12 | sudo bash -" do
  user "root"
end

package "nodejs" do
  action :install
end

execute "/usr/bin/npm install vsoagent-installer -g" do
  user "root"
end

directory "/home/#{node["vsoagent"]["vm_user"]}/myagent" do
  owner node["vsoagent"]["vm_user"]
  group node["vsoagent"]["vm_group"]
  mode '0755'
  action :create
end

execute "/usr/bin/vsoagent-installer" do
  cwd "/home/#{node["vsoagent"]["vm_user"]}/myagent"
  user node["vsoagent"]["vm_user"]
  group node["vsoagent"]["vm_group"]
  not_if {File.exist?("/home/#{node["vsoagent"]["vm_user"]}/myagent/agent")}
end

template "/home/#{node["vsoagent"]["vm_user"]}/.bash_profile" do
  mode '0664'
  source '.bash_profile.erb'
  user node["vsoagent"]["vm_user"]
  group node["vsoagent"]["vm_group"]
  not_if { File.exist?("/home/#{node["vsoagent"]["vm_user"]}/.bash_profile")}
end

template "/home/#{node["vsoagent"]["vm_user"]}/myagent/.agent" do
  mode '0664'
  source '.agent.erb'
  user node["vsoagent"]["vm_user"]
  group node["vsoagent"]["vm_group"]
  not_if { File.exists?("/home/#{node["vsoagent"]["vm_user"]}/myagent/.agent")}
end

3.2.2.1. executeリソース

これは、普通に対象サーバーでコマンドを実行してくれるものだ。後述するが、冪等性をカバーするために、工夫が必要
何回も実行されても影響のないコマンドなら気にしなくてよい。

execute

execute "add-apt-repository ppa:openjdk-r/ppa" do
  user "root"
end

3.2.2.2. packageリソース

これは、パッケージをインストールするためのもの。Ubuntuの場合apt-getが実行される。Yes-Noの確認をすることをスキップする-yは指定される。

package

package "mongodb" do
  action :install
end

3.2.2.3. attributes

レシピを書くときに変数を使いたいケースがある。そのような場合次のように書ける。

directory "/home/#{node["vsoagent"]["vm_user"]}/myagent" do
  owner node["vsoagent"]["vm_user"]
  group node["vsoagent"]["vm_group"]
  mode '0755'
  action :create
end

これらの変数はもとはcookbook内にあるcookbooks/vsoagent/attributes/default.rbで定義されている。これはデフォルト値のようなものなので設定によっては上書き可能だ。

default["vsoagent"]["pool_name"] = "demo01pool"
default["vsoagent"]["server_url"] = "https://devopsjapan.visualstudio.com"
default["vsoagent"]["agent_name"] = "demo01agent"
default["vsoagent"]["vm_user"] = "azureuser"
default["vsoagent"]["vm_group"] = "azureuser"

3.2.2.4. templateリソース

最後にResource Template。これは、何らかのファイルを書きたいときによく使う。

template "/home/#{node["vsoagent"]["vm_user"]}/.bash_profile" do
  mode '0664'
  source '.bash_profile.erb'
  user node["vsoagent"]["vm_user"]
  group node["vsoagent"]["vm_group"]
  not_if { File.exist?("/home/#{node["vsoagent"]["vm_user"]}/.bash_profile")}
end

これは、sourceのところで指定されたテンプレートの中身でファイルを作る。この例ではcookbooks/vsoagent/templates/default/.bash_profile.erbのテンプレートが適用されて、bash_profileが作られる内容はこうだ

# Set environment variables for Java
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$PATH:/usr/lib/jvm/java-8-openjdk-amd64/bin

もちろん、テンプレートにも変数は使える。ほかの.agentなどのコードを見てほしい。

4. 今回苦労したところ

自動化野郎としては、エージェントのサービス起動まで自動化したかったところだ。VSOエージェントは今のままだと、どうしても手作業が入ってしまう。VSOエージェントのページをみると、実はサービスで動かすモードがある
らしい。これは熱い!!!Microsoft Cross Platform Build Agentしかし、残念ながらこのページを見ると、MacではあるがUbuntuでのサポートはまだのようだ。無念。

次の作戦はDockerHubだ!DockerHubは自動化野郎の心のふるさと。こまったらここだ。しっかりとjgarverick/vsoagentなんてのがある。
これ使ったらDockerだといちころよね。しかも、Dockerfileみると設定がわかる!というわけで見てみよう。Dockerfile

  :
RUN mkdir /opt/vsoagent
RUN mkdir /opt/vsoagent/_work
WORKDIR /opt/vsoagent
RUN vsoagent-installer
WORKDIR /opt/vsoagent/agent
COPY agent.config /opt/vsoagent/agent/.agent
RUN chown -R vsoservice /opt/vsoagent
  :

世の中あまくなかった。.agentファイルに、visual studio onlineを指定する場所などを記載するところがあり、node agent/vsoagentを初回起動したときにいろいろごねごね入れる手順のみが
省けるようで、今のままだと自分のエイリアスユーザコードとパスワードを入力するのは避けられない。対話式のコマンドをスクリプト化する方法みたいな方法でなんとかなるのかな。
でも本質的にはサービス化待ちのほうが本番はいいですね。

5. おわりに

というわけで、最後の一歩だけまだですが、Azure + Chef ProvisiningでがっつりVM生成、プロビジョニングを決めてVSOエージェントのビルドサーバーを作れたのでよしとしましょう。
ワンコマンドでエージェント動作します。こういうインフラストラクチャのコード化をしていると、いつでも安心して環境を再構築できるので、ほんま気が楽ですね!

ではよいコーディングを!

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4