Application hangs sending to SQS using docker container hosted in AWS AppRunner #2591
-
Describe the bugI have an ASP.NET MVC Core application that publishes to an SQS queue. This works fine in my local development and when I run the container locally using Docker. When I publish the container to ECR and then deploy the container to my AppRunner application, my code hangs at the point I try to send a message to the queue. When calling Expected BehaviorWhen calling the Current BehaviorWhen calling the
Reproduction StepsCreate a new .NET 6 API MVC project with Docker support: Add the following Controller example:
Example dockerfile:
Publish to an ECR repo and then create an AppRunner application deploying from the ECR repo. Possible SolutionNo response Additional Information/ContextNo response AWS .NET SDK and/or Package version usedAWSSDK.SQS 3.7.100.117 Targeted .NET Platform.NET 6 (Also tried .NET 7 and 3.1 with the same issue) Operating System and versionContainer deployed through AppRunner |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Hi @j5alive, Good morning. Somehow, I'm unable to reproduce the issue. Below are the reproductions steps, used
using Amazon.Runtime;
using Amazon.SQS;
using Amazon.SQS.Model;
using System.Net;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Amazon;
using Microsoft.Extensions.Options;
namespace HelloAppRunnerVpc.Controllers;
[ApiController]
[Route("")]
public class QueueController : ControllerBase
{
private readonly ILogger<QueueController> _logger;
private readonly QueueOptions _options;
private readonly RegionEndpoint region;
private readonly string queueUrl;
public QueueController(ILogger<QueueController> logger, IOptions<QueueOptions> options)
{
_logger = logger;
_options = options.Value;
region = RegionEndpoint.GetBySystemName(_options.Region);
queueUrl = _options.QueueUrl;
}
[HttpGet("")]
public string GetHealthcheck()
{
return "Healthcheck: Healthy";
}
[HttpGet("Queue")]
public async Task<string> Queue()
{
using (var client = new AmazonSQSClient(region))
{
_logger.LogInformation("Preparing to send message to SQS");
var body = JsonSerializer.Serialize(new
{
FirstName = "John",
LastName = "Doe"
});
var request = new SendMessageRequest
{
MessageBody = body,
QueueUrl = queueUrl
};
_logger.LogInformation("Sending message to SQS");
var result = await client.SendMessageAsync(request);
if (result.HttpStatusCode != HttpStatusCode.OK)
{
throw new Exception($"Failed to publish payload to SQS. Error code {result.HttpStatusCode}");
}
_logger.LogInformation($"Message {result.MessageId} sent to SQS");
return result.MessageId;
}
}
} This class has using System;
namespace HelloAppRunnerVpc
{
public class QueueOptions
{
public const string Queue = "Queue";
public string QueueUrl { get; set; } = String.Empty;
public string Region { get; set; } = String.Empty;
}
} appsettings.json {
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Queue": {
"QueueUrl": "https://sqs.us-east-1.amazonaws.com/<<account-id>>/testapprunnerqueue",
"Region": "us-east-1"
}
} Ideally, this information should be read from Secrets Manager (AppRunner also helps configure Environment Variables from Secrets Manager values). using HelloAppRunnerVpc;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.Configure<QueueOptions>(
builder.Configuration.GetSection(QueueOptions.Queue));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run(); HelloAppRunnerVpc.csproj <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerComposeProjectPath>docker-compose.dcproj</DockerComposeProjectPath>
<UserSecretsId>da71b967-16cf-4eaa-b591-af0e26e98619</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="AWSSDK.SQS" Version="3.7.100.117" />
</ItemGroup>
</Project> Dockerfile
Here I used the default Docker file generated by Visual Studio.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:<<account-id>>:testapprunnerqueue"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"tasks.apprunner.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
So, for your case, please check,
For best practices,
Thanks, |
Beta Was this translation helpful? Give feedback.
-
Thanks it was the VPC endpoint for SQS that was missing. I also needed to allow HTTPS traffic within my security group for the subnet as this was missing. There are a few odd behaviours here still that were unexpected:
Thanks, I've been stuck on this issue for weeks so very excited to finally get it working. Cheers, |
Beta Was this translation helpful? Give feedback.
-
@j5alive Thanks for the reply and good to hear that it worked for you. Here are the inputs:
Converting this issue into discussion for better discoverability and marking it as answered. Thanks, |
Beta Was this translation helpful? Give feedback.
-
Hello! Reopening this discussion to make it searchable. |
Beta Was this translation helpful? Give feedback.
Hi @j5alive,
Good morning.
Somehow, I'm unable to reproduce the issue. Below are the reproductions steps, used
us-east-1
region for all AWS resources (reference https://aws.amazon.com/developer/language/net/badges-and-training/app-runner/module-three/).testapprunnerqueue
AppRunnerTest
.dotnet new webapi -n HelloAppRunnerVpc --framework net6.0
to create a new WebApi project.QueueController.cs