2

I have the following code:

public void ConfigureServices(IServiceCollection services)
{
    // AWS Options
    var awsOptions = Configuration.GetAWSOptions();
    services.AddDefaultAWSOptions(awsOptions);

    var client = awsOptions.CreateServiceClient<IAmazonDynamoDB>();
    var dynamoDbOptions = new DynamoDbOptions();
    ConfigurationBinder.Bind(Configuration.GetSection("DynamoDbTables"), dynamoDbOptions);

    services.AddScoped<IDynamoDbManager<MyModel>>(provider => new DynamoDbManager<MyModel>(client, dynamoDbOptions.MyModel));
}

public class DynamoDbManager<T> : DynamoDBContext, IDynamoDbManager<T> where T : class
{
    private DynamoDBOperationConfig _config;

    public DynamoDbManager(IAmazonDynamoDB client, string tableName) : base(client)
    {
        _config = new DynamoDBOperationConfig()
        {
            OverrideTableName = tableName
        };
    }       
}

My Appsettings.json is as:

{
    "AWS": {
        "Region": "us-east-1",
        "AwsId": "xxx",
        "AwsPassword": "xxx"
    },
    "DynamoDbTables": {
        "MyModel": "MyTable"
    }
}

When I run my code I am getting the error:

AmazonServiceException: Unable to find credentials

Exception 1 of 3: Amazon.Runtime.AmazonClientException: Unable to find the 'default' profile in CredentialProfileStoreChain. at Amazon.Runtime.FallbackCredentialsFactory.GetAWSCredentials(ICredentialProfileSource source) in E:\JenkinsWorkspaces\v3-trebuchet-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Credentials\FallbackCredentialsFactory.cs:line 72

Exception 2 of 3: System.InvalidOperationException: The environment variables AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN were not set with AWS credentials.

Exception 3 of 3: System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.WinHttpException: The operation timed out at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

I have tried many things but not getting this to work.

I have tried:

Setting up profile as: Amazon.Runtime.AmazonServiceException: Unable to find credentials

And also tried settingup of environment variables:

https://github.com/aws/aws-sdk-net/issues/499

But still cannot get past this error.

Fábio Nascimento
  • 2,644
  • 1
  • 21
  • 27
aman
  • 4,198
  • 4
  • 24
  • 36
  • Have you tried using debugger or add some Console.WriteLine statements to prove that you are getting you settings correctly? For example, should Configuration.GetSection("DynamoDbTables") be awsOptions.something? – NealWalters Nov 08 '18 at 14:59

1 Answers1

2

So when we are using AWS SDK we need to setup and provide an AWS access key & a secret key. And from what I have come across it does not read directly from the app settings. So I found below are the two working methods with which you can set these credentials.

Method 1 - Using Credentials file

You can create a credentials file and store your credentials there. Below is the format of the file.

[default]
aws_access_key_id = your id goes here
aws_secret_access_key = your password goes here

In above file, "default" is the name of your profile.

After creating the above file you need to specify the same in Appsettings.json file as:

"AWS": {
    "Profile": "default",
    "ProfilesLocation": "C:\\filelocation\\awscredentials",
    "Region": "us-east-1",
   }

Method 2 - Setting and Reading from Environment Variables

We can setup the environment variables in our startup.cs file as below:

Environment.SetEnvironmentVariable("AWS_ACCESS_KEY_ID", Configuration["AWS:AwsId"]);
Environment.SetEnvironmentVariable("AWS_SECRET_ACCESS_KEY", Configuration["AWS:AwsPassword"]);
Environment.SetEnvironmentVariable("AWS_REGION", Configuration["AWS:Region"]); 

And read these variables from our appSettings.json file as:

AWS": {
        "Region": "us-east-1",
        "AwsId": "xxxx",
        "AwsPassword": "xxxx"
      }
jarmod
  • 71,565
  • 16
  • 115
  • 122
aman
  • 4,198
  • 4
  • 24
  • 36
  • I'm not sure where the idea of using AwsId and AwsPassword came from (they're not documented as viable options) but there are numerous documented ways to provide credentials. Your method #1 is appropriate for local developer machines. Note that you don't need to supply ProfilesLocation if you store your credentials file in the default location (.aws/ under your home directory), and you *should* store your credentials file there (in preference to other locations) because it provides other advantages (all other AWS tools and SDKs will be able to seamlessly retrieve credentials). – jarmod Nov 09 '18 at 16:00
  • @jarmod Thats correct I should have used AccessKey And SecretKey instead. I dont remember where but I have seen both Id and password so I had used it here. We have the appsettings key values being updated dynamically when in uat and production environment so yes we are not using Method 1, have been using Method 2 for that. – aman Nov 09 '18 at 16:05
  • You can't provide credentials to the SDK directly in appsettings.json, no matter what you call them (AwsId or AccessKey, for example). You can only supply a profile name (and optional location) and that relates to credentials stored in ~/.aws/credentials. When it comes to UAT and production, assuming this is deployed on EC2 or ECS, why are you supplying credentials like this in the first place? You should be using IAM roles and instance profiles. – jarmod Nov 09 '18 at 16:10
  • I understood that we cannot provide these directly in appsettings. What I mean was calling them by what AWS calls them which is AccessKey And SecretKey. I am not aware of using IAM roles and instance profiles for this have to read on that. Also as I mentioned we are using Octopus deploy where we define all application variables ie key pair values. We define UAT & Prod variables here. – aman Nov 09 '18 at 16:30
  • You can succeed using IAM user credentials via environment variables but there are some downsides. One issue is that the credentials are long-lived. It's generally better to launch your compute resource with a minimal IAM role. The apps on that instance can then retrieve credentials automatically via the AWS SDK you're using *and* the credentials are temporary and auto-rotated. That's a better security practice.Octopus will almost certainly support IAM roles (and instance profiles) -- they're fundamental to the platform. Good luck with your project. – jarmod Nov 09 '18 at 19:39
  • Thanks for your inputs. – aman Nov 09 '18 at 20:01