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