Search code examples
c#mysqlamazon-web-servicesamazon-rds

How to connect to MySQL on AWS by C#?


We are figuring out the following small example from an online source about connecting to AWS by C#:

  ...
  try
  {
      var ssmClient = AwsConnection.ConnectToAWSByVariables(
          accessKeyId: "xxx",
          secretAccessKey: "wrongwrong",
          regionString: "xxx"
          );
      Console.WriteLine("Successfully connected to AWS using environment variables.");
  }
  catch (Exception ex)
  {
      Console.WriteLine($"Error: {ex.Message}");
  }

  ...

public static IAmazonSimpleSystemsManagement ConnectToAWSByVariables(
  string accessKeyId,
  string secretAccessKey,
  string regionString)
{
    // Create AWS credentials
    var awsCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);
    RegionEndpoint region = RegionEndpoint.GetBySystemName(regionString);

    // Create the AWS service client (in this case, SSM)
    return new AmazonSimpleSystemsManagementClient(awsCredentials, region);
}

As the sample source code above shows in secretAccessKey: "wrongwrong",, we deliberately give a wrong value for the secret access key. Nevertheless, the program still proceeded without error and printed "Successfully connected to AWS using environment variables.".

Tentatively, we thought the program above does not actually connect to the AWS, otherwise it should not succeed with a wrong credential. So, do we have a better way to verify the connection?

We have done a successful happy pass before using AWS CLI, with the following steps:

  • Connect to AWS by command aws ssm start-session ..., and get logged in on a base station host inside AWS.
  • On the base station host, connect to the MySQL instance by command mysql -h xxx.rds.amazonaws.com -u xxx -p
  • After logging in to MySQL, we can run SQL queries to prove the connection path is functional.

We hope to do similar tests with C#.


Solution

  • Creating an instance of AmazonSimpleSystemsManagementClient does not in itself actually make any calls back to AWS. It sets up the client configuration, such as credentials and region, and then when you call methods on the client it will make the actual calls to AWS. So the line where this sample code is logging--immediately after instantiating the object--has not made any calls back AWS yet (so, credentials have not been authenticated/authorized), so that logging message is incorrect and misleading at that point.

    The AWS SDK calls must each be authenticated/authorized by AWS when it receives them, so it is not like you can authenticate/authorize it once when the object is instantiated and expect it to be valid forever thereafter while the object exists. The credentials it is configured to use could be revoked in AWS or could be expired in AWS at the point any actual call is made in your code, so there is no reason the constructor should make any calls. Instead of asking you to provide the region and the credentials for every method call, the constructor makes it so you can provide these once.