前回 Zabbix のセットアップ 手順を確認したので、今回はそれを Chef の cookbook に落とし込もうと思います。 また作成した cookbook を AWS OpsWorks を使用して動かしてみています。

作成した cookbook は こちら に置いています。

  1. Zabbix Server 用 cookbook の作成
  2. Zabbix Agent 用 cookbook の作成
  3. Cookbook のアップロード
  4. OpsWorks Stack の作成

1. Zabbix Server 用 cookbook の作成

前回同様 CentOS 7 のみを想定した Zabbix Server をインストールするための cookbook を作成します。

予め ChefDK を用意した上で、以下のコマンドにより空の cookbook を作成します。

$ mkdir cookbooks && cd cookbooks

# Create a cookbook for zabbix server
$ chef generate cookbook "zabbix-server"

Zabbix Server をインストールを実行する recipe としては以下のようなものを作成しました。 基本的には前回と同様なことを Chef に落とし込んでいるのですが、DB 周りは別途 RDS で用意したのでこの中には含まれていません。

# Set timezone
timezone = "#{node['zabbix-server']['timezone']}"
bash 'set_timezone' do
    code <<-EOH
        timedatectl set-timezone #{timezone}
    EOH
end

# Disable SELinux
execute "disable selinux" do
    only_if "which selinuxenabled && selinuxenabled"
    command "setenforce 0"
    action :run
    notifies :create, "template[/etc/selinux/config]"
end

template '/etc/selinux/config' do
    source 'selinux/config.erb'
    owner 'root'
    group 'root'
    mode '0644'
    action :nothing
end

# Register a repository of zabbix 3.2
# `not_if` executes a given string as shell command (or code block as ruby script).
# `not_if` prevents a resource from executing when the condition is true.
# https://docs.chef.io/resource_common.html#guards
remote_file '/tmp/zabbix-release-3.2-1.el7.noarch.rpm' do
    source "http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm"
    not_if 'rpm -qa | grep -q "zabbix-release-3.2-1.el7.noarch"'
    action :create
    notifies :install, "rpm_package[zabbix]", :immediately
end

rpm_package "zabbix" do
    source '/tmp/zabbix-release-3.2-1.el7.noarch.rpm'
    action :install
end

# Install zabbix-agent
# https://docs.chef.io/resource_package.html
package %w(zabbix-server-mysql zabbix-web-mysql zabbix-get) do
    action :install
end

# Set timezone of zabbix web interface
template '/etc/httpd/conf.d/zabbix.conf' do
    source 'httpd/conf.d/zabbix.conf.erb'
    owner 'root'
    group 'root'
    mode '0644'
    action :create
end

# Set database configuration of zabbix server
template '/etc/zabbix/zabbix_server.conf' do
    source 'zabbix/zabbix_server.conf.erb'
    owner 'root'
    group 'zabbix'
    mode '0644'
    action :create
end

# Start and enable zabbix-server
service 'zabbix-server' do
    action [:enable, :start]
end

service 'httpd' do
    action [:enable, :start]
end

2. Zabbix Agent 用 cookbook の作成

続いて Zabbix Agent 用の cookbook を作成します。

空の cookbook を以下のコマンドで用意します。

# Generate cookbook for zabbix-agent
$ chef generate cookbook zabbix-agent

Recipe は以下のようにしました。

# Register a repository of zabbix 3.2
# `not_if` executes a given string as shell command (or code block as ruby script).
# `not_if` prevents a resource from executing when the condition is true.
# https://docs.chef.io/resource_common.html#guards
remote_file '/tmp/zabbix-release-3.2-1.el6.noarch.rpm' do
    source "http://repo.zabbix.com/zabbix/3.2/rhel/6/x86_64/zabbix-release-3.2-1.el6.noarch.rpm"
    not_if 'rpm -qa | grep -q "zabbix-release-3.2-1.el6.noarch"'
    action :create
    notifies :install, "rpm_package[zabbix]", :immediately
end

rpm_package "zabbix" do
    source '/tmp/zabbix-release-3.2-1.el6.noarch.rpm'
    action :install
end

# Install zabbix-agent
# https://docs.chef.io/resource_package.html
package 'zabbix-agent' do
    action :install
end

# Prepare a configuration file for zabbix-agent.
# The configuration file is generated by the below resources.
#   - template file (`templates/zabbix_agentd.conf.erb`)
#   - attirbute file (`attributes/agent.rb`)
# https://docs.chef.io/resource_template.html
template '/etc/zabbix/zabbix_agentd.conf' do
    source 'zabbix_agentd.conf.erb'
    owner'root'
    group 'root'
    mode '0644'
    action :create
end

# Start and enable zabbix-agent
service 'zabbix-agent' do
    action [:enable, :start]
end

3. Cookbook のアップロード

OpsWorks で使用するために上で作成した cookbooks を S3 にアップロードします。

アップロードする cookbooks を 1 つの圧縮ファイルにまとめるために Berksfile を利用します。

# Create Berksfile
$ vim Berksfile
$ cat Berksfile
source "https://supermarket.chef.io"

cookbook "zabbix-server", path: "./zabbix-server"
cookbook "zabbix-agent", path: "./zabbix-agent"

S3 へアップロードするためのスクリプト例は以下のようになります。

#!/bin/sh

PACKAGED_COOKBOOKS_NAME=zabbix-opsworks-cookbooks.tar.gz
S3_BUCKET=s3://zabbix-opsworks-cookbooks/$PACKAGED_COOKBOOKS_NAME

# Package all cookbooks
berks package $PACKAGED_COOKBOOKS_NAME

# Upload to S3 bucket
aws s3 cp $PACKAGED_COOKBOOKS_NAME $S3_BUCKET

rm $PACKAGED_COOKBOOKS_NAME

アップロード手順は ローカルでのクックブックの依存関係のパッケージ化 を参考にしました。

4. OpsWorks Stack の作成

作成した cookbooks を使用するために OpsWorks に環境を作成します。

インフラ周りの準備

まずは VPC や セキュリティグループなど EC2 を起動するために必要なもの達を CloudFormation で用意しておきます。 ここではこちらのようなテンプレートを使用しました。

セキュリティグループはそれぞれ Zabbix Server には ざっくり 80, 10051 port を空けたもの、Zabbix Agent には 10050 を空けたものを用意しています。

Stack の設定

続いて Stack (OpsWorks において 1 つのシステム全体を表す概念) を作成します。

Stack の作成は AWS ドキュメントの 新しいスタックを作成する を参考に進めますが、今回最も重要な設定は [Use custom Chef cookbooks] の設定で、ここで先程アップロードした S3 bucket 内のファイルを指定します。

Layer の設定

Cookbooks に関する細かい設定は Layer が担当する部分です。 今回は Zabbix Server 用、Zabbix Agent 用で 2 つ Layer を作成し、それぞれの Layer に適当な設定を行い EC2 起動時に Zabbix インストールを実行させます。

  • Recipes
  • General Settings
    • Custom JSON で attributes の設定を行うことができる
    • 例えば recipe 内で node['zabbix-server']['db_host'] という設定に対応する値を以下の JSON で指定できる
    • 詳細は Custom JSON
{
  "zabbix-server": {
    "db_host": "zabbixdb"
  }
}

OpsWorks を自分で使ってみるのは初めてでしたが、Chef Server だったりを気にせず cookbooks の作成に集中することができるという点で便利なサービスだと思いました。