簡単に言えば、サーバー構成管理(一般的にITオートメーションとも呼ばれます)は、インフラストラクチャ管理をコードベースに変換するソリューションであり、バージョン管理および再利用が容易なプロビジョニングスクリプトのセットでサーバーを展開するために必要なすべてのプロセスを記述します。 サーバーインフラストラクチャの整合性を長期にわたって大幅に改善できます。

https://www.digitalocean.com/community/tutorials/an-introduction-to-configuration-management [前のガイド]で、サーバーインフラストラクチャの構成管理戦略を実装する主な利点、構成管理の方法について説明しましたツールが機能し、これらのツールに通常共通するもの。

シリーズのこの部分では、Rubyプログラミング言語を活用してインフラストラクチャの管理とプロビジョニングを自動化する強力な構成管理ツールであるChefを使用して、サーバープロビジョニングを自動化するプロセスを説明します。 Apacheを使用したUbuntu 18.04 Webサーバーの展開を完全に自動化するための簡単な例を作成するために必要な言語用語、構文、および機能に焦点を当てます。

これは、目標を達成するために自動化する必要がある手順のリストです。

  1. `+ apt +`キャッシュを更新する

  2. Apacheをインストールする

  3. カスタムドキュメントルートディレクトリを作成する

  4. カスタムドキュメントルートに `+ index.html`ファイルを配置します

  5. テンプレートを適用して、カスタム仮想ホストをセットアップします

  6. Apacheを再起動します

まず、シェフが使用する用語を見てから、レシピの作成に使用できる主な言語機能の概要を説明します。 このガイドの最後で、完全な例を共有するので、自分で試してみることができます。

入門

Chefのより実践的なビューに移る前に、このツールで導入された重要な用語と概念を理解することが重要です。

シェフ規約

  • * Chef Server *:情報を保存し、ノードのプロビジョニングを管理する中央サーバー

  • * Chef Node *:Chef Serverによって管理される個々のサーバー

  • * Chef Workstation *:プロビジョニングが作成され、Chef Serverにアップロードされるコントローラーマシン

  • * Recipe *:実行する命令(リソース)のセットを含むファイル。 レシピは_Cookbook_内に含まれている必要があります

  • リソース:システムの要素と実行するアクションを宣言するコードの一部。 たとえば、パッケージをインストールするには、アクション* install *で_package_リソースを宣言します

  • クックブック:プロビジョニングの一部を共有および再利用しやすくするために、事前定義された方法で編成されたレシピおよびその他の関連ファイルのコレクション

  • 属性:特定のノードに関する詳細。 属性は自動にすることができ(次の定義を参照)、レシピ内で定義することもできます

  • 自動属性:ネットワークインターフェイスやオペレーティングシステムなどのシステムに関する情報を含むグローバル変数(他のツールでは_facts_として知られています)。 これらの自動属性は、_Ohai_というツールによって収集されます

  • サービス:サービスの再起動や停止など、サービスのステータスの変更をトリガーするために使用されます

レシピ形式

シェフのレシピは、Rubyを使用して記述されています。 レシピは基本的に、ノードによって実行されるステップバイステップの命令セットを作成するリソース定義のコレクションです。 これらのリソース定義をRubyコードと組み合わせて、柔軟性とモジュール性を高めることができます。

以下に、 `+ apt-get update `を実行し、後で ` vim +`をインストールするレシピの簡単な例を示します。

execute "apt-get update" do
command "apt-get update"
end

apt_package "vim" do
action :install
end

レシピを書く

変数の使用

ローカル変数は、通常のRubyローカル変数としてレシピ内で定義できます。 以下の例は、後でリソース定義内で使用されるローカル変数を作成する方法を示しています。

package  = "vim"

apt_package package do
action :install
end

ただし、これらの変数のスコープは限定されており、定義されたファイル内でのみ有効です。 変数を作成してグローバルに利用可能にして、どのクックブックまたはレシピからでも使用できるようにする場合は、*カスタム属性*を定義する必要があります。

属性を使用する

属性はノードに関する詳細を表します。 Chefには自動属性があります。これは、Ohaiというツールによって収集され、システムに関する情報(プラットフォーム、ホスト名、デフォルトIPアドレスなど)を含む属性ですが、独自のカスタム属性を定義することもできます。

属性には、作成する属性のタイプによって定義される異なる優先レベルがあります。 `+ default +`属性は、必要に応じて他の属性タイプで上書きされる可能性があるため、最も一般的な選択肢です。

次の例は、ローカル変数の代わりに「+ default +」ノード属性を使用した場合の前の例の様子を示しています。

node.default['main']['package'] = "vim"

apt_package node['main']['package'] do
action :install
end

この例には、次の2つの詳細事項があります。

ノード変数を定義する際の推奨される方法は、使用中の現在のクックブックをキーとして使用してハッシュとして編成することです。 この場合、同じ名前のクックブックがあるため、 `+ main `を使用しました。 これにより、類似の名前付き属性を持つ可能性のある複数のクックブックを使用している場合に混乱を避けることができます。 +属性を定義するときに ` node.default `を使用しましたが、後でその値にアクセスするときは、 ` node `を直接使用したことに注意してください。 ` node.default +`の使用法は、* default タイプの属性を作成することを定義しています。 この属性の値は、 normal または override *属性など、優先順位の高い別のタイプによって上書きされる可能性があります。

属性の優先順位は、最初は少しわかりにくいかもしれませんが、ある程度練習すれば慣れるでしょう。 動作を説明するために、次の例を検討してください。

node.normal['main']['package']  = "vim"

node.override['main']['package'] = "git"

node.default['main']['package'] = "curl"

apt_package node['main']['package'] do
action :install
end

この場合、どのパッケージがインストールされるか知っていますか? 「+ git 」を推測した場合、正しく推測しました。 属性が定義された順序に関係なく、タイプ ` override `の優先順位が高いほど、 ` node [‘main’] [‘package’]は+` git`に評価されます。

ループを使用する

ループは通常、異なる入力値を使用してタスクを繰り返すために使用されます。 たとえば、10個の異なるパッケージをインストールするための10個のタスクを作成する代わりに、単一のタスクを作成し、ループを使用して、インストールするすべての異なるパッケージでタスクを繰り返すことができます。

Chefは、レシピ内でループを作成するためのすべてのRubyループ構造をサポートしています。 簡単に使用するには、 `+ each +`が一般的な選択肢です。

['vim', 'git', 'curl'].each do |package|
apt_package package do
  action :install
end
end

インライン配列を使用する代わりに、ループ内で使用するパラメーターを定義するための変数または属性を作成することもできます。 これにより、物事がより整理され、読みやすくなります。 以下に、ローカル変数を使用してインストールするパッケージを定義する同じ例:

packages = ['vim', 'git', 'curl']

packages.each do |package|
apt_package package do
  action :install
end
end

条件を使用する

条件を使用して、たとえば変数またはコマンドからの出力に基づいて、コードのブロックを実行するかどうかを動的に決定できます。

Chefは、レシピ内で条件ステートメントを作成するためのすべてのRuby条件をサポートしています。 さらに、すべてのリソースタイプは、タスクを実行するかどうかを決定する前に式を評価する2つの特別なプロパティをサポートします: + if_only +`と `+ not_if +

以下の例では、拡張機能「+ php-pear 」をインストールする前に、「 php 」の存在を確認します。 このシステムに現在インストールされている「 php 」実行可能ファイルがあるかどうかを確認するために、コマンド「 which 」を使用します。 コマンド ` which php +`がfalseを返す場合、このタスクは実行されません:

apt_package "php-pear" do
action :install
only_if "which php"
end

条件が真であると評価されたときに*例外*で常にコマンドを実行する反対の操作を行いたい場合、代わりに `+ not_if `を使用します。 この例では、システムがCentOSでない限り、「 php5 +」をインストールします。

apt_package "php5" do
action :install
not_if { node['platform'] == 'centos' }
end

特定の条件下で複数のタスクを実行する場合、より複雑な評価を実行するには、標準のRuby条件のいずれかを使用できます。 次の例では、システムがDebian または Ubuntuの場合にのみ `+ apt-get update +`を実行します。

if node['platform'] == 'debian' || node['platform'] == 'ubuntu'
execute "apt-get update" do
  command "apt-get update"
end
end

テンプレートの使用

テンプレートは通常、構成ファイルをセットアップするために使用され、変数やその他の機能を使用して、これらのファイルをより汎用的で再利用可能にすることを目的としています。

Chefは、Embedded Ruby(ERB)テンプレートを使用します。これは、Puppetで使用されるのと同じ形式です。 条件、ループ、その他のRuby機能をサポートしています。

以下は、変数を使用してこのホストのドキュメントルートを定義する、Apache仮想ホストをセットアップするためのERBテンプレートの例です。

<VirtualHost *:80>
   ServerAdmin [email protected]
   DocumentRoot <%= @doc_root %>

   <Directory <%= @doc_root %>>
       AllowOverride All
       Require all granted
   </Directory>
</VirtualHost>

テンプレートを適用するには、 `+ template +`リソースを作成する必要があります。 これは、このテンプレートを適用してデフォルトのApache仮想ホストを置き換える方法です。

template "/etc/apache2/sites-available/000-default.conf" do
source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
end

Chefは、組織とモジュール性を強化するために、ローカルファイルを扱う際にいくつかの仮定を行います。 この場合、Chefは_templates_フォルダー内でこのレシピが置かれている同じクックブックにあるはずの `+ vhost.erb +`テンプレートファイルを探します。

これまで見てきた他の構成管理ツールとは異なり、Chefには変数のより厳密なスコープがあります。 これは、 `+ template `リソースを定義するときに、テンプレート内で使用する予定の変数を明示的に提供する必要があることを意味します。 この例では、 ` variables `メソッドを使用して、仮想ホストテンプレートで必要な ` doc_root +`属性を渡します。

サービスの定義とトリガー

サービスリソースは、サービスが初期化および有効化されていることを確認するために使用されます。 また、サービスの再起動をトリガーするためにも使用されます。

Chefでは、通知する前にサービスリソースを宣言する必要があります。そうしないと、エラーが発生します。

Apache仮想ホストを設定する以前のテンプレートの使用例を考慮してみましょう。 仮想ホストの変更後にApacheが再起動されるようにするには、最初にApacheサービス用の_service_リソースを作成する必要があります。 これは、そのようなリソースがChefで定義される方法です。

service "apache2" do
 action [ :enable, :start ]
end

さて、* template *リソースを定義するとき、再起動をトリガーするために `+ notify +`オプションを含める必要があります:

template "/etc/apache2/sites-available/000-default.conf" do
source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
notifies :restart, resources(:service => "apache2")
end

レシピ例

このガイドの概要で説明したように、Ubuntu 14.04システム内でのApache Webサーバーのインストールを自動化するマニフェストを見てみましょう。

Apacheを設定するためのテンプレートファイルとWebサーバーによって提供されるHTMLファイルを含む完全な例は、https://github.com/erikaheidi/cfmgmt/tree/master/chef [on Github]にあります。 このフォルダーには、https://vagrantup.com [Vagrant]によって管理される仮想マシンを使用して、簡素化されたセットアップでマニフェストをテストできるVagrantfileも含まれています。

以下に完全なレシピがあります。

node.default['main']['doc_root'] = "/vagrant/web"

execute "apt-get update" do
command "apt-get update"
end

apt_package "apache2" do
action :install
end

service "apache2" do
action [ :enable, :start ]
end

directory node['main']['doc_root'] do
owner 'www-data'
group 'www-data'
mode '0644'
action :create
end

cookbook_file "#{node['main']['doc_root']}/index.html" do
source 'index.html'
owner 'www-data'
group 'www-data'
action :create
end

template "/etc/apache2/sites-available/000-default.conf" do
source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
notifies :restart, resources(:service => "apache2")
end

レシピの説明

ライン1

レシピは*属性*定義、 `+ node [‘main’] [‘doc_root’] +`で始まります。 ここでは単純なローカル変数を使用できますが、ほとんどのユースケースシナリオでは、レシピは含まれるレシピまたは他のファイルから使用されるグローバル変数を定義する必要があります。 これらの状況では、ローカル変数のスコープが制限されているため、ローカル変数の代わりに属性を作成する必要があります。

行3〜5

この* execute *リソースは `+ apt-get update`を実行します。

7〜10行目

この* apt_package *リソースは、パッケージ `+ apache2 +`をインストールします。

12〜15行目

この* service *リソースはサービス `+ apache2 +`を有効にして開始します。 後で、サービスの再起動のためにこのリソースに通知する必要があります。 サービスに通知しようとするリソースの前にサービス定義が来ることが重要です。そうしないと、エラーが発生します。

17〜22行目

この* directory *リソースは、カスタム属性 `+ node [‘main’] [‘doc_root’] +`で定義された値を使用して、*ドキュメントルート*として機能するディレクトリを作成します。

24〜29行目
  • cookbook_file *リソースは、ローカルファイルをリモートサーバーにコピーするために使用されます。 このリソースは、 `+ index.html`ファイルをコピーし、前のタスクで作成したドキュメントルート内に配置します。

31〜36行目

最後に、この* template *リソースはApache仮想ホストテンプレートを適用し、サービス `+ apache2 +`に再起動を通知します。

結論

Chefは、Ruby言語を活用してサーバーのプロビジョニングと展開を自動化する強力な構成管理ツールです。 標準言語機能を自由に使用して最大限の柔軟性を実現し、一部のリソースにカスタムDSLを提供することもできます。