Search code examples
terraformamazon-rdspgadmin-4aws-secrets-manager

How to access pgAdmin4 with my SecretsManager username and password (set up in Terraform)


I am using some AWS Terraform code to create some simple test infrastructure. I created two secrets using AWS CLI prior to typing the Terraform code (one for Postgres username and one for Postgres password that I can see in the AWS management console secrets manager section).

When I run terraform apply it does create the infrastructure, but when I use the AWS RDS endpoint host name/address and my username, password in the Register-Server (connection tab) of pgAdmin4 it says "Unable to connect to server:connection is bad:Name or service not known".

Please see image at the bottom of question.

(I have removed some sensitive info in the code block below).

main.tf

resource "aws_vpc" "testrdsvpc" {
 cidr_block = "10.0.0.0/16"
 enable_dns_support = true
 enable_dns_hostnames= true 

 tags = {

   Name = "Test-RDS-related-VPC"

 }
}

resource "aws_subnet" "public_subnets" {
 count      = length(var.public_subnet_cidrs)
 vpc_id     = aws_vpc.testrdsvpc.id
 cidr_block = element(var.public_subnet_cidrs, count.index)
 availability_zone = element(var.azs, count.index)
 map_public_ip_on_launch = true


 

 tags = {

   Name = "Public Subnet(rds) ${count.index + 1}"

 }

}

resource "aws_subnet" "private_subnets" {
 count      = length(var.private_subnet_cidrs)
 vpc_id     = aws_vpc.testrdsvpc.id
 cidr_block = element(var.private_subnet_cidrs, count.index)
 availability_zone = element(var.azs, count.index)
 map_public_ip_on_launch = false

 tags = {

   Name = "Private Subnet(rds) ${count.index + 1}"

 }
}

resource "aws_internet_gateway" "gw" {
 vpc_id = aws_vpc.testrdsvpc.id
 tags = {
   Name = "testrds-vpc-igw"

 }

}

resource "aws_route_table" "second_rt" {

 vpc_id = aws_vpc.testrdsvpc.id

 

 route {
   cidr_block = "0.0.0.0/0"
   gateway_id = aws_internet_gateway.gw.id

 }

 tags = {

   Name = "2nd Route Table"

 }

}

resource "aws_route_table_association" "public_subnet_asso" {
 count = length(var.public_subnet_cidrs)
 subnet_id      = element(aws_subnet.public_subnets[*].id, count.index)
 route_table_id = aws_route_table.second_rt.id
}

resource "aws_security_group" "rds-security-group" {
 name        = "Allow postgres"
 description = "Allow inbound traffic from my IP address"
 vpc_id      = aws_vpc.testrdsvpc.id

ingress {
   description = "postgresql ingress"
   from_port   = 5432
   to_port     = 5432
   protocol    = "tcp"
   cidr_blocks = ["myipaddrsss"]
   ipv6_cidr_blocks = ["myipv6ipaddress"]
 }


egress {
   from_port   = 0
   to_port     = 0
   protocol    = "-1"
   cidr_blocks = ["0.0.0.0/0"]
   ipv6_cidr_blocks = ["::/0"]

 }

 tags = {
    Name = "postgres-sg"
 }

}

data "aws_secretsmanager_secret" "rds_secret" {
  count = length(var.secrets_list)
  name = element(var.secrets_list,count.index)
}

data "aws_secretsmanager_secret_version" "secret-rds-version" {
  count = length(var.secrets_list)
  secret_id = data.aws_secretsmanager_secret.rds_secret[count.index].id
}

#rds_instance name is:"RDS_learner_db"
resource "aws_db_instance" "learner-rds-ins" {
  allocated_storage    = var.allocated_storage
  db_name              = var.rds_instance_name
  publicly_accessible  = true
  engine               = var.engine
  engine_version       = var.engine_version
  instance_class       = var.instance_class
  username             = var.db_username
  password             = var.db_password
  db_subnet_group_name = aws_db_subnet_group.rds_sub_grp.name
  skip_final_snapshot  = true
  vpc_security_group_ids = [aws_security_group.rds-security-group.id]
}

resource "aws_db_subnet_group" "rds_sub_grp" {
  name       = "rds-subnet-test-grp"
  subnet_ids = aws_subnet.public_subnets[*].id

  tags = {
    Name = "My RDS subnet group"
  }
}

outputs.tf

output "secret_value" {
  value = data.aws_secretsmanager_secret_version.secret-rds-version[*].secret_string
  sensitive = true
}

output "rds_instance_endpoint" {
  value = aws_db_instance.learner-rds-ins.address
}

output "rds_instance_endpoint-port" {
  value = aws_db_instance.learner-rds-ins.port
}

Note: the var.db_username and var.db_password are the same as my secrets username and password (secret names) and var.secrets_list are the secret names that are in the secrets manager AWS console

enter image description here

enter image description here


Solution

  • First of all create your db credentials and then reference the datasource like this example:

    enter image description here

    enter image description here

    Next try to get your secret credential from tf code:

    code example:

    
    data "aws_secretsmanager_secret" "rds_secret" {
      name = "db-credential-test" #your aws secret manager name
    }
    
    data "aws_secretsmanager_secret_version" "secret-rds-version" {
      secret_id = data.aws_secretsmanager_secret.password.id
    }
    
    #rds_instance name is:"RDS_learner_db"
    resource "aws_db_instance" "learner-rds-ins" {
      allocated_storage    = var.allocated_storage
      db_name              = var.rds_instance_name
      publicly_accessible  = true
      engine               = var.engine
      engine_version       = var.engine_version
      instance_class       = var.instance_class
      username             = jsondecode(data.aws_secretsmanager_secret_version.secret-rds-version.secret_string)["username"]
      password             = jsondecode(data.aws_secretsmanager_secret_version.secret-rds-version.secret_string)["password"]
      db_subnet_group_name = aws_db_subnet_group.rds_sub_grp.name
      skip_final_snapshot  = true
      vpc_security_group_ids = [aws_security_group.rds-security-group.id]
    }