简体   繁体   中英

Build ASP.NET Core 2.2 Docker Image with AWS Systems Manager Parameter Store

Setup

  • Windows 10
  • Visual Studio Professional 2017
  • Docker CE v 2.0.0.3
  • ASP.NET Core 2.2
  • PowerShell v6.1.0

I'm using the AWS Systems Manager Parameter Store to hold an encrypted connection string for my ASP.NET app.

I found this extension to configure the Parameter Store within my app as follows:

Program.cs

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration(builder =>
        {
            builder.AddSystemsManager(configureSource =>
            {
                var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").ToLower();
                configureSource.Path = $"/my-app-name/{env}";

                configureSource.Optional = false;
            });
        });

This all works fine when I build, run or test the app in Visual Studio because I have an appsettings.json file that configures the aws profile for the .NET SDK

"AWS": {
    "Profile": "default",
    "Region": "eu-west-1"
}

However, I now want to build the image locally. I've seen this StackOverflow post which describes passing the AWS credentials as arguments to the docker build command

My Dockerfile looks like this (I've removed the runtime stage for brevity):

FROM microsoft/dotnet:2.2.100-sdk AS build
ENV ASPNETCORE_ENVIRONMENT=Development
ARG AWS_DEFAULT_REGION
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
WORKDIR /src
COPY . .
RUN dotnet restore --configfile NuGet.config
RUN dotnet build MyApp.sln --no-restore -c Release -o /app

FROM build as unittest
WORKDIR /src/tests/MyApp.UnitTests
RUN dotnet test

FROM build as integrationtest
WORKDIR /src/tests/MyApp.IntegrationTests
RUN dotnet test

When I run my build command:

docker build -t my-org/my-app:1.0.0-integrationtest `
    --build-arg AWS_DEFAULT_REGION="eu-west-1" `
    --build-arg AWS_ACCESS_KEY_ID="my-access-key" `
    --build-arg AWS_SECRET_ACCESS_KEY="my-secret-key" `
    --target integrationtest .

The Problem

My integration tests fail because my app can't connect to the AWS Parameter Store

FYI - I have added the connection string as an environment variable in my Dockerfile and everything works successfully (so I know the previous statement is true)

So the question is: How can I pass AWS credentials to my .net core app when it is building locally inside a docker container?

If it helps, here is the error from PowerShell:

System.AggregateException : One or more errors occurred. (Connection refused) (The following constructor parameters did not have matching fixture data: APITestsFixture`1 fixture)
---- System.Net.Http.HttpRequestException : Connection refused
-------- System.Net.Sockets.SocketException : Connection refused
---- The following constructor parameters did not have matching fixture data: APITestsFixture`1 fixture
Stack Trace:

----- Inner Stack Trace #1 (System.Net.Http.HttpRequestException) -----
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at System.Net.Http.HttpClient.GetStringAsyncCore(Task`1 getTask)
   at Amazon.Runtime.Internal.Util.AsyncHelpers.<>c__DisplayClass1_1`1.<<RunSync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Amazon.Runtime.Internal.Util.AsyncHelpers.ExclusiveSynchronizationContext.BeginMessageLoop() in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Internal\Util\_mobile\AsyncHelpers.cs:line 142
   at Amazon.Runtime.Internal.Util.AsyncHelpers.RunSync[T](Func`1 task) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Internal\Util\_mobile\AsyncHelpers.cs:line 87
   at Amazon.Util.AWSSDKUtils.DownloadStringContent(Uri uri, TimeSpan timeout, IWebProxy proxy) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Util\AWSSDKUtils.cs:line 1008
   at Amazon.Util.EC2InstanceMetadata.GetItems(String relativeOrAbsolutePath, Int32 tries, Boolean slurp) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Util\_bcl+netstandard\EC2InstanceMetadata.cs:line 513
   at Amazon.Util.EC2InstanceMetadata.get_IAMSecurityCredentials() in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Util\_bcl+netstandard\EC2InstanceMetadata.cs:line 311
   at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.FetchCredentials() in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Credentials\_bcl+netstandard\DefaultInstanceProfileAWSCredentials.cs:line 142
   at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.GetCredentials() in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Credentials\_bcl+netstandard\DefaultInstanceProfileAWSCredentials.cs:line 88
   at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.GetCredentialsAsync() in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Credentials\_bcl+netstandard\DefaultInstanceProfileAWSCredentials.cs:line 106
   at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Pipeline\Handlers\CredentialsRetriever.cs:line 90
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Pipeline\RetryHandler\RetryHandler.cs:line 137
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Extensions.Configuration.SystemsManager.Internal.SystemsManagerProcessor.GetParametersByPathAsync()
   at Amazon.Extensions.Configuration.SystemsManager.Internal.SystemsManagerProcessor.GetDataAsync()
   at Amazon.Extensions.Configuration.SystemsManager.SystemsManagerConfigurationProvider.LoadAsync(Boolean reload)
   at Amazon.Extensions.Configuration.SystemsManager.SystemsManagerConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
   at MyApp.IntegrationTests.TestsFixture`1..ctor() in /src/tests/MyApp.IntegrationTests/TestsFixture.cs:line 20
----- Inner Stack Trace -----
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----

You can add additional ENV lines after your ARGS to your docker file

ENV AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
ENV AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
ENV AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM