openstack-infrastructure-te.../modules/postgresql/postgresql.tf

284 lines
11 KiB
HCL

#
# Dedicated network of the PostgreSQL service.
# No gateway: it carries database traffic only, the instances reach the rest of
# the world through their port on the main private network.
#
resource "openstack_networking_network_v2" "postgresql_net" {
name = var.postgresql_data.network_name
description = var.postgresql_data.network_description
admin_state_up = "true"
external = "false"
dns_domain = var.dns_zone_name
mtu = var.mtu_size
port_security_enabled = true
shared = false
region = var.main_region
}
resource "openstack_networking_subnet_v2" "postgresql_subnet" {
name = var.postgresql_data.subnet_name
description = var.postgresql_data.subnet_description
network_id = openstack_networking_network_v2.postgresql_net.id
cidr = var.postgresql_data.network_cidr
dns_nameservers = var.resolvers_ip
ip_version = 4
enable_dhcp = true
no_gateway = true
allocation_pool {
start = var.postgresql_data.allocation_pool_start
end = var.postgresql_data.allocation_pool_end
}
}
#
# Security group of the server: the service is reachable only from the
# dedicated network, and only on its port
#
resource "openstack_networking_secgroup_v2" "postgresql_access" {
name = "access_to_the_postgresql_service"
delete_default_rules = "true"
description = "Access to the PostgreSQL service through the dedicated network"
}
resource "openstack_networking_secgroup_rule_v2" "postgresql_ingress" {
security_group_id = openstack_networking_secgroup_v2.postgresql_access.id
description = "Connections to port ${var.postgresql_data.port} from the ${var.postgresql_data.network_cidr} network"
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = var.postgresql_data.port
port_range_max = var.postgresql_data.port
remote_ip_prefix = var.postgresql_data.network_cidr
}
resource "openstack_networking_secgroup_rule_v2" "postgresql_ingress_icmp" {
security_group_id = openstack_networking_secgroup_v2.postgresql_access.id
description = "ICMP from the dedicated network"
direction = "ingress"
ethertype = "IPv4"
protocol = "icmp"
remote_ip_prefix = var.postgresql_data.network_cidr
}
# The port of the server has no default egress rule (delete_default_rules), so
# the answers and DHCP have to be allowed explicitly
resource "openstack_networking_secgroup_rule_v2" "postgresql_egress" {
security_group_id = openstack_networking_secgroup_v2.postgresql_access.id
description = "Egress traffic on the dedicated network"
direction = "egress"
ethertype = "IPv4"
remote_ip_prefix = var.postgresql_data.network_cidr
}
resource "openstack_networking_secgroup_rule_v2" "postgresql_egress_bootps" {
security_group_id = openstack_networking_secgroup_v2.postgresql_access.id
description = "DHCP requests on the dedicated network"
direction = "egress"
ethertype = "IPv4"
protocol = "udp"
port_range_min = 67
port_range_max = 67
}
resource "openstack_networking_secgroup_rule_v2" "postgresql_ingress_bootpc" {
security_group_id = openstack_networking_secgroup_v2.postgresql_access.id
description = "DHCP answers on the dedicated network"
direction = "ingress"
ethertype = "IPv4"
protocol = "udp"
port_range_min = 68
port_range_max = 68
}
#
# Monitoring: the Prometheus postgres_exporter, installed on the server by the
# postgresql role (see infrastructure-playbooks, postgresql-cloud.yml).
#
# It is a group of its own, on the MAIN network port, because that is where the
# exporter is scraped from: the two groups above live on the service port, in
# the dedicated database network, which Prometheus has no reason to join. Only
# the server gets it, so nothing else in the project has 9187 opened.
#
resource "openstack_networking_secgroup_v2" "postgresql_monitoring" {
name = "prometheus_access_to_the_postgresql_exporter"
delete_default_rules = "true"
description = "Prometheus access to the postgres_exporter of the PostgreSQL server"
}
resource "openstack_networking_secgroup_rule_v2" "postgresql_exporter_ingress" {
security_group_id = openstack_networking_secgroup_v2.postgresql_monitoring.id
description = "Connections to the postgres_exporter port ${var.postgresql_data.exporter_port} from Prometheus"
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = var.postgresql_data.exporter_port
port_range_max = var.postgresql_data.exporter_port
remote_ip_prefix = var.prometheus_cidr
}
#
# Security group of the clients: it goes on the port that every client of the
# database has on the dedicated network
#
resource "openstack_networking_secgroup_v2" "postgresql_client_access" {
name = "vm_access_to_the_postgresql_service"
delete_default_rules = "true"
description = "Access to the PostgreSQL service from the port of a VM in the dedicated network"
}
resource "openstack_networking_secgroup_rule_v2" "client_egress_postgresql" {
security_group_id = openstack_networking_secgroup_v2.postgresql_client_access.id
description = "Connections to port ${var.postgresql_data.port} of the PostgreSQL server"
direction = "egress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = var.postgresql_data.port
port_range_max = var.postgresql_data.port
remote_ip_prefix = var.postgresql_data.server_cidr
}
resource "openstack_networking_secgroup_rule_v2" "client_egress_icmp" {
security_group_id = openstack_networking_secgroup_v2.postgresql_client_access.id
description = "ICMP to the PostgreSQL server"
direction = "egress"
ethertype = "IPv4"
protocol = "icmp"
remote_ip_prefix = var.postgresql_data.server_cidr
}
resource "openstack_networking_secgroup_rule_v2" "client_egress_bootps" {
security_group_id = openstack_networking_secgroup_v2.postgresql_client_access.id
description = "DHCP requests on the dedicated network"
direction = "egress"
ethertype = "IPv4"
protocol = "udp"
port_range_min = 67
port_range_max = 67
}
resource "openstack_networking_secgroup_rule_v2" "client_ingress_bootpc" {
security_group_id = openstack_networking_secgroup_v2.postgresql_client_access.id
description = "DHCP answers on the dedicated network"
direction = "ingress"
ethertype = "IPv4"
protocol = "udp"
port_range_min = 68
port_range_max = 68
}
#
# Volumes: data and WAL on separate SSD backed volumes
#
resource "openstack_blockstorage_volume_v3" "postgresql_data_vol" {
name = var.postgresql_data.vol_data_name
description = "PostgreSQL data directory"
size = var.postgresql_data.vol_data_size
volume_type = var.postgresql_data.volume_type
enable_online_resize = true
}
resource "openstack_blockstorage_volume_v3" "postgresql_wal_vol" {
name = var.postgresql_data.vol_wal_name
description = "PostgreSQL write ahead log"
size = var.postgresql_data.vol_wal_size
volume_type = var.postgresql_data.volume_type
enable_online_resize = true
}
#
# Ports. They are defined outside the instance so that the addresses and the
# security groups do not depend on the life cycle of the VM
#
resource "openstack_networking_port_v2" "postgresql_main_port" {
name = "${var.postgresql_data.name}-main-port"
description = "Administration port of the PostgreSQL server on the main private network"
admin_state_up = true
network_id = var.main_private_network_id
# The default group carries SSH from the jump proxy, ICMP, the node exporter
# and the egress rule; the monitoring one adds the postgres_exporter port
security_group_ids = [
var.default_security_group_id,
openstack_networking_secgroup_v2.postgresql_monitoring.id,
]
fixed_ip {
subnet_id = var.main_private_subnet_id
ip_address = var.postgresql_main_ip
}
}
resource "openstack_networking_port_v2" "postgresql_service_port" {
name = "${var.postgresql_data.name}-service-port"
description = "Service port of the PostgreSQL server on the dedicated network"
admin_state_up = true
network_id = openstack_networking_network_v2.postgresql_net.id
security_group_ids = [openstack_networking_secgroup_v2.postgresql_access.id]
fixed_ip {
subnet_id = openstack_networking_subnet_v2.postgresql_subnet.id
ip_address = var.postgresql_data.server_ip
}
}
#
# Instance
#
resource "openstack_compute_instance_v2" "postgresql_server" {
name = var.postgresql_data.name
availability_zone_hints = var.availability_zone
flavor_name = var.postgresql_data.flavor
key_pair = var.ssh_key_name
block_device {
uuid = var.image.uuid
source_type = "image"
volume_size = var.postgresql_data.boot_vol_size
boot_index = 0
destination_type = "volume"
delete_on_termination = false
}
network {
port = openstack_networking_port_v2.postgresql_main_port.id
}
network {
port = openstack_networking_port_v2.postgresql_service_port.id
}
user_data = file(var.image.user_data_file)
# Do not replace the instance when the ssh key or the user data change
lifecycle {
ignore_changes = [
key_pair, user_data, network
]
}
}
resource "openstack_compute_volume_attach_v2" "postgresql_data_attach" {
instance_id = openstack_compute_instance_v2.postgresql_server.id
volume_id = openstack_blockstorage_volume_v3.postgresql_data_vol.id
device = var.postgresql_data.vol_data_device
}
resource "openstack_compute_volume_attach_v2" "postgresql_wal_attach" {
instance_id = openstack_compute_instance_v2.postgresql_server.id
volume_id = openstack_blockstorage_volume_v3.postgresql_wal_vol.id
device = var.postgresql_data.vol_wal_device
# The devices are assigned in order, so the WAL volume is attached after the
# data one
depends_on = [openstack_compute_volume_attach_v2.postgresql_data_attach]
}
#
# Optional A record on the main network address
#
resource "openstack_dns_recordset_v2" "postgresql_recordset" {
count = length(var.postgresql_recordset_name) > 0 ? 1 : 0
zone_id = var.dns_zone_id
name = var.postgresql_recordset_name
description = "Address of the PostgreSQL server on the main private network"
ttl = 8600
type = "A"
records = [var.postgresql_main_ip]
}