Skip to content

Commit 6fddc68

Browse files
committed
Replace RDS password-based authentication with IAM role authentication
- Updated pet_clinic_billing_service to use IAM auth tokens instead of Secrets Manager - Updated pet_clinic_insurance_service to use IAM auth tokens instead of Secrets Manager - Added SSL requirement for PostgreSQL connections when using IAM authentication - Removed dependency on AWS Secrets Manager for database passwords
1 parent 64c9e39 commit 6fddc68

File tree

2 files changed

+60
-38
lines changed
  • pet_clinic_billing_service/pet_clinic_billing_service
  • pet_clinic_insurance_service/pet_clinic_insurance_service

2 files changed

+60
-38
lines changed

pet_clinic_billing_service/pet_clinic_billing_service/settings.py

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,31 +92,39 @@
9292
},
9393
}
9494

95-
# Get secret name and region from environment or use defaults
96-
SECRET_NAME = os.environ.get('SECRET_NAME', 'petclinic-python-dbsecret')
95+
# Get region from environment or use default
9796
REGION = os.environ.get('REGION', 'us-east-1')
9897

99-
def get_secret_value(secret_name: str, region_name: str) -> str:
98+
def get_rds_auth_token(db_host: str, db_port: int, db_user: str, region_name: str) -> str:
10099
"""
101-
Retrieve a secret string from AWS Secrets Manager.
100+
Generate an IAM authentication token for RDS.
102101
"""
103-
client = boto3.client('secretsmanager', region_name=region_name)
104-
response = client.get_secret_value(SecretId=secret_name)
105-
return response['SecretString']
106-
107-
102+
client = boto3.client('rds', region_name=region_name)
103+
return client.generate_db_auth_token(
104+
DBHostname=db_host,
105+
Port=db_port,
106+
DBUsername=db_user,
107+
Region=region_name
108+
)
109+
110+
# Use IAM authentication token instead of password
111+
DB_HOST = os.environ.get("DB_SERVICE_HOST")
112+
DB_PORT = int(os.environ.get("DB_SERVICE_PORT", "5432"))
113+
DB_USER = os.environ.get('DB_USER', 'postgres')
114+
115+
# Generate IAM auth token if using RDS IAM authentication
108116
env_db_password = os.environ.get('DB_USER_PASSWORD')
109-
110117
if env_db_password:
111118
DB_PASSWORD = env_db_password
112-
else:
113-
# Retrieve from Secrets Manager
119+
elif DB_HOST and os.environ.get('DATABASE_PROFILE') == 'postgresql':
114120
try:
115-
DB_PASSWORD = get_secret_value(SECRET_NAME, REGION)
116-
print(f"Retrieved secret '{SECRET_NAME}' from AWS Secrets Manager {DB_PASSWORD}")
121+
DB_PASSWORD = get_rds_auth_token(DB_HOST, DB_PORT, DB_USER, REGION)
122+
print(f"Generated IAM auth token for RDS connection")
117123
except Exception as e:
118-
# Print the error
119-
print(f"Error retrieving secret '{SECRET_NAME}' from AWS Secrets Manager: {e}", file=sys.stderr)
124+
print(f"Error generating IAM auth token: {e}", file=sys.stderr)
125+
DB_PASSWORD = None
126+
else:
127+
DB_PASSWORD = None
120128

121129

122130
# Database
@@ -130,10 +138,13 @@ def get_secret_value(secret_name: str, region_name: str) -> str:
130138
"postgresql":{
131139
"ENGINE": "django.db.backends.postgresql",
132140
"NAME": os.environ.get('DB_NAME'),
133-
"USER": os.environ.get('DB_USER'),
141+
"USER": DB_USER,
134142
"PASSWORD": DB_PASSWORD,
135-
"HOST": os.environ.get("DB_SERVICE_HOST"),
136-
"PORT": os.environ.get("DB_SERVICE_PORT"),
143+
"HOST": DB_HOST,
144+
"PORT": DB_PORT,
145+
"OPTIONS": {
146+
"sslmode": "require",
147+
} if os.environ.get('DATABASE_PROFILE') == 'postgresql' and not env_db_password else {},
137148
}
138149
}
139150

pet_clinic_insurance_service/pet_clinic_insurance_service/settings.py

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,31 +75,39 @@
7575
WSGI_APPLICATION = "pet_clinic_insurance_service.wsgi.application"
7676

7777

78-
# Get secret name and region from environment or use defaults
79-
SECRET_NAME = os.environ.get('SECRET_NAME', 'petclinic-python-dbsecret')
78+
# Get region from environment or use default
8079
REGION = os.environ.get('REGION', 'us-east-1')
8180

82-
def get_secret_value(secret_name: str, region_name: str) -> str:
81+
def get_rds_auth_token(db_host: str, db_port: int, db_user: str, region_name: str) -> str:
8382
"""
84-
Retrieve a secret string from AWS Secrets Manager.
83+
Generate an IAM authentication token for RDS.
8584
"""
86-
client = boto3.client('secretsmanager', region_name=region_name)
87-
response = client.get_secret_value(SecretId=secret_name)
88-
return response['SecretString']
89-
90-
85+
client = boto3.client('rds', region_name=region_name)
86+
return client.generate_db_auth_token(
87+
DBHostname=db_host,
88+
Port=db_port,
89+
DBUsername=db_user,
90+
Region=region_name
91+
)
92+
93+
# Use IAM authentication token instead of password
94+
DB_HOST = os.environ.get("DB_SERVICE_HOST")
95+
DB_PORT = int(os.environ.get("DB_SERVICE_PORT", "5432"))
96+
DB_USER = os.environ.get('DB_USER', 'postgres')
97+
98+
# Generate IAM auth token if using RDS IAM authentication
9199
env_db_password = os.environ.get('DB_USER_PASSWORD')
92-
93100
if env_db_password:
94101
DB_PASSWORD = env_db_password
95-
else:
96-
# Retrieve from Secrets Manager
102+
elif DB_HOST and os.environ.get('DATABASE_PROFILE') == 'postgresql':
97103
try:
98-
DB_PASSWORD = get_secret_value(SECRET_NAME, REGION)
99-
print(f"Retrieved secret '{SECRET_NAME}' from AWS Secrets Manager {DB_PASSWORD}")
104+
DB_PASSWORD = get_rds_auth_token(DB_HOST, DB_PORT, DB_USER, REGION)
105+
print(f"Generated IAM auth token for RDS connection")
100106
except Exception as e:
101-
# Print the error
102-
print(f"Error retrieving secret '{SECRET_NAME}' from AWS Secrets Manager: {e}", file=sys.stderr)
107+
print(f"Error generating IAM auth token: {e}", file=sys.stderr)
108+
DB_PASSWORD = None
109+
else:
110+
DB_PASSWORD = None
103111

104112

105113
# Database
@@ -113,10 +121,13 @@ def get_secret_value(secret_name: str, region_name: str) -> str:
113121
"postgresql":{
114122
"ENGINE": "django.db.backends.postgresql",
115123
"NAME": os.environ.get('DB_NAME'),
116-
"USER": os.environ.get('DB_USER'),
124+
"USER": DB_USER,
117125
"PASSWORD": DB_PASSWORD,
118-
"HOST": os.environ.get("DB_SERVICE_HOST"),
119-
"PORT": os.environ.get("DB_SERVICE_PORT"),
126+
"HOST": DB_HOST,
127+
"PORT": DB_PORT,
128+
"OPTIONS": {
129+
"sslmode": "require",
130+
} if os.environ.get('DATABASE_PROFILE') == 'postgresql' and not env_db_password else {},
120131
}
121132
}
122133

0 commit comments

Comments
 (0)