chefでデータベースとかユーザとか作りたい

Vagrantで開発環境を共有したりしているのですが、

  • データベースの作成
  • ユーザの作成

とかってどこでやるべきなんでしょう?

「本来ここでやるべき」とか知ってる人がいたら教えて下さい。

とりあえず現状は、MySQLのインストールとかをchefでやっているので、ついでにchefでやってしまおうと思います。

knife cookbook create database-prepare -o site-cookbooks/
vim site-cookbooks/database-prepare/recipes/default.rb

mysql-clientのインストールと、SQL文の実行を記述しておきます。

package 'mysql-client-5.5' do
    action :upgrade
end

package 'libmysqlclient-dev' do
    action :upgrade
end

template '/tmp/mysql-schema.sql' do
    source 'mysql-schema.sql.erb'
end

bash 'apply schema' do
    code "mysql -uroot -h#{node[:database][:host]} #{"-p" + node[:database][:password] if node[:database][:host] != 'localhost'} < /tmp/mysql-schema.sql"
end

templateは下記のように。

<%
host = node[:database][:host]
name = node[:database][:name]
user = node[:database][:user]
password = node[:database][:password]
%>
<% if host == 'localhost' %>
CREATE DATABASE IF NOT EXISTS `<%= name %>` DEFAULT CHARACTER SET utf8;

CREATE DATABASE IF NOT EXISTS `<%= name %>_test` DEFAULT CHARACTER SET utf8;
GRANT ALL PRIVILEGES ON `<%= name %>_test`.* TO <%= user %>@localhost IDENTIFIED BY '<%= password %>';
GRANT ALL PRIVILEGES ON `<%= name %>_test`.* TO <%= user %>@"%" IDENTIFIED BY '<%= password %>';
<% end %>

GRANT ALL PRIVILEGES ON `<%= name %>`.* TO <%= user %>@localhost IDENTIFIED BY '<%= password %>';
GRANT ALL PRIVILEGES ON `<%= name %>`.* TO <%= user %>@"%" IDENTIFIED BY '<%= password %>';
FLUSH PRIVILEGES;

localhost の場合のみ"CREATE DATABASE"を行っているのは、RDSだと勝手に作られるから。 あと、"_test"ってのを作ってるのも、ローカルでのみテストを行うから。 そのへんはプロジェクト・案件によって変わってくるのかなー、と。

で、MySQLはこんな感じで簡単に出来たんだけど、PostgreSQL が面倒だった。

  • "IF EXISTS"的なものが見つからない。
  • 同じようにSQLファイルを用意しても、エラーになってしまった。

というわけで、毎回コマンドを発行することに。

package 'postgresql-client-common' do
    action :upgrade
end

execute "create-role" do
    exists = <<-EOH
        su - postgres -c "psql -c\\"SELECT * FROM pg_user WHERE usename='#{node[:database][:user]}'\\" | grep -c #{node[:database][:user]}"
    EOH
    command <<-EOC
        su - postgres -c "psql -c\\"CREATE ROLE #{node[:database][:user]} WITH LOGIN PASSWORD '#{node[:database][:password]}';\\""
    EOC
    not_if exists 
end

execute "create-database" do
    exists = <<-EOH
        su - postgres -c "psql -c\\"SELECT * FROM pg_database WHERE datname = '#{node[:database][:name]}'\\" | grep -c #{node[:database][:name]}"
    EOH
    command <<-EOC
        su - postgres -c "psql -c\\"CREATE DATABASE #{node[:database][:name]} OWNER #{node[:database][:user]} ENCODING 'UTF8' LC_CTYPE 'en_US.UTF-8' LC_COLLATE 'en_US.UTF-8' TEMPLATE template0;\\""
        su - postgres -c "psql -d #{node[:database][:name]} -f /usr/share/postgresql/9.3/extension/postgis--2.1.2.sql"
    EOC
    not_if exists 
end

ちなみに、Vagrantfileにはパラメータを設定しておく。

chef.json = {
  :database => {
  #  :type => "mysql",
    :type => "postgresql",
    :host => "localhost",
    :name => "sample_db",
    :user => "web",
    :password => "password"
  }
}

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code