Skip to content

chore: allow access to RDS from any source #122

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

Closed
wants to merge 4 commits into from
Closed
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
83 changes: 83 additions & 0 deletions .github/workflows/show-terraform-state.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Show Terraform State

on:
workflow_dispatch:
inputs:
environment:
type: choice
description: Environment to show state for
options:
- staging
- production

jobs:
show-state:
name: Show Terraform state for ${{ github.event.inputs.environment }}
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment }}
env:
TF_VAR_AWS_REGION: ${{ vars.AWS_REGION }}
TF_VAR_APP_NAME: ${{ vars.APP_NAME }}
TF_VAR_APP_ENVIRONMENT: ${{ github.event.inputs.environment }}
#Database
TF_VAR_DATALAYER_PG_USER: ${{ secrets.DATALAYER_PG_USER }}
TF_VAR_DATALAYER_PG_PASSWORD: ${{ secrets.DATALAYER_PG_PASSWORD }}
#Hasura API
TF_VAR_GREEN_DATALAYER_HASURA_ADMIN_SECRET: ${{ secrets.DATALAYER_HASURA_ADMIN_SECRET }}
TF_VAR_BLUE_DATALAYER_HASURA_ADMIN_SECRET: ${{ secrets.DATALAYER_HASURA_ADMIN_SECRET }}
#Coingecko API
TF_VAR_GREEN_COINGECKO_API_KEY: ${{ secrets.COINGECKO_API_KEY }}
TF_VAR_BLUE_COINGECKO_API_KEY: ${{ secrets.COINGECKO_API_KEY }}
steps:
- name: Check out github repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Check if user is an admin
uses: ./.github/actions/check-admin
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: ${{ vars.TERRAFORM_VERSION }}
terraform_wrapper: false

- name: Set up AWS CLI
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}

- name: Terraform Init
working-directory: deployment/environments/${{github.event.inputs.environment}}
run: |
terraform init \
-backend-config="bucket=${{ vars.APP_NAME }}-terraform-state" \
-backend-config="key=${{ vars.APP_NAME }}-${{github.event.inputs.environment}}-state" \
-backend-config="region=${{ vars.AWS_REGION }}" \
-backend-config="encrypt=true"

- name: Show Terraform State
working-directory: deployment/environments/${{github.event.inputs.environment}}
run: |
echo "=== Terraform State Information ==="
echo "Current State:"
terraform show

echo -e "\n=== Terraform Outputs ==="
terraform output

echo -e "\n=== RDS Connection Information ==="
echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
echo "Connection String: postgresql://${{ secrets.DATALAYER_PG_USER }}:${{ secrets.DATALAYER_PG_PASSWORD }}@$(terraform output -raw rds_endpoint)/GitcoinDatalayer{{Green|Blue}}"

echo -e "\n=== Current Deployment State ==="
echo "Deployment State: $(terraform output -raw deployment_state)"
echo "Active Deployment: $(terraform output -raw active_deployment)"

echo -e "\n=== API Gateway Information ==="
echo "API Gateway URL: $(terraform output -raw api_gateway_url)"
6 changes: 6 additions & 0 deletions .github/workflows/upgrade-current-deployment-infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,11 @@ jobs:
echo "Deployment state: $deployment_state"
echo "Active deployment: $active_deployment"
terraform apply -var-file=tfvars.json -auto-approve -var="DEPLOYMENT_STATE=$deployment_state" -var="ACTIVE_DEPLOYMENT=$active_deployment"

# Display RDS connection information
echo "=== RDS Connection Information ==="
echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
echo "Connection String: postgresql://${{ secrets.DATALAYER_PG_USER }}:${{ secrets.DATALAYER_PG_PASSWORD }}@$(terraform output -raw rds_endpoint)/GitcoinDatalayer{{Green|Blue}}"
Comment on lines +79 to +83
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid exposing credentials in logs & correct the placeholder
Echoing the full connection string (including ${{ secrets.DATALAYER_PG_PASSWORD }}) risks leaking sensitive data—even if GitHub masks secrets—and the literal {{Green|Blue}} will not resolve to the active environment. Instead, mask or omit the password in the log and interpolate the ${active_deployment} shell variable for the database name.

Suggested diff:

-                  # Display RDS connection information
-                  echo "=== RDS Connection Information ==="
-                  echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
-                  echo "Connection String: postgresql://${{ secrets.DATALAYER_PG_USER }}:${{ secrets.DATALAYER_PG_PASSWORD }}@$(terraform output -raw rds_endpoint)/GitcoinDatalayer{{Green|Blue}}"
+                  # Display RDS connection information (password masked)
+                  echo "=== RDS Connection Information ==="
+                  echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
+                  echo "Connection String: postgresql://${TF_VAR_DATALAYER_PG_USER}:****@$(terraform output -raw rds_endpoint)/${active_deployment}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Display RDS connection information
echo "=== RDS Connection Information ==="
echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
echo "Connection String: postgresql://${{ secrets.DATALAYER_PG_USER }}:${{ secrets.DATALAYER_PG_PASSWORD }}@$(terraform output -raw rds_endpoint)/GitcoinDatalayer{{Green|Blue}}"
# Display RDS connection information (password masked)
echo "=== RDS Connection Information ==="
echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
echo "Connection String: postgresql://${TF_VAR_DATALAYER_PG_USER}:****@$(terraform output -raw rds_endpoint)/${active_deployment}"
🤖 Prompt for AI Agents
In .github/workflows/upgrade-current-deployment-infra.yml around lines 79 to 83,
the script echoes the full database connection string including the secret
password, which risks exposing sensitive credentials in logs, and the
placeholder {{Green|Blue}} is not dynamically replaced. Remove or mask the
password from the echoed connection string to prevent credential leaks, and
replace the placeholder with the actual environment variable that specifies the
deployment name, such as ${active_deployment}. Ensure the connection string logs
only non-sensitive information and correctly references environment variables.


env:
TERRAFORM_VARS: ${{ vars.TERRAFORM_VARS }}
4 changes: 4 additions & 0 deletions deployment/environments/staging/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ output "deployment_state" {
output "api_gateway_url" {
value = module.api_gateway.api_gateway_url
}

output "rds_endpoint" {
value = module.storage.rds_endpoint
}
8 changes: 8 additions & 0 deletions deployment/modules/networking/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ resource "aws_security_group" "rds" {
cidr_blocks = module.vpc.public_subnets_cidr_blocks # Allow access from public subnets
}

# Allow access from anywhere (0.0.0.0/0)
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
Comment on lines +74 to +80
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Critical security risk: Public RDS exposure
Allowing 0.0.0.0/0 ingress on your RDS security group opens your database to the entire internet, greatly increasing the risk of unauthorized access and data exfiltration. At minimum, you should restrict access to known IP ranges, a bastion host, or VPN. Better yet, parameterize public access so it can be safely disabled in production.

Example refactor to make public ingress optional via a variable:

@@ -74,7 +74,12 @@ resource "aws_security_group" "rds" {
-  ingress {
-    from_port   = 5432
-    to_port     = 5432
-    protocol    = "tcp"
-    cidr_blocks = ["0.0.0.0/0"]
+  # Public access controlled via variable
+  ingress {
+    from_port   = 5432
+    to_port     = 5432
+    protocol    = "tcp"
+    cidr_blocks = var.rds_public_cidr_blocks
+    description = "Optional public RDS access"
  }

Add to your variables file:

variable "rds_public_cidr_blocks" {
  type        = list(string)
  description = "CIDR blocks allowed to access RDS publicly; leave empty to disable public access"
  default     = []
}
🤖 Prompt for AI Agents
In deployment/modules/networking/main.tf lines 74 to 80, the security group rule
allows ingress from 0.0.0.0/0, exposing the RDS instance to the entire internet,
which is a major security risk. To fix this, replace the hardcoded cidr_blocks
value with a variable that controls public access, and set it to an empty list
by default to disable public ingress. Update your variable definitions
accordingly to make the access configurable and safer for production
environments.


egress {
from_port = 0
to_port = 0
Expand Down
2 changes: 1 addition & 1 deletion deployment/modules/storage/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module "rds" {

maintenance_window = "Mon:00:00-Mon:03:00"

publicly_accessible = false
publicly_accessible = true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical Security Concern: Exposing RDS to the public Internet
Setting publicly_accessible = true opens your database endpoint to the Internet. Combined with an ingress rule of 0.0.0.0/0 on port 5432, this exposes sensitive data to anyone and violates security best practices. Please consider reverting this change or scoping it behind a controlled variable and locking down CIDRs.

Suggested refactor:

-  publicly_accessible = true
+  publicly_accessible = var.rds_publicly_accessible

And in variables.tf:

+variable "rds_publicly_accessible" {
+  description = "Whether the RDS instance is publicly accessible"
+  type        = bool
+  default     = false
+}

Additionally, enforce tighter network controls (whitelisted CIDRs or VPN/bastion), and enable features like deletion_protection for extra safety.

Would you like help wiring up the variable or locking down the allowed CIDRs?

🤖 Prompt for AI Agents
In deployment/modules/storage/main.tf at line 26, the setting
publicly_accessible is set to true, which exposes the RDS instance to the public
internet. Change this value to false to restrict access, or make it configurable
via a variable that defaults to false. Additionally, review and update the
security group ingress rules to restrict access to trusted CIDRs, avoiding
0.0.0.0/0. Ensure that sensitive data is protected by limiting public exposure.


storage_encrypted = true

Expand Down
Loading