Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new scripts for the DB access #317

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ VpnCerts

# ignore tfenv pinned version file
.terraform-version

/.db_connection*
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,20 @@ output: ## terraform output (make output OUTPUT_ARGUMENT='--raw dns_dhcp_vpc_id'
output-bastion-rds-admin: ## terraform output (make output-bastion-rds-admin)
$(DOCKER_RUN) /bin/bash -c "terraform output -no-color -json rds_bastion | jq -r .admin[][]"

.PHONY: output-bastion-rds-server
output-bastion-rds-server: ## terraform output (make output-bastion-rds-server)
.PHONY: rds-admin
rds-admin: ## Get RDS admin connection details (make rds-admin)
$(DOCKER_RUN) /bin/bash -c "./scripts/create_db_connection_details.sh admin"

.PHONY: rds-admin-password
rds-admin-password: ## Get RDS admin password (make rds-admin-password)
$(DOCKER_RUN) /bin/bash -c "./scripts/get_db_credentials.sh admin"

.PHONY: instanceid-bastion-rds-admin
instanceid-bastion-rds-admin: ## Get RDS Admin bastion Instance ID (make instanceid-bastion-rds-admin)
$(DOCKER_RUN) /bin/bash -c "terraform output -no-color -json rds_bastion | jq -r .admin[][]"

.PHONY: instanceid-bastion-rds-server
instanceid-bastion-rds-server: ## Get RDS server bastion Instance ID (make instanceid-bastion-rds-server)
$(DOCKER_RUN) /bin/bash -c "terraform output -no-color -json rds_bastion | jq -r .server[][]"

.PHONY: apply
Expand Down
98 changes: 62 additions & 36 deletions documentation/rds-bastion.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# RDS Bastion

# RDS Bastion

In order to carry out various maintenance tasks such as obtaining a database dump for loading into a local development DB; or obtain data that currently isn't available via an export mechanism; a bastion is created.

The bastion doesn't have any service exposed to the public like a "jump box" bastion e.g. SSH on port 22 as it is only accessible via the AWS Session Manager.
Expand All @@ -8,14 +10,21 @@ The routine is

- Enable

- Enable the bastion via an "enable" flag set in AWS SSM Parameter Store to `true`.
- Deploy by running the CI pipeline.
- Create an SSM Session.
- Carry out required procedure
- Spin up a bastion
- Enable the bastion via an "enable" flag set in AWS SSM Parameter Store to `true`.
- Deploy by running the CI pipeline.

- Configure

- Simple set up to enable assuming a role
- Prepare Terraform locally for the environment.

- Action

- Create an SSM Session.
- Retrieve connection details.
- Carry out required procedure.
- Get DB Dump.
- Query DB.

- Removal
- Disallow the bastion via an "enable" flag set in AWS SSM Parameter Store to `false`.
Expand All @@ -25,15 +34,36 @@ The routine is

### Spin up a bastion

Set the boolean value in parameter store to `true`
run the pipeline
Navigate to the ssm parameter store in the Shared Services AWS account.
Set the boolean value for
Set the boolean value for

- NAC Admin DB: `/moj-network-access-control/{environment}/enable_rds_admin_bastion` in [AWS SSM Parameter Store](https://eu-west-2.console.aws.amazon.com/systems-manager/parameters/?region=eu-west-2&tab=Table) to `true`
- Run the `network-access-control-infrastructure` [pipeline](https://eu-west-2.console.aws.amazon.com/codesuite/codepipeline/pipelines/network-access-control-infrastructure/view?region=eu-west-2) to create the bastion instance.

## Configure

### Get environment details for the target env
### Prepare Terraform locally for the environment.

We will need to query the Terraform state for the environment we need to run the init command, which will get then necessary env vars and terraform providers and modules.
For the `development` environment we do not need to add an ENV_ARGUMENT

```
make clean
make init
make init
```

For pre-production and production we do add the ENV_ARGUMENT as shown below.

```
make gen-env ENV_ARGUMENT=production
make clean
make init ENV_ARGUMENT=production
make init ENV_ARGUMENT=production
```

## Action

### run the script to identify the bastion instance id

```
Expand All @@ -54,9 +84,13 @@ Run make command with instance id
make aws_ssm_start_session INSTANCE_ID=i-019174128cf7b4563
```

## Configure
When the SSM session starts issue `sudo su -` command.

### Configure

First we need to enable an AWS role to transfer files to (or from) an S3 transfer bucket.
The bastions are now configured at deployment time with the following AWS role to transfer files to (or from) an S3 transfer bucket.

Should this not be the case for any reason here is how

```
#######################
Expand All @@ -81,50 +115,40 @@ aws sts get-caller-identity
then access to the s3 bucket

```
aws s3 ls s3://mojo-file-transfer/ --profile s3-role;
aws s3 ls s3://mojo-file-transfer/ --profile s3-role
```

## Get a DB dump

from another terminal window in the root of the project run

```shell
make shell
```
## Get a DB dump

the issue a terraform command to get the database details
In order to connect to the database the following items will be needed.

Admin (dhcp & dns)
- fqdn e.g. `"fqdn": "dhcp-dns-admin-dhcp-db.dev.staff.service.justice.gov.uk",`
- username e.g. `"username": "adminuser"`
- password

```shell
terraform output -json terraform_outputs | jq '.admin.db'
```
### Retrieve connection details

DHCP
Connection strings for testing connectivity and accessing the DBs are described below, however you can obtain ready baked dynamically created versions by running:

```shell
terraform output -json terraform_outputs | jq '.dhcp.db'
make rds-admin
```

Admin (NAC)\* note: NAC code used `rds` as module name.
To get the password run

```shell
terraform output -json terraform_outputs | jq '.admin.rds'
make rds-admin-password
```

To get the password run
A file will be created and shown on the terminal with all the correct details retrieved from Terraform outputs for the environment. You can view that file at any time it will be named `.db_connection.{ENV}.admin`.

```shell
./scripts/get_db_parameters.sh
cat .db_connection.{ENV}.admin
```

## DHCP Database Backup and Restore

In order to connect to the database the following items will be needed.

- fqdn e.g. `"fqdn": "dhcp-dns-admin-dhcp-db.dev.staff.service.justice.gov.uk",`
- username e.g. `"username": "adminuser"`
- password
> Do Not Copy Paste examples below. Use the generated file.

### Test connection

Expand Down Expand Up @@ -180,7 +204,9 @@ show tables;

### Get a DB dump

Create a timestamped database dump and upload it to S3 transfer bucket (copy and paste as below, update variable values as required.)
Create a timestamped database dump and upload it to S3 transfer bucket (copy and paste from your local `.db_connection.{env}.admin` file).

Example below for illustration only.

```shell
env="DEVELOPMENT"; \
Expand Down
48 changes: 48 additions & 0 deletions scripts/create_db_connection_details.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash

db_type=${1}
file_name=".db_connection.${ENV}.${db_type}"
terraform_outputs=$(terraform output -json)

if [ ${db_type} == "admin" ]; then
## Admin RDS
admin_db_username=admin
admin_db_fqdn=$(echo ${terraform_outputs} | jq -r '.terraform_outputs.value.admin.rds.fqdn')
admin_db_port=$(echo ${terraform_outputs} | jq -r '.terraform_outputs.value.admin.rds.port')
admin_db_name=$(echo ${terraform_outputs} | jq -r '.terraform_outputs.value.admin.rds.name')

cat << EOF > ./${file_name}
Connections strings for ${ENV} environment RDS

NAC Admin RDS:
Test connection:
Copy command below to test RDS DB access from Admin RDS Bastion.
----
curl -v telnet://${admin_db_fqdn}:${admin_db_port} --output rds.admin.txt



Connect to DB with MySQL client:
Copy command below to test RDS DB access from Admin RDS Bastion.
-----
mysql --user=${admin_db_username} --host=${admin_db_fqdn} --port=${admin_db_port} --password


Create DB dump and push to S3
--------
filename="\`date "+%Y_%m_%d-%H_%M_%S"\`_${ENV}_${admin_db_name}_rds-dump.sql"; \\
mysqldump \\
-u "${admin_db_username}" \\
-p \\
--set-gtid-purged=OFF \\
--triggers --routines --events \\
-h "${admin_db_fqdn}" \\
"${admin_db_name}" > ~/\${filename}; \\
ls -al; \\
aws s3 cp ~/\${filename} s3://mojo-file-transfer/ --profile s3-role; \\
aws s3 ls s3://mojo-file-transfer/ --profile s3-role;

EOF
fi

cat ./${file_name}
28 changes: 28 additions & 0 deletions scripts/get_db_credentials.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

aws_secretsmanager_get_secret_value() {
db_type=${1}

if [ ${db_type} == "admin" ]; then
aws secretsmanager get-secret-value \
--secret-id /moj-network-access-control/${ENV}/admin/db | jq --raw-output '.SecretString' | jq -r .password
aws secretsmanager get-secret-value \
--secret-id /moj-network-access-control/${ENV}/admin/db | jq --raw-output '.SecretString' | jq -r .username
fi
}

assume_role_in_environment() {
export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \
$(aws sts assume-role \
--role-arn "${TF_VAR_assume_role}" \
--role-session-name MySessionName \
--query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
--output text))
}

main() {
assume_role_in_environment
aws_secretsmanager_get_secret_value "${1}"
}

main "${1}"
20 changes: 0 additions & 20 deletions scripts/get_db_parameters.sh

This file was deleted.