Home > Software engineering >  Can't make AWS Aurora Postgres RDS publicly available
Can't make AWS Aurora Postgres RDS publicly available

Time:11-18

I'm trying to spin up an Aurora Postgres Cluster and I can't seem to make it available over the internet. I'm using Terraform to code the infrastructure.

I've created a security group to allow external access and that is attached to the VPC's subnets used by the Cluster. Still, I can't seem to be able to access the endpoints from my local machine.

I can't figured out what I'm missing.

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = ">=3.11.0"

  name = "vpc-auroradb-${var.environment}"
  cidr = var.vpc_cidr_block

  azs              = var.availability_zones
  private_subnets  = var.vpc_private_subnets
  public_subnets   = var.vpc_public_subnets
  database_subnets = var.vpc_database_subnets

  enable_nat_gateway   = true
  enable_dns_hostnames = true
  enable_dns_support   = true
  create_igw           = true
  create_database_internet_gateway_route = true
  create_database_nat_gateway_route = true
  create_database_subnet_group = true
  create_database_subnet_route_table = true
}

module "aurora_cluster" {
  source  = "terraform-aws-modules/rds-aurora/aws"
  version = ">=6.1.3"

  name           = "bambi-${var.environment}"
  engine         = "aurora-postgresql"
  engine_version = "12.8"
  instance_class = "db.t4g.large"
  publicly_accessible = true
  instances = {
    1 = {
        identifier = "bambi-1"
    }
    2 = {
      identifier = "bambi-2"
    }
  }

  autoscaling_enabled      = true
  autoscaling_min_capacity = 2
  autoscaling_max_capacity = 3

  vpc_id                 = module.vpc.vpc_id
  db_subnet_group_name   = module.vpc.database_subnet_group_name
  create_db_subnet_group = false
  create_security_group = false

  iam_database_authentication_enabled = true

  storage_encrypted   = true
  apply_immediately   = true
  monitoring_interval = 30

  db_parameter_group_name         = aws_db_parameter_group.parameter_group.id
  db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.parameter_group.id

  vpc_security_group_ids = [aws_security_group.sg_public.id]

  enabled_cloudwatch_logs_exports = ["postgresql"]
}

resource "aws_security_group" "sg_public" {
  vpc_id = module.vpc.vpc_id

  ingress {
    from_port   = 5432
    to_port     = 5432
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # Allowing traffic in from all sources
  }

  egress {
    from_port   = 0             # Allowing any incoming port
    to_port     = 0             # Allowing any outgoing port
    protocol    = "-1"          # Allowing any outgoing protocol 
    cidr_blocks = ["0.0.0.0/0"] # Allowing traffic out to all IP addresses
  }
}

CodePudding user response:

From the documentation of the used VPC module, in order to have public access for the database, you need the following:

create_database_subnet_group           = true
create_database_subnet_route_table     = true
create_database_internet_gateway_route = true

enable_dns_hostnames = true
enable_dns_support   = true

create_database_nat_gateway_route should not be true. If we take a look at the code for the module on github:

resource "aws_route" "database_internet_gateway" {
  count = var.create_vpc && var.create_igw && var.create_database_subnet_route_table && length(var.database_subnets) > 0 && var.create_database_internet_gateway_route && false == var.create_database_nat_gateway_route ? 1 : 0

  route_table_id         = aws_route_table.database[0].id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.this[0].id

  timeouts {
    create = "5m"
  }
}

We can see that the count for the route for the internet gateway will be 0. This means the route which would allow public internet access is not created for the database subnet.

In the other hand setting create_database_internet_gateway_route to true will block access through the NAT gateway as well, since the route table wont have the correct route.

resource "aws_route" "database_nat_gateway" {
  count = var.create_vpc && var.create_database_subnet_route_table && length(var.database_subnets) > 0 && false == var.create_database_internet_gateway_route && var.create_database_nat_gateway_route && var.enable_nat_gateway ? var.single_nat_gateway ? 1 : length(var.database_subnets) : 0

  route_table_id         = element(aws_route_table.database.*.id, count.index)
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = element(aws_nat_gateway.this.*.id, count.index)

  timeouts {
    create = "5m"
  }
}

Essentially you block all the traffic by setting both variables to true.

  • Related