diff --git a/AWS.Deploy.sln b/AWS.Deploy.sln index ff251ec3f..04e822fed 100644 --- a/AWS.Deploy.sln +++ b/AWS.Deploy.sln @@ -68,6 +68,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWS.Deploy.ServerMode.Clien EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkerServiceExample", "testapps\WorkerServiceExample\WorkerServiceExample.csproj", "{7C330493-9BF7-4DB6-815B-807C08500AC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApiNET6", "testapps\WebApiNET6\WebApiNET6.csproj", "{B2EA65BD-9FFE-4452-B2DC-574EB1A9FAF1}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\AWS.Deploy.Constants\AWS.Deploy.Constants.projitems*{3f7a5ca6-7178-4dbf-8dad-6a63684c7a8e}*SharedItemsImports = 5 @@ -173,6 +175,10 @@ Global {7C330493-9BF7-4DB6-815B-807C08500AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C330493-9BF7-4DB6-815B-807C08500AC6}.Release|Any CPU.ActiveCfg = Release|Any CPU {7C330493-9BF7-4DB6-815B-807C08500AC6}.Release|Any CPU.Build.0 = Release|Any CPU + {B2EA65BD-9FFE-4452-B2DC-574EB1A9FAF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2EA65BD-9FFE-4452-B2DC-574EB1A9FAF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2EA65BD-9FFE-4452-B2DC-574EB1A9FAF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2EA65BD-9FFE-4452-B2DC-574EB1A9FAF1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -203,6 +209,7 @@ Global {F2266C44-C8C5-45AD-AA9B-44F8825BDF63} = {11C7056E-93C1-408B-BD87-5270595BBE0E} {74444ED0-9044-4DF7-A111-7D9F81ADF0FD} = {BD466B5C-D8B0-4069-98A9-6DC8F01FA757} {7C330493-9BF7-4DB6-815B-807C08500AC6} = {C3A0C716-BDEA-4393-B223-AF8F8531522A} + {B2EA65BD-9FFE-4452-B2DC-574EB1A9FAF1} = {C3A0C716-BDEA-4393-B223-AF8F8531522A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5A4B2863-1763-4496-B122-651A38A4F5D7} diff --git a/README.md b/README.md index 1dcc31333..0e42046e2 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ We welcome community contributions and pull requests. See [CONTRIBUTING](https:/ * [AWS Developer Guide](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/deployment-tool.html) Find additional information about developing, deploying, and maintaining your applications using the AWS .Net deployment tool. * [AWS Developer Center - Explore .NET on AWS](https://aws.amazon.com/developer/language/net/) Find all the .NET code samples, step-by-step guides, videos, blog content, tools, and information about live events that you need in one place. * [AWS Developer Blog - .NET](https://aws.amazon.com/blogs/developer/category/programing-language/dot-net/) Come see what .NET developers at AWS are up to! Learn about new .NET software announcements, guides, and how-to's. +* [AWS re:Invent 2021 - What’s new with .NET development and deployment on AWS](https://www.youtube.com/watch?v=UvTJ_Inb634) New deployment tooling incorporates best AWS practices right from the start, providing you with recommendations and the optimal deployment option for your .NET application. * [@dotnetonaws](https://twitter.com/dotnetonaws) Follow us on twitter! * Deployment tool blog posts * [Reimagining the AWS .NET deployment experience](http://aws.amazon.com/blogs/developer/reimagining-the-aws-net-deployment-experience/) diff --git a/src/AWS.Deploy.CLI/Commands/DeployCommand.cs b/src/AWS.Deploy.CLI/Commands/DeployCommand.cs index 43a01089e..9a7ed1ad7 100644 --- a/src/AWS.Deploy.CLI/Commands/DeployCommand.cs +++ b/src/AWS.Deploy.CLI/Commands/DeployCommand.cs @@ -240,7 +240,7 @@ public async Task EvaluateSystemCapabilities(Recommendation selectedRecommendati var missingCapabilitiesMessage = ""; foreach (var capability in systemCapabilities) { - missingCapabilitiesMessage = $"{missingCapabilitiesMessage}{capability.GetMessage()}{Environment.NewLine}"; + missingCapabilitiesMessage = $"{missingCapabilitiesMessage}{Environment.NewLine}{capability.GetMessage()}{Environment.NewLine}"; } if (systemCapabilities.Any()) diff --git a/src/AWS.Deploy.Constants/CDK.cs b/src/AWS.Deploy.Constants/CDK.cs index e2a7dcc2e..2dc62315f 100644 --- a/src/AWS.Deploy.Constants/CDK.cs +++ b/src/AWS.Deploy.Constants/CDK.cs @@ -21,6 +21,6 @@ internal static class CDK /// /// Default version of CDK CLI /// - public static readonly Version DefaultCDKVersion = Version.Parse("1.107.0"); + public static readonly Version DefaultCDKVersion = Version.Parse("2.13.0"); } } diff --git a/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs b/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs index a73cfdfcd..f4c1a26b8 100644 --- a/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs +++ b/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs @@ -79,12 +79,13 @@ public async Task DeployCdkProject(OrchestratorSession session, CloudApplication _interactiveService.LogMessageLine("Deploying AWS CDK project"); + var appSettingsFilePath = Path.Combine(cdkProjectPath, "appsettings.json"); + // Ensure region is bootstrapped - await _commandLineWrapper.Run($"npx cdk bootstrap aws://{session.AWSAccountId}/{session.AWSRegion}", + await _commandLineWrapper.Run($"npx cdk bootstrap aws://{session.AWSAccountId}/{session.AWSRegion} -c {Constants.CloudFormationIdentifier.SETTINGS_PATH_CDK_CONTEXT_PARAMETER}=\"{appSettingsFilePath}\"", + workingDirectory: cdkProjectPath, needAwsCredentials: true); - var appSettingsFilePath = Path.Combine(cdkProjectPath, "appsettings.json"); - var deploymentStartDate = DateTime.Now; // Handover to CDK command line tool // Use a CDK Context parameter to specify the settings file that has been serialized. diff --git a/src/AWS.Deploy.Orchestration/SystemCapabilities.cs b/src/AWS.Deploy.Orchestration/SystemCapabilities.cs index 93037d2db..102fe1cf5 100644 --- a/src/AWS.Deploy.Orchestration/SystemCapabilities.cs +++ b/src/AWS.Deploy.Orchestration/SystemCapabilities.cs @@ -48,7 +48,12 @@ public SystemCapability(string name, bool installed, bool available) public string GetMessage() { if (!string.IsNullOrEmpty(Message)) - return Message; + { + if (!string.IsNullOrEmpty(InstallationUrl)) + return $"{Message} {InstallationUrl}"; + else + return Message; + } var availabilityMessage = Available ? "and available" : "but not available"; var installationMessage = Installed ? $"installed {availabilityMessage}" : "not installed"; diff --git a/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs b/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs index eff889504..ae7096cda 100644 --- a/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs +++ b/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs @@ -92,14 +92,14 @@ public async Task> EvaluateSystemCapabilities(Recommendat { capabilities.Add(new SystemCapability("NodeJS", false, false) { InstallationUrl = "https://nodejs.org/en/download/", - Message = "The selected deployment uses the AWS CDK, which requires Node.js. The latest LTS version of Node.js is recommended and can be installed from https://nodejs.org/en/download/. Specifically, AWS CDK requires 10.13.0+ to work properly." + Message = $"The selected deployment uses the AWS CDK, which requires Node.js. AWS CDK requires {MinimumNodeJSVersion} of Node.js or later, and the latest LTS version is recommended." }); } else if (systemCapabilities.NodeJsVersion < MinimumNodeJSVersion) { capabilities.Add(new SystemCapability("NodeJS", false, false) { InstallationUrl = "https://nodejs.org/en/download/", - Message = $"The selected deployment uses the AWS CDK, which requires version of Node.js higher than your current installation ({systemCapabilities.NodeJsVersion}). The latest LTS version of Node.js is recommended and can be installed from https://nodejs.org/en/download/. Specifically, AWS CDK requires 10.3+ to work properly." + Message = $"The selected deployment uses the AWS CDK, which requires a version of Node.js higher than your current installation ({systemCapabilities.NodeJsVersion}). AWS CDK requires {MinimumNodeJSVersion} of Node.js or later, and the latest LTS version is recommended." }); } } @@ -111,7 +111,7 @@ public async Task> EvaluateSystemCapabilities(Recommendat capabilities.Add(new SystemCapability("Docker", false, false) { InstallationUrl = "https://docs.docker.com/engine/install/", - Message = "The selected deployment option requires Docker, which was not detected. Please install and start the appropriate version of Docker for your OS: https://docs.docker.com/engine/install/" + Message = "The selected deployment option requires Docker, which was not detected. Please install and start the appropriate version of Docker for your OS." }); } else if (!systemCapabilities.DockerInfo.DockerContainerType.Equals("linux", StringComparison.OrdinalIgnoreCase)) diff --git a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalk.recipe b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalk.recipe index f92cfca1f..04b9e25c5 100644 --- a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalk.recipe +++ b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalk.recipe @@ -32,7 +32,7 @@ "Type": "MSProperty", "Condition": { "PropertyName": "TargetFramework", - "AllowedValues": [ "netcoreapp2.1", "netcoreapp3.1", "net5.0" ] + "AllowedValues": [ "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net6.0" ] } } ], diff --git a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe index 5d1fa5f69..373e982f6 100644 --- a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe +++ b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe @@ -24,7 +24,7 @@ "Type": "MSProperty", "Condition": { "PropertyName": "TargetFramework", - "AllowedValues": [ "netcoreapp2.1", "netcoreapp3.1", "net5.0" ] + "AllowedValues": [ "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net6.0" ] } } ], diff --git a/test/AWS.Deploy.CLI.UnitTests/Constants.cs b/test/AWS.Deploy.CLI.UnitTests/Constants.cs index eabd23414..c03a5ac4b 100644 --- a/test/AWS.Deploy.CLI.UnitTests/Constants.cs +++ b/test/AWS.Deploy.CLI.UnitTests/Constants.cs @@ -7,6 +7,7 @@ internal static class Constants { public const string ASPNET_CORE_ASPNET_CORE_FARGATE_RECIPE_ID = "AspNetAppEcsFargate"; public const string ASPNET_CORE_BEANSTALK_RECIPE_ID = "AspNetAppElasticBeanstalkLinux"; + public const string ASPNET_CORE_APPRUNNER_ID = "AspNetAppAppRunner"; public const string CONSOLE_APP_FARGATE_SERVICE_RECIPE_ID = "ConsoleAppEcsFargateService"; public const string CONSOLE_APP_FARGATE_SCHEDULE_TASK_RECIPE_ID = "ConsoleAppEcsFargateScheduleTask"; diff --git a/test/AWS.Deploy.CLI.UnitTests/RecommendationTests.cs b/test/AWS.Deploy.CLI.UnitTests/RecommendationTests.cs index 43b77c4f1..a4c58a27d 100644 --- a/test/AWS.Deploy.CLI.UnitTests/RecommendationTests.cs +++ b/test/AWS.Deploy.CLI.UnitTests/RecommendationTests.cs @@ -64,6 +64,26 @@ public async Task WebAppNoDockerFileTest() .ShouldBeTrue("Failed to receive Recommendation: " + Constants.ASPNET_CORE_ASPNET_CORE_FARGATE_RECIPE_ID); } + [Fact] + public async Task WebApiNET6() + { + var engine = await BuildRecommendationEngine("WebApiNET6"); + + var recommendations = await engine.ComputeRecommendations(); + + recommendations + .Any(r => r.Recipe.Id == Constants.ASPNET_CORE_BEANSTALK_RECIPE_ID) + .ShouldBeTrue("Failed to receive Recommendation: " + Constants.ASPNET_CORE_BEANSTALK_RECIPE_ID); + + recommendations + .Any(r => r.Recipe.Id == Constants.ASPNET_CORE_ASPNET_CORE_FARGATE_RECIPE_ID) + .ShouldBeTrue("Failed to receive Recommendation: " + Constants.ASPNET_CORE_ASPNET_CORE_FARGATE_RECIPE_ID); + + recommendations + .Any(r => r.Recipe.Id == Constants.ASPNET_CORE_APPRUNNER_ID) + .ShouldBeTrue("Failed to receive Recommendation: " + Constants.ASPNET_CORE_APPRUNNER_ID); + } + [Fact] public async Task WebAppWithDockerFileTest() { diff --git a/test/AWS.Deploy.Orchestration.UnitTests/CDK/CDKVersionDetectorTests.cs b/test/AWS.Deploy.Orchestration.UnitTests/CDK/CDKVersionDetectorTests.cs index eb677d40e..a56493566 100644 --- a/test/AWS.Deploy.Orchestration.UnitTests/CDK/CDKVersionDetectorTests.cs +++ b/test/AWS.Deploy.Orchestration.UnitTests/CDK/CDKVersionDetectorTests.cs @@ -18,9 +18,9 @@ public CDKVersionDetectorTests() } [Theory] - [InlineData("MixedReferences", "1.109.0")] - [InlineData("SameReferences", "1.108.0")] - [InlineData("NoReferences", "1.107.0")] + [InlineData("MixedReferences", "2.15.0")] + [InlineData("SameReferences", "2.14.0")] + [InlineData("NoReferences", "2.13.0")] public void Detect_CSProjPath(string fileName, string expectedVersion) { var csprojPath = Path.Combine("CDK", "CSProjFiles", fileName); @@ -38,7 +38,7 @@ public void Detect_CSProjPaths() "NoReferences" }.Select(fileName => Path.Combine("CDK", "CSProjFiles", fileName)); var version = _cdkVersionDetector.Detect(csprojPaths); - Assert.Equal("1.109.0", version.ToString()); + Assert.Equal("2.15.0", version.ToString()); } } } diff --git a/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/MixedReferences b/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/MixedReferences index 4bf1d90d6..b4de98cd1 100644 --- a/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/MixedReferences +++ b/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/MixedReferences @@ -1,10 +1,10 @@ - - - - + + + + diff --git a/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/SameReferences b/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/SameReferences index 3c08c5aa8..e520be87a 100644 --- a/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/SameReferences +++ b/test/AWS.Deploy.Orchestration.UnitTests/CDK/CSProjFiles/SameReferences @@ -1,9 +1,9 @@ - - - + + + diff --git a/testapps/WebApiNET6/Program.cs b/testapps/WebApiNET6/Program.cs new file mode 100644 index 000000000..a1f9c1834 --- /dev/null +++ b/testapps/WebApiNET6/Program.cs @@ -0,0 +1,12 @@ +var builder = WebApplication.CreateBuilder(args); + +var app = builder.Build(); + +app.UseHttpsRedirection(); + +app.MapGet("/", () => +{ + return "Hello"; +}); + +app.Run(); diff --git a/testapps/WebApiNET6/WebApiNET6.csproj b/testapps/WebApiNET6/WebApiNET6.csproj new file mode 100644 index 000000000..c78c9c7e8 --- /dev/null +++ b/testapps/WebApiNET6/WebApiNET6.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/testapps/WebApiNET6/appsettings.Development.json b/testapps/WebApiNET6/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/testapps/WebApiNET6/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/testapps/WebApiNET6/appsettings.json b/testapps/WebApiNET6/appsettings.json new file mode 100644 index 000000000..10f68b8c8 --- /dev/null +++ b/testapps/WebApiNET6/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/version.json b/version.json index 5e160c17d..422ab96e2 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.36", + "version": "0.37", "publicReleaseRefSpec": [ ".*" ],