From 238b5edaeed14b5dfb56eeaf2cbe55bc680a38d4 Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Wed, 19 Dec 2018 16:28:59 +0100 Subject: [PATCH 1/2] Align SQS behavior with ServiceControl to enable IAM roles --- .../ServiceControlSqsTransport.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ServiceControl.Transports.AmazonSQS/ServiceControlSqsTransport.cs b/src/ServiceControl.Transports.AmazonSQS/ServiceControlSqsTransport.cs index 1dcc48d..e2675d3 100644 --- a/src/ServiceControl.Transports.AmazonSQS/ServiceControlSqsTransport.cs +++ b/src/ServiceControl.Transports.AmazonSQS/ServiceControlSqsTransport.cs @@ -5,7 +5,10 @@ namespace ServiceControl.Transports.AmazonSQS using System.Linq; using System.Reflection; using Amazon; + using Amazon.Runtime; + using Amazon.SQS; using NServiceBus; + using NServiceBus.Logging; using NServiceBus.Settings; using NServiceBus.Transport; @@ -15,8 +18,21 @@ public override TransportInfrastructure Initialize(SettingsHolder settings, stri { var builder = new DbConnectionStringBuilder { ConnectionString = connectionString }; - PromoteEnvironmentVariableFromConnectionString(builder, "AccessKeyId", "AWS_ACCESS_KEY_ID"); - PromoteEnvironmentVariableFromConnectionString(builder, "SecretAccessKey", "AWS_SECRET_ACCESS_KEY"); + if (builder.ContainsKey("AccessKeyId") || builder.ContainsKey("SecretAccessKey")) + { + PromoteEnvironmentVariableFromConnectionString(builder, "AccessKeyId", "AWS_ACCESS_KEY_ID"); + PromoteEnvironmentVariableFromConnectionString(builder, "SecretAccessKey", "AWS_SECRET_ACCESS_KEY"); + + // if the user provided the access key and secret access key they should always be loaded from environment credentials + var transport = new TransportExtensions(settings); + transport.ClientFactory(() => new AmazonSQSClient(new EnvironmentVariablesAWSCredentials())); + } + else + { + //See https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#creds-assign + log.Info("BasicAWSCredentials have not been supplied in the connection string. Attempting to use existing environment or IAM role credentials."); + } + var region = PromoteEnvironmentVariableFromConnectionString(builder, "Region", "AWS_REGION"); var awsRegion = RegionEndpoint.EnumerableAllRegions @@ -62,5 +78,7 @@ static string PromoteEnvironmentVariableFromConnectionString(DbConnectionStringB throw new ArgumentException($"Missing value for '{connectionStringKey}'", connectionStringKey); } + + static ILog log = LogManager.GetLogger(); } } \ No newline at end of file From bd53d6fac2941b3fc8bc3554ba23fd27e643ae7e Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Thu, 20 Dec 2018 11:01:16 +0100 Subject: [PATCH 2/2] Make sure we consistently use the same approach also for queue length provider --- .../QueueLengthProvider.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ServiceControl.Transports.AmazonSQS/QueueLengthProvider.cs b/src/ServiceControl.Transports.AmazonSQS/QueueLengthProvider.cs index fd18fd9..9f3b4cf 100644 --- a/src/ServiceControl.Transports.AmazonSQS/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.AmazonSQS/QueueLengthProvider.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; + using Amazon.Runtime; using Amazon.SQS; using Monitoring; using Monitoring.Infrastructure; @@ -24,11 +25,23 @@ public class QueueLengthProvider : IProvideQueueLength string queueNamePrefix; CancellationTokenSource stop = new CancellationTokenSource(); Task pooler; + Func clientFactory = () => new AmazonSQSClient(); public void Initialize(string connectionString, QueueLengthStore store) { var builder = new DbConnectionStringBuilder { ConnectionString = connectionString }; + if (builder.ContainsKey("AccessKeyId") || builder.ContainsKey("SecretAccessKey")) + { + // if the user provided the access key and secret access key they should always be loaded from environment credentials + clientFactory = () => new AmazonSQSClient(new EnvironmentVariablesAWSCredentials()); + } + else + { + //See https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html#creds-assign + Logger.Info("BasicAWSCredentials have not been supplied in the connection string. Attempting to use existing environment or IAM role credentials."); + } + if (builder.TryGetValue("QueueNamePrefix", out var prefix)) { queueNamePrefix = (string)prefix; @@ -66,7 +79,7 @@ public Task Start() pooler = Task.Run(async () => { - using (var client = new AmazonSQSClient()) + using (var client = clientFactory()) { var cache = new QueueAttributesRequestCache(client);