diff --git a/src/AWS.Deploy.Constants/RecipeIdentifier.cs b/src/AWS.Deploy.Constants/RecipeIdentifier.cs index b59fc259f..bb7a48052 100644 --- a/src/AWS.Deploy.Constants/RecipeIdentifier.cs +++ b/src/AWS.Deploy.Constants/RecipeIdentifier.cs @@ -36,5 +36,7 @@ internal static class RecipeIdentifier /// Id for the 'dotnet build --self-contained' recipe option /// public const string DotnetPublishSelfContainedBuildOptionId = "SelfContainedBuild"; + + public const string TARGET_SERVICE_ELASTIC_BEANSTALK = "AWS Elastic Beanstalk"; } } diff --git a/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs b/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs index 94ae57ffd..d810fbd6f 100644 --- a/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs +++ b/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs @@ -13,6 +13,7 @@ using AWS.Deploy.Common.IO; using AWS.Deploy.Common.Recipes; using AWS.Deploy.Common.Utilities; +using AWS.Deploy.Constants; using AWS.Deploy.Orchestration.Data; using AWS.Deploy.Orchestration.Utilities; @@ -103,6 +104,13 @@ public async Task CreateDotnetPublishZip(Recommendation recommendation) _interactiveService.LogInfoMessage(string.Empty); _interactiveService.LogInfoMessage("Creating Dotnet Publish Zip file..."); + // Since Beanstalk doesn't currently have .NET 7 preinstalled we need to make sure we are doing a self contained publish when creating the deployment bundle. + if (recommendation.Recipe.TargetService == RecipeIdentifier.TARGET_SERVICE_ELASTIC_BEANSTALK && recommendation.ProjectDefinition.TargetFramework == "net7.0") + { + _interactiveService.LogInfoMessage("Using self contained publish since AWS Elastic Beanstalk does not currently have .NET 7 preinstalled"); + recommendation.DeploymentBundle.DotnetPublishSelfContainedBuild = true; + } + var publishDirectoryInfo = _directoryManager.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())); var additionalArguments = recommendation.DeploymentBundle.DotnetPublishAdditionalBuildArguments; var runtimeArg = diff --git a/src/AWS.Deploy.Orchestration/DeploymentCommands/BeanstalkEnvironmentDeploymentCommand.cs b/src/AWS.Deploy.Orchestration/DeploymentCommands/BeanstalkEnvironmentDeploymentCommand.cs index 222b477b2..c4dfe1c78 100644 --- a/src/AWS.Deploy.Orchestration/DeploymentCommands/BeanstalkEnvironmentDeploymentCommand.cs +++ b/src/AWS.Deploy.Orchestration/DeploymentCommands/BeanstalkEnvironmentDeploymentCommand.cs @@ -44,6 +44,10 @@ public async Task ExecuteAsync(Orchestrator orchestrator, CloudApplication cloud { elasticBeanstalkHandler.SetupWindowsDeploymentManifest(recommendation, deploymentPackage); } + else if (recommendation.Recipe.Id.Equals(Constants.RecipeIdentifier.EXISTING_BEANSTALK_ENVIRONMENT_RECIPE_ID)) + { + elasticBeanstalkHandler.SetupProcfileForSelfContained(deploymentPackage); + } var versionLabel = $"v-{DateTime.Now.Ticks}"; var s3location = await elasticBeanstalkHandler.CreateApplicationStorageLocationAsync(applicationName, versionLabel, deploymentPackage); diff --git a/src/AWS.Deploy.Orchestration/ServiceHandlers/AWSElasticBeanstalkHandler.cs b/src/AWS.Deploy.Orchestration/ServiceHandlers/AWSElasticBeanstalkHandler.cs index 3baccb316..e2d374142 100644 --- a/src/AWS.Deploy.Orchestration/ServiceHandlers/AWSElasticBeanstalkHandler.cs +++ b/src/AWS.Deploy.Orchestration/ServiceHandlers/AWSElasticBeanstalkHandler.cs @@ -26,6 +26,14 @@ public interface IElasticBeanstalkHandler /// The two main settings that are updated are IIS Website and IIS App Path. /// void SetupWindowsDeploymentManifest(Recommendation recommendation, string dotnetZipFilePath); + + /// + /// When deploying a self contained deployment bundle, Beanstalk needs a Procfile to tell the environment what process to start up. + /// Check out the AWS Elastic Beanstalk developer guide for more information on Procfiles + /// https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/dotnet-linux-procfile.html + /// + void SetupProcfileForSelfContained(string dotnetZipFilePath); + Task CreateApplicationStorageLocationAsync(string applicationName, string versionLabel, string deploymentPackage); Task CreateApplicationVersionAsync(string applicationName, string versionLabel, S3Location sourceBundle); Task UpdateEnvironmentAsync(string applicationName, string environmentName, string versionLabel, List optionSettings); @@ -204,6 +212,65 @@ public void SetupWindowsDeploymentManifest(Recommendation recommendation, string } } + /// + /// When deploying a self contained deployment bundle, Beanstalk needs a Procfile to tell the environment what process to start up. + /// Check out the AWS Elastic Beanstalk developer guide for more information on Procfiles + /// https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/dotnet-linux-procfile.html + /// + /// This code is a copy of the code in the AspNetAppElasticBeanstalkLinux CDK recipe definition. Any changes to this method + /// should be made into that version as well. + /// + /// + public void SetupProcfileForSelfContained(string dotnetZipFilePath) + { + const string RUNTIME_CONFIG_SUFFIX = ".runtimeconfig.json"; + const string PROCFILE_NAME = "Procfile"; + + string runtimeConfigFilename; + string runtimeConfigJson; + using (var zipArchive = ZipFile.Open(dotnetZipFilePath, ZipArchiveMode.Read)) + { + // Skip Procfile setup if one already exists. + if (zipArchive.GetEntry(PROCFILE_NAME) != null) + { + return; + } + + var runtimeConfigEntry = zipArchive.Entries.FirstOrDefault(x => x.Name.EndsWith(RUNTIME_CONFIG_SUFFIX)); + if (runtimeConfigEntry == null) + { + return; + } + + runtimeConfigFilename = runtimeConfigEntry.Name; + using var stream = runtimeConfigEntry.Open(); + runtimeConfigJson = new StreamReader(stream).ReadToEnd(); + } + + var runtimeConfigDoc = JsonDocument.Parse(runtimeConfigJson); + + if (!runtimeConfigDoc.RootElement.TryGetProperty("runtimeOptions", out var runtimeOptionsNode)) + { + return; + } + + // If there are includedFrameworks then the zip file is a self contained deployment bundle. + if (!runtimeOptionsNode.TryGetProperty("includedFrameworks", out _)) + { + return; + } + + var executableName = runtimeConfigFilename.Substring(0, runtimeConfigFilename.Length - RUNTIME_CONFIG_SUFFIX.Length); + var procCommand = $"web: ./{executableName}"; + + using (var zipArchive = ZipFile.Open(dotnetZipFilePath, ZipArchiveMode.Update)) + { + var procfileEntry = zipArchive.CreateEntry(PROCFILE_NAME); + using var zipEntryStream = procfileEntry.Open(); + zipEntryStream.Write(System.Text.UTF8Encoding.UTF8.GetBytes(procCommand)); + } + } + public async Task CreateApplicationStorageLocationAsync(string applicationName, string versionLabel, string deploymentPackage) { string bucketName; diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/Generated/Recipe.cs b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/Generated/Recipe.cs index cdd5d5a1b..6750e49ba 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/Generated/Recipe.cs +++ b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/Generated/Recipe.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; +using System.IO.Compression; +using System.Text.Json; using Amazon.CDK; using Amazon.CDK.AWS.ElasticBeanstalk; using Amazon.CDK.AWS.IAM; @@ -13,6 +15,7 @@ using Constructs; using System.Linq; using Amazon.CDK.AWS.EC2; +using System.IO; // This is a generated file from the original deployment recipe. It is recommended to not modify this file in order // to allow easy updates to the file when the original recipe that this project was created from has updates. @@ -59,6 +62,9 @@ public Recipe(Construct scope, IRecipeProps props) if (string.IsNullOrEmpty(props.DotnetPublishZipPath)) throw new InvalidOrMissingConfigurationException("The provided path containing the dotnet publish zip file is null or empty."); + // Self contained deployment bundles need a Procfile to tell Beanstalk what process to start. + SetupProcfileForSelfContained(props.DotnetPublishZipPath); + ApplicationAsset = new Asset(this, "Asset", new AssetProps { Path = props.DotnetPublishZipPath @@ -480,5 +486,61 @@ private void ConfigureBeanstalkEnvironment(Configuration settings, string beanst VersionLabel = ApplicationVersion.Ref, })); } + + /// + /// When deploying a self contained deployment bundle, Beanstalk needs a Procfile to tell the environment what process to start up. + /// Check out the AWS Elastic Beanstalk developer guide for more information on Procfiles + /// https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/dotnet-linux-procfile.html + /// + /// + static void SetupProcfileForSelfContained(string dotnetZipFilePath) + { + const string RUNTIME_CONFIG_SUFFIX = ".runtimeconfig.json"; + const string PROCFILE_NAME = "Procfile"; + + string runtimeConfigFilename; + string runtimeConfigJson; + using (var zipArchive = ZipFile.Open(dotnetZipFilePath, ZipArchiveMode.Read)) + { + // Skip Procfile setup if one already exists. + if (zipArchive.GetEntry(PROCFILE_NAME) != null) + { + return; + } + + var runtimeConfigEntry = zipArchive.Entries.FirstOrDefault(x => x.Name.EndsWith(RUNTIME_CONFIG_SUFFIX)); + if (runtimeConfigEntry == null) + { + return; + } + + runtimeConfigFilename = runtimeConfigEntry.Name; + using var stream = runtimeConfigEntry.Open(); + runtimeConfigJson = new StreamReader(stream).ReadToEnd(); + } + + var runtimeConfigDoc = JsonDocument.Parse(runtimeConfigJson); + + if (!runtimeConfigDoc.RootElement.TryGetProperty("runtimeOptions", out var runtimeOptionsNode)) + { + return; + } + + // If there are includedFrameworks then the zip file is a self contained deployment bundle. + if (!runtimeOptionsNode.TryGetProperty("includedFrameworks", out _)) + { + return; + } + + var executableName = runtimeConfigFilename.Substring(0, runtimeConfigFilename.Length - RUNTIME_CONFIG_SUFFIX.Length); + var procCommand = $"web: ./{executableName}"; + + using (var zipArchive = ZipFile.Open(dotnetZipFilePath, ZipArchiveMode.Update)) + { + var procfileEntry = zipArchive.CreateEntry(PROCFILE_NAME); + using var zipEntryStream = procfileEntry.Open(); + zipEntryStream.Write(System.Text.UTF8Encoding.UTF8.GetBytes(procCommand)); + } + } } } diff --git a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkLinux.recipe b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkLinux.recipe index bc6bcddf7..124594d5b 100644 --- a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkLinux.recipe +++ b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkLinux.recipe @@ -33,7 +33,7 @@ "Type": "MSProperty", "Condition": { "PropertyName": "TargetFramework", - "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0" ] + "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0", "net7.0" ] } } ], diff --git a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkWindows.recipe b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkWindows.recipe index 5ffae04ab..f087695aa 100644 --- a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkWindows.recipe +++ b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppElasticBeanstalkWindows.recipe @@ -33,7 +33,7 @@ "Type": "MSProperty", "Condition": { "PropertyName": "TargetFramework", - "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0" ] + "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0", "net7.0" ] } } ], diff --git a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe index cc2d64acd..15ba478ae 100644 --- a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe +++ b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkEnvironment.recipe @@ -25,7 +25,7 @@ "Type": "MSProperty", "Condition": { "PropertyName": "TargetFramework", - "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0" ] + "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0", "net7.0" ] } } ], diff --git a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkWindowsEnvironment.recipe b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkWindowsEnvironment.recipe index 12b92969f..ec0c319a6 100644 --- a/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkWindowsEnvironment.recipe +++ b/src/AWS.Deploy.Recipes/RecipeDefinitions/ASP.NETAppExistingBeanstalkWindowsEnvironment.recipe @@ -25,7 +25,7 @@ "Type": "MSProperty", "Condition": { "PropertyName": "TargetFramework", - "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0" ] + "AllowedValues": [ "netcoreapp3.1", "net5.0", "net6.0", "net7.0" ] } } ], diff --git a/test/AWS.Deploy.CLI.IntegrationTests/BeanstalkBackwardsCompatibilityTests/CLITests.cs b/test/AWS.Deploy.CLI.IntegrationTests/BeanstalkBackwardsCompatibilityTests/CLITests.cs index d2a91b38f..75947133b 100644 --- a/test/AWS.Deploy.CLI.IntegrationTests/BeanstalkBackwardsCompatibilityTests/CLITests.cs +++ b/test/AWS.Deploy.CLI.IntegrationTests/BeanstalkBackwardsCompatibilityTests/CLITests.cs @@ -40,5 +40,26 @@ public async Task DeployToExistingBeanstalkEnvironment() var expectedVersionLabel = successMessage.Split(" ").Last(); Assert.True(await _fixture.EBHelper.VerifyEnvironmentVersionLabel(_fixture.EnvironmentName, expectedVersionLabel)); } + + [Fact] + public async Task DeployToExistingBeanstalkEnvironmentSelfContained() + { + var projectPath = _fixture.TestAppManager.GetProjectPath(Path.Combine("testapps", "WebAppNoDockerFile", "WebAppNoDockerFile.csproj")); + var deployArgs = new[] { "deploy", "--project-path", projectPath, "--application-name", _fixture.EnvironmentName, "--diagnostics", "--silent", "--region", "us-west-2", "--apply", "Existing-ElasticBeanStalkConfigFile-Linux-SelfContained.json" }; + Assert.Equal(CommandReturnCodes.SUCCESS, await _fixture.App.Run(deployArgs)); + + var environmentDescription = await _fixture.AWSResourceQueryer.DescribeElasticBeanstalkEnvironment(_fixture.EnvironmentName); + + // URL could take few more minutes to come live, therefore, we want to wait and keep trying for a specified timeout + await _fixture.HttpHelper.WaitUntilSuccessStatusCode(environmentDescription.CNAME, TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(5)); + + var successMessagePrefix = $"The Elastic Beanstalk Environment {_fixture.EnvironmentName} has been successfully updated"; + var deployStdOutput = _fixture.InteractiveService.StdOutReader.ReadAllLines(); + var successMessage = deployStdOutput.First(line => line.Trim().StartsWith(successMessagePrefix)); + Assert.False(string.IsNullOrEmpty(successMessage)); + + var expectedVersionLabel = successMessage.Split(" ").Last(); + Assert.True(await _fixture.EBHelper.VerifyEnvironmentVersionLabel(_fixture.EnvironmentName, expectedVersionLabel)); + } } } diff --git a/test/AWS.Deploy.CLI.IntegrationTests/WebAppNoDockerFileTests.cs b/test/AWS.Deploy.CLI.IntegrationTests/WebAppNoDockerFileTests.cs index 77ad2fe97..1169d275a 100644 --- a/test/AWS.Deploy.CLI.IntegrationTests/WebAppNoDockerFileTests.cs +++ b/test/AWS.Deploy.CLI.IntegrationTests/WebAppNoDockerFileTests.cs @@ -68,72 +68,14 @@ public WebAppNoDockerFileTests() _testAppManager = new TestAppManager(); } - [Fact] - public async Task DefaultConfigurations() - { - _stackName = $"WebAppNoDockerFile{Guid.NewGuid().ToString().Split('-').Last()}"; - var saveSettingsFilePath = Path.Combine(Path.GetTempPath(), $"DeploymentSettings-{Guid.NewGuid().ToString().Split('-').Last()}.json"); - - // Arrange input for deploy - await _interactiveService.StdInWriter.WriteAsync(Environment.NewLine); // Select default recommendation - await _interactiveService.StdInWriter.WriteAsync(Environment.NewLine); // Select default option settings - await _interactiveService.StdInWriter.FlushAsync(); - - // Deploy - var projectPath = _testAppManager.GetProjectPath(Path.Combine("testapps", "WebAppNoDockerFile", "WebAppNoDockerFile.csproj")); - var deployArgs = new[] { "deploy", "--project-path", projectPath, "--application-name", _stackName, "--diagnostics", "--save-settings", saveSettingsFilePath }; - Assert.Equal(CommandReturnCodes.SUCCESS, await _app.Run(deployArgs)); - - // Verify application is deployed and running - Assert.Equal(StackStatus.CREATE_COMPLETE, await _cloudFormationHelper.GetStackStatus(_stackName)); - - var deployStdOut = _interactiveService.StdOutReader.ReadAllLines(); - - var tempCdkProjectLine = deployStdOut.First(line => line.StartsWith("Saving AWS CDK deployment project to: ")); - var tempCdkProject = tempCdkProjectLine.Split(": ")[1].Trim(); - Assert.False(Directory.Exists(tempCdkProject), $"{tempCdkProject} must not exist."); - - // Example: Endpoint: http://52.36.216.238/ - var endpointLine = deployStdOut.First(line => line.Trim().StartsWith($"Endpoint")); - var applicationUrl = endpointLine.Substring(endpointLine.IndexOf(":") + 1).Trim(); - Assert.True(Uri.IsWellFormedUriString(applicationUrl, UriKind.Absolute)); - - // URL could take few more minutes to come live, therefore, we want to wait and keep trying for a specified timeout - await _httpHelper.WaitUntilSuccessStatusCode(applicationUrl, TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(5)); - - // Check the overridden workspace - Assert.True(File.Exists(Path.Combine(_customWorkspace, "CDKBootstrapTemplate.yaml"))); - Assert.True(Directory.Exists(Path.Combine(_customWorkspace, "temp"))); - Assert.True(Directory.Exists(Path.Combine(_customWorkspace, "Projects"))); - - // Verify existence of the saved deployment settings file - Assert.True(File.Exists(saveSettingsFilePath)); - - // list - var listArgs = new[] { "list-deployments", "--diagnostics" }; - Assert.Equal(CommandReturnCodes.SUCCESS, await _app.Run(listArgs));; - - // Verify stack exists in list of deployments - var listStdOut = _interactiveService.StdOutReader.ReadAllLines().Select(x => x.Split()[0]).ToList(); - Assert.Contains(listStdOut, (deployment) => _stackName.Equals(deployment)); - - // Arrange input for delete - // Use --silent flag to delete without user prompts - var deleteArgs = new[] { "delete-deployment", _stackName, "--diagnostics", "--silent" }; - - // Delete - Assert.Equal(CommandReturnCodes.SUCCESS, await _app.Run(deleteArgs));; - - // Verify application is deleted - Assert.True(await _cloudFormationHelper.IsStackDeleted(_stackName), $"{_stackName} still exists."); - } - [Theory] - [InlineData("ElasticBeanStalkConfigFile-Windows.json")] - [InlineData("ElasticBeanStalkConfigFile-Windows-SelfContained.json")] - public async Task WindowsEBDefaultConfigurations(string configFile) + [InlineData("ElasticBeanStalkConfigFile-Linux.json", true)] + [InlineData("ElasticBeanStalkConfigFile-Linux-SelfContained.json", true)] + [InlineData("ElasticBeanStalkConfigFile-Windows.json", false)] + [InlineData("ElasticBeanStalkConfigFile-Windows-SelfContained.json", false)] + public async Task EBDefaultConfigurations(string configFile, bool linux) { - _stackName = $"WinTest-{Guid.NewGuid().ToString().Split('-').Last()}"; + _stackName = $"BeanstalkTest-{Guid.NewGuid().ToString().Split('-').Last()}"; // Deploy var projectPath = _testAppManager.GetProjectPath(Path.Combine("testapps", "WebAppNoDockerFile", "WebAppNoDockerFile.csproj")); @@ -154,8 +96,11 @@ public async Task WindowsEBDefaultConfigurations(string configFile) var applicationUrl = endpointLine.Substring(endpointLine.IndexOf(":") + 1).Trim(); Assert.True(Uri.IsWellFormedUriString(applicationUrl, UriKind.Absolute)); - // "extra-path" is the IISAppPath set in the config file. - applicationUrl = new Uri(new Uri(applicationUrl), "extra-path").AbsoluteUri; + if(!linux) + { + // "extra-path" is the IISAppPath set in the config file. + applicationUrl = new Uri(new Uri(applicationUrl), "extra-path").AbsoluteUri; + } // URL could take few more minutes to come live, therefore, we want to wait and keep trying for a specified timeout await _httpHelper.WaitUntilSuccessStatusCode(applicationUrl, TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(5)); diff --git a/testapps/WebAppNoDockerFile/ElasticBeanStalkConfigFile-Linux-SelfContained.json b/testapps/WebAppNoDockerFile/ElasticBeanStalkConfigFile-Linux-SelfContained.json new file mode 100644 index 000000000..91dbb6eb2 --- /dev/null +++ b/testapps/WebAppNoDockerFile/ElasticBeanStalkConfigFile-Linux-SelfContained.json @@ -0,0 +1,6 @@ +{ + "RecipeId": "AspNetAppElasticBeanstalkLinux", + "Settings": { + "SelfContainedBuild": true + } +} diff --git a/testapps/WebAppNoDockerFile/ElasticBeanStalkConfigFile-Linux.json b/testapps/WebAppNoDockerFile/ElasticBeanStalkConfigFile-Linux.json new file mode 100644 index 000000000..7a4522bc1 --- /dev/null +++ b/testapps/WebAppNoDockerFile/ElasticBeanStalkConfigFile-Linux.json @@ -0,0 +1,6 @@ +{ + "RecipeId": "AspNetAppElasticBeanstalkLinux", + "Settings": { + + } +} diff --git a/testapps/WebAppNoDockerFile/Existing-ElasticBeanStalkConfigFile-Linux-SelfContained.json b/testapps/WebAppNoDockerFile/Existing-ElasticBeanStalkConfigFile-Linux-SelfContained.json new file mode 100644 index 000000000..a8b1de88a --- /dev/null +++ b/testapps/WebAppNoDockerFile/Existing-ElasticBeanStalkConfigFile-Linux-SelfContained.json @@ -0,0 +1,6 @@ +{ + "RecipeId": "AspNetAppExistingBeanstalkEnvironment", + "Settings": { + "SelfContainedBuild": true + } +} diff --git a/testapps/WebAppNoDockerFile/WebAppNoDockerFile.csproj b/testapps/WebAppNoDockerFile/WebAppNoDockerFile.csproj index 96312487f..3e6549c20 100644 --- a/testapps/WebAppNoDockerFile/WebAppNoDockerFile.csproj +++ b/testapps/WebAppNoDockerFile/WebAppNoDockerFile.csproj @@ -5,6 +5,15 @@ + + Always + + + Always + + + Always + Always