Skip to content
Open
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
9 changes: 2 additions & 7 deletions .github/workflows/java-eks-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,6 @@ jobs:
RDS_MYSQL_CLUSTER_SECRETS, ${{env.RDS_MYSQL_CLUSTER_CREDENTIAL_SECRET_NAME}}
parse-json-secrets: true

- name: Convert RDS database credentials to base64
continue-on-error: true
run: |
echo "RDS_MYSQL_CLUSTER_SECRETS_PASSWORD_BASE64=$(echo -n '${{env.RDS_MYSQL_CLUSTER_SECRETS_PASSWORD}}' | base64)" >> $GITHUB_ENV

- name: Initiate Terraform
uses: ./.github/workflows/actions/execute_and_retry
with:
Expand Down Expand Up @@ -254,11 +249,11 @@ jobs:
-var="service_account_aws_access=service-account-${{ env.TESTING_ID }}" \
-var="sample_app_image=${{ env.MAIN_SAMPLE_APP_IMAGE_ARN }}" \
-var="sample_remote_app_image=${{ env.REMOTE_SAMPLE_APP_IMAGE_ARN }}" \
-var="rds_mysql_cluster_database=information_schema" \
-var="rds_mysql_cluster_endpoint=${{env.RDS_MYSQL_CLUSTER_ENDPOINT}}" \
-var="rds_mysql_cluster_username=${{env.RDS_MYSQL_CLUSTER_SECRETS_USERNAME}}" \
-var='rds_mysql_cluster_password=${{env.RDS_MYSQL_CLUSTER_SECRETS_PASSWORD_BASE64}}' \
-var='account_id=${{ env.ACCOUNT_ID }}' \
|| deployment_failed=$?
|| deployment_failed=$?

if [ $deployment_failed -ne 0 ]; then
echo "Terraform deployment was unsuccessful. Will attempt to retry deployment."
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/node-eks-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ jobs:
-var="service_account_aws_access=service-account-${{ env.TESTING_ID }}" \
-var="sample_app_image=${{ env.MAIN_SAMPLE_APP_IMAGE_ARN }}" \
-var="sample_remote_app_image=${{ env.REMOTE_SAMPLE_APP_IMAGE_ARN }}" \
-var="rds_mysql_cluster_database=information_schema" \
-var="rds_mysql_cluster_endpoint=${{env.RDS_MYSQL_CLUSTER_ENDPOINT}}" \
-var="rds_mysql_cluster_username=${{env.RDS_MYSQL_CLUSTER_SECRETS_USERNAME}}" \
-var='rds_mysql_cluster_password=${{env.RDS_MYSQL_CLUSTER_SECRETS_PASSWORD}}' \
-var='account_id=${{ env.ACCOUNT_ID }}' \
|| deployment_failed=$?
|| deployment_failed=$?

if [ $deployment_failed -ne 0 ]; then
echo "Terraform deployment was unsuccessful. Will attempt to retry deployment."
Expand Down
6 changes: 0 additions & 6 deletions .github/workflows/python-eks-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,6 @@ jobs:
RDS_MYSQL_CLUSTER_SECRETS, ${{env.RDS_MYSQL_CLUSTER_CREDENTIAL_SECRET_NAME}}
parse-json-secrets: true

- name: Convert RDS database credentials to base64
continue-on-error: true
run: |
echo "RDS_MYSQL_CLUSTER_SECRETS_PASSWORD_BASE64=$(echo -n '${{env.RDS_MYSQL_CLUSTER_SECRETS_PASSWORD}}' | base64)" >> $GITHUB_ENV

- name: Initiate Terraform
uses: ./.github/workflows/actions/execute_and_retry
with:
Expand Down Expand Up @@ -257,7 +252,6 @@ jobs:
-var='python_remote_app_image=${{ env.REMOTE_SAMPLE_APP_IMAGE_ARN }}' \
-var='rds_mysql_cluster_endpoint=${{env.RDS_MYSQL_CLUSTER_ENDPOINT}}' \
-var='rds_mysql_cluster_username=${{env.RDS_MYSQL_CLUSTER_SECRETS_USERNAME}}' \
-var='rds_mysql_cluster_password=${{env.RDS_MYSQL_CLUSTER_SECRETS_PASSWORD_BASE64}}' \
-var='rds_mysql_cluster_database=information_schema' \
-var='account_id=${{ env.ACCOUNT_ID }}' \
|| deployment_failed=$?
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ build
node_modules/

# Ignore Bin files from validator folder
validator/bin
validator/bin

.venv
__pycache__
1 change: 1 addition & 0 deletions sample-apps/java/springboot-main-service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ dependencies {
implementation("io.opentelemetry:opentelemetry-api:1.34.1")
implementation("software.amazon.awssdk:s3")
implementation("software.amazon.awssdk:sts")
implementation("software.amazon.awssdk:rds")
implementation("com.mysql:mysql-connector-j:8.4.0")
implementation ("org.apache.httpcomponents:httpclient:4.5.13")
implementation("org.jetbrains.kotlin:kotlin-stdlib:2.0.20")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
import org.springframework.web.bind.annotation.ResponseBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetBucketLocationRequest;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
import software.amazon.awssdk.services.rds.RdsUtilities;
import software.amazon.awssdk.services.rds.model.GenerateAuthenticationTokenRequest;

@Controller
public class FrontendServiceController {
Expand Down Expand Up @@ -146,19 +151,34 @@ public String asyncService() {
return "{\"traceId\": \"1-00000000-000000000000000000000000\"}";
}

// Uses the /mysql endpoint to make an SQL call
// Uses the /mysql endpoint to make an SQL call with IAM authentication
@GetMapping("/mysql")
@ResponseBody
public String mysql() {
logger.info("mysql received");
final String rdsMySQLClusterPassword = new String(new Base64().decode(System.getenv("RDS_MYSQL_CLUSTER_PASSWORD").getBytes()));
try {
Connection connection = DriverManager.getConnection(
System.getenv("RDS_MYSQL_CLUSTER_CONNECTION_URL"),
System.getenv("RDS_MYSQL_CLUSTER_USERNAME"),
rdsMySQLClusterPassword);
RdsUtilities rdsUtilities = RdsUtilities.builder()
.credentialsProvider(DefaultCredentialsProvider.create())
.region(DefaultAwsRegionProviderChain.builder().build().getRegion())
.build();

String hostname = System.getenv("RDS_MYSQL_CLUSTER_ENDPOINT");
String username = System.getenv("RDS_MYSQL_CLUSTER_USERNAME");
String database = System.getenv("RDS_MYSQL_CLUSTER_DATABASE");
GenerateAuthenticationTokenRequest tokenRequest = GenerateAuthenticationTokenRequest.builder()
.hostname(hostname)
.port(3306)
.username(username)
.build();

String authToken = rdsUtilities.generateAuthenticationToken(tokenRequest);
String jdbcUrl = String.format("jdbc:mysql://%s:3306/%s?useSSL=true&requireSSL=true&serverTimezone=UTC",
hostname, database);

Connection connection = DriverManager.getConnection(jdbcUrl, username, authToken);
Statement statement = connection.createStatement();
statement.executeQuery("SELECT * FROM tables LIMIT 1;");
connection.close();
} catch (SQLException e) {
logger.error("Could not complete SQL request: {}", e.getMessage());
throw new RuntimeException(e);
Expand Down
76 changes: 48 additions & 28 deletions sample-apps/node/frontend-service/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const express = require('express');
const mysql = require('mysql2');
const bunyan = require('bunyan');
const { S3Client, GetBucketLocationCommand } = require('@aws-sdk/client-s3');
const { Signer } = require('@aws-sdk/rds-signer');

const PORT = parseInt(process.env.SAMPLE_APP_PORT || '8000', 10);

Expand Down Expand Up @@ -120,40 +121,59 @@ app.get('/client-call', (req, res) => {
makeAsyncCall = true;
});

app.get('/mysql', (req, res) => {
// Create a connection to the MySQL database
const connection = mysql.createConnection({
host: process.env.RDS_MYSQL_CLUSTER_ENDPOINT,
user: process.env.RDS_MYSQL_CLUSTER_USERNAME,
password: process.env.RDS_MYSQL_CLUSTER_PASSWORD,
database: process.env.RDS_MYSQL_CLUSTER_DATABASE,
});

// Connect to the database
connection.connect((err) => {
if (err) {
const msg = '/mysql called with an error: ' + err.errors;
logger.error(msg);
return res.status(500).send(msg);
}

// Perform a simple query
connection.query('SELECT * FROM tables LIMIT 1;', (queryErr, results) => {
// Close the connection
connection.end();
app.get('/mysql', async (req, res) => {
try {
const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';
const signer = new Signer({
region: region,
hostname: process.env.RDS_MYSQL_CLUSTER_ENDPOINT,
port: 3306,
username: process.env.RDS_MYSQL_CLUSTER_USERNAME
});
const token = await signer.getAuthToken();

// Create a connection to the MySQL database using IAM authentication
const connection = mysql.createConnection({
host: process.env.RDS_MYSQL_CLUSTER_ENDPOINT,
user: process.env.RDS_MYSQL_CLUSTER_USERNAME,
password: token,
database: process.env.RDS_MYSQL_CLUSTER_DATABASE,
ssl: 'Amazon RDS',
authPlugins: {
mysql_clear_password: () => () => Buffer.from(token + '\0')
}
});

if (queryErr) {
const msg = 'Could not complete http request to RDS database:' + queryErr.message;
// Connect to the database
connection.connect((err) => {
if (err) {
const msg = '/mysql called with an error: ' + err.message;
logger.error(msg);
return res.status(500).send(msg);
}

// Send the query results as the response
const msg = `/outgoing-http-call response: ${results}`;
logger.info(msg);
res.send(msg);
// Perform a simple query
connection.query('SELECT * FROM tables LIMIT 1;', (queryErr, results) => {
// Close the connection
connection.end();

if (queryErr) {
const msg = 'Could not complete http request to RDS database:' + queryErr.message;
logger.error(msg);
return res.status(500).send(msg);
}

// Send the query results as the response
const msg = `/mysql response: ${JSON.stringify(results)}`;
logger.info(msg);
res.send(msg);
});
});
});
} catch (error) {
const msg = '/mysql called with IAM token generation error: ' + error.message;
logger.error(msg);
res.status(500).send(msg);
}
});

app.listen(PORT, () => {
Expand Down
Loading