Greg Karékinian 21119fff08 Add a custom resource to set up PostgreSQL 12
Supports both primary and replica. The access rules and firewall have to
be set up outside of the custom resource, so they are part of the
recipes instead

Refs #160
2020-05-11 18:23:11 +02:00

127 lines
3.6 KiB
Ruby

resource_name :postgresql_custom_server
property :postgresql_version, String, required: true, name_property: true
property :role, String, required: true # Can be primary or replica
property :tls, [TrueClass, FalseClass], default: false
action :create do
postgresql_version = new_resource.postgresql_version
postgresql_data_dir = data_dir(postgresql_version)
postgresql_service = "postgresql@#{postgresql_version}-main"
node.override['build-essential']['compile_time'] = true
include_recipe 'build-essential::default'
package("libpq-dev") { action :nothing }.run_action(:install)
chef_gem 'pg' do
compile_time true
end
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
postgresql_server_install "main" do
version postgresql_version
setup_repo true
password postgresql_data_bag_item['server_password']
action :install
end
service postgresql_service do
supports restart: true, status: true, reload: true
# action [:enable, :start]
end
postgresql_client_install "main" do
version postgresql_version
setup_repo true
action :install
end
postgresql_user "replication" do
action :create
replication true
password postgresql_data_bag_item['replication_password']
end
shared_buffers = if node['memory']['total'].to_i / 1024 < 1024 # > 1GB RAM
"128MB"
else # >= 1GB RAM, use 25% of total RAM
"#{node['memory']['total'].to_i / 1024 / 4}MB"
end
additional_config = {
max_connections: 100, # default
shared_buffers: shared_buffers,
unix_socket_directories: "/var/run/postgresql",
dynamic_shared_memory_type: "posix",
timezone: "UTC", # default is GMT
listen_addresses: "0.0.0.0",
}
if new_resource.role == "replica"
additional_config[:promote_trigger_file] = "#{postgresql_data_dir}/failover.trigger"
end
if new_resource.tls
include_recipe "kosmos-nginx"
include_recipe "kosmos-base::letsencrypt"
domain = node[:fqdn]
postgresql_post_hook = <<-EOF
#!/usr/bin/env bash
set -e
# Copy the postgresql certificate and restart the server if it has been renewed
# This is necessary because the postgresql user doesn't have access to the
# letsencrypt live folder
for domain in $RENEWED_DOMAINS; do
case $domain in
#{domain})
cp "${RENEWED_LINEAGE}/privkey.pem" #{postgresql_data_dir}/#{domain}.key
cp "${RENEWED_LINEAGE}/fullchain.pem" #{postgresql_data_dir}/#{domain}.crt
chown postgres:postgres #{postgresql_data_dir}/#{domain}.*
chmod 600 #{postgresql_data_dir}/#{domain}.*
systemctl reload #{postgresql_service}
;;
esac
done
EOF
# This hook will be executed by certbot after every successful certificate
# creation or renewal
file "/etc/letsencrypt/renewal-hooks/post/postgresql" do
content postgresql_post_hook
mode 0755
owner "root"
group "root"
end
template "#{node['nginx']['dir']}/sites-available/#{domain}" do
source 'nginx_conf_empty.erb'
owner node["nginx"]["user"]
mode 0640
notifies :reload, 'service[nginx]', :delayed
end
nginx_certbot_site domain
additional_config[:ssl] = "on"
additional_config[:ssl_cert_file] = "#{postgresql_data_dir}/#{domain}.crt"
additional_config[:ssl_key_file] = "#{postgresql_data_dir}/#{domain}.key"
end
postgresql_server_conf "main" do
version postgresql_version
additional_config additional_config
notifies :reload, "service[#{postgresql_service}]"
end
end
action_class do
# to use the data_dir helper
include PostgresqlCookbook::Helpers
end