# Connect to a database from your computer

This guide shows you how to connect to a database via localhost on a specific port.

<figure markdown>
![Otters doing telecommunication](https://user-images.githubusercontent.com/1691190/229385245-5f484665-cb90-4f2a-aa13-54fddbfc511e.svg){ width="390" }
</figure>

<!-- prettier-ignore-start -->
!!! example "Reference implementation"
    See how [RDS bastion is configured in `pirates-iac`](https://github.com/oslokommune/pirates-iac/blob/main/stacks/dev/rds-bastion/_gp_rds_bastion.tf).
<!-- prettier-ignore-end -->

## Things to consider

The database is accessible by anyone who can log in to the AWS account.

If you choose to omit the optional step involving the setup of VPC endpoints, it's important to understand the consequences. When you run the `ok forward` command, as outlined in this guide, it initiates an ECS task running Nginx. This setup allows the container to access your database, but it also grants Nginx access to the entire internet, [denoted by the CIDR block `0.0.0.0/0`](https://github.com/oslokommune/golden-path-iac/blob/main/terraform/modules/rds_bastion/security_groups.tf#L32). **You should consider the security risks of this**, but as a general guideline, you should not run this in production.

## Before you begin

- You have followed the setup guide and have a working environment
- You have a database in a private subnet
- You have an ECS cluster in a private subnet

## Step 1: Configure

1. Add and configure the RDS bastion package

   ```bash title="repo-iac/environments/dev/"
   ok pkg add rds-bastion
   ```

   Update `package-config.yml` with your preferences.

1. Install and apply the package

   ```bash title="repo-iac/environments/dev/rds-bastion/"
   ok pkg install
   terraform init
   terraform apply
   ```

## Step 2: Harden container security with VPC endpoints (optional)

To improve the security of your container and prevent it from accessing the internet directly, use VPC endpoints.

<!-- prettier-ignore-start -->
!!! warning "Before you begin"
    - Ensure you have set up VPC endpoints. For guidance, refer to [setting up networking](../initial-setup-of-your-aws-environment/set-up-networking.md).
    - Make sure you have a suitable container image in your private ECR registry. For details on setting this up, see [Create and use ECR pull through cache rules](../initial-setup-of-your-aws-environment/set-up-application-common.md#step-4-perform-initial-pull-for-ecr).
<!-- prettier-ignore-end -->

Once you have the VPC endpoints set up and your container image in place, the next step is to enable VPC endpoint support in your Terraform configuration.

1. Open `rds-bastion/package-config.yml`.
1. Set the `UseVPCEndpoints` variable to `true`.
1. Apply the configuration

```bash title="repo-iac/environments/dev/rds-bastion/"
ok pkg install
terraform init
terraform apply
```

## Step 3: Connect to database

1. Run the `ok forward` command to start the port forwarding session.

   ```bash
   ok forward
   ```

1. You are presented a list of Task Definitions which is applicable for port forwarding. Select the one you want to use using the arrow keys and press enter.

   ```bash
   > ssm-pf-my-bastion-task-definition
   > ssm-pf-another-bastion-task-definition
   ```

   Now a new ECS task starts. This takes about 20 to 30 seconds.

1. Next you are presented a list of all the RDS instances in your environment. Select the one you want to port forward to using the arrow keys and press enter.

   ```bash
   > my-team-db.c7d1xxxi7fm.eu-west-1.rds.amazonaws.com
   > some-other-db.c7d1xxxi7fm.eu-west-1.rds.amazonaws.com
   ```

1. Last step is to enter the ports you want to forward to and expose locally for the forwarded database.
1. Now the database is port forwarded and you can connect to it using the forwarded ports.

   ```bash
   LOCAL_PORT=4812 # or replace this with the port you entered in step 4
   psql --host=localhost --port=$LOCAL_PORT --username=db_username --password --dbname=postgres
   ```

1. When you are done, press `Ctrl+C` to stop the port forwarding session.

If you don't stop the port forwarding session manually, the Lambda function stops it automatically after some time of inactivity.

## builds/ directory

<!-- prettier-ignore-start -->
!!! info "What is the `builds` directory?"
    `terraform apply` creates a directory called `builds`. This should be committed to your IaC repository. If not, future runs of `terraform apply` always detect a change.
    Sometimes `terraform plan/apply` reports a change even though the code has not changed. This is due to the hash changing and is normal expected behavior.
<!-- prettier-ignore-end -->
