3

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
  }
}
2
  • 1
    What's the exact error you are getting? A network timeout? Your terraform looks correct to me. You might want to login to the AWS web console and just double check that the Aurora instances are running, and the public accessibility feature is actual enabled. I think you may be running into an issue because you enabled both create_database_nat_gateway_route and create_database_internet_gateway_route. Those settings conflict with each other. You should disable the database NAT Gateway route. Commented Nov 17, 2021 at 21:12
  • Thanks for the pointer! Indeed, as you mentioned and as Ervin detailed below, I did enable two conflicting settings on my VPC module. Thanks! Commented Nov 18, 2021 at 1:06

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for the detailed answer! You're absolutely right. It's working now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.