Skip to content

Commit

Permalink
commit 1
Browse files Browse the repository at this point in the history
  • Loading branch information
philasmar committed Oct 14, 2024
1 parent 628fb39 commit fa3e83a
Show file tree
Hide file tree
Showing 24 changed files with 526 additions and 28 deletions.
7 changes: 7 additions & 0 deletions AWS.Deploy.sln
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWS.Deploy.DocGenerator.Uni
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWS.Deploy.DockerImageUploader", "test\AWS.Deploy.DockerImageUploader\AWS.Deploy.DockerImageUploader.csproj", "{49A1C020-F4C8-4B28-A6B2-6AD3C8452E69}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAppArmDeployment", "testapps\WebAppArmDeployment\WebAppArmDeployment.csproj", "{303A0323-3FEF-4640-80C2-E33A8BC0F1FC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -179,6 +181,10 @@ Global
{49A1C020-F4C8-4B28-A6B2-6AD3C8452E69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49A1C020-F4C8-4B28-A6B2-6AD3C8452E69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49A1C020-F4C8-4B28-A6B2-6AD3C8452E69}.Release|Any CPU.Build.0 = Release|Any CPU
{303A0323-3FEF-4640-80C2-E33A8BC0F1FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{303A0323-3FEF-4640-80C2-E33A8BC0F1FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{303A0323-3FEF-4640-80C2-E33A8BC0F1FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{303A0323-3FEF-4640-80C2-E33A8BC0F1FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -211,6 +217,7 @@ Global
{6D4BD0C2-C2A0-4AFB-BC22-623DD64A4F84} = {11C7056E-93C1-408B-BD87-5270595BBE0E}
{7E661545-7DFD-4FE3-A5F9-767FAE30DFFE} = {BD466B5C-D8B0-4069-98A9-6DC8F01FA757}
{49A1C020-F4C8-4B28-A6B2-6AD3C8452E69} = {BD466B5C-D8B0-4069-98A9-6DC8F01FA757}
{303A0323-3FEF-4640-80C2-E33A8BC0F1FC} = {C3A0C716-BDEA-4393-B223-AF8F8531522A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5A4B2863-1763-4496-B122-651A38A4F5D7}
Expand Down
4 changes: 3 additions & 1 deletion src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,13 @@ public async Task<string> CreateDotnetPublishZip(Recommendation recommendation)

var publishDirectoryInfo = _directoryManager.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
var additionalArguments = recommendation.DeploymentBundle.DotnetPublishAdditionalBuildArguments;
var windowsPlatform = recommendation.DeploymentBundle.EnvironmentArchitecture == SupportedArchitecture.Arm64 ? "win-arm64" : "win-x64";
var linuxPlatform = recommendation.DeploymentBundle.EnvironmentArchitecture == SupportedArchitecture.Arm64 ? "linux-arm64" : "linux-x64";
var runtimeArg =
recommendation.DeploymentBundle.DotnetPublishSelfContainedBuild &&
!additionalArguments.Contains("--runtime ") &&
!additionalArguments.Contains("-r ")
? $"--runtime {(recommendation.Recipe.TargetPlatform == TargetPlatform.Windows ? "win-x64" : "linux-x64")}"
? $"--runtime {(recommendation.Recipe.TargetPlatform == TargetPlatform.Windows ? windowsPlatform : linuxPlatform)}"
: "";
var publishCommand =
$"dotnet publish \"{recommendation.ProjectPath}\"" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class Recipe : Construct
public const string LOADBALANCERSCHEME_PUBLIC = "public";

public const string REVERSEPROXY_NGINX = "nginx";

public const string ENHANCED_HEALTH_REPORTING = "enhanced";

public Vpc? AppVpc { get; private set; }
Expand Down Expand Up @@ -74,7 +74,7 @@ public Recipe(Construct scope, IRecipeProps<Configuration> props)
ConfigureVpc(settings);
ConfigureIAM(settings);
var beanstalkApplicationName = ConfigureApplication(settings);
ConfigureBeanstalkEnvironment(settings, beanstalkApplicationName);
ConfigureBeanstalkEnvironment(settings, beanstalkApplicationName, props.EnvironmentArchitecture);
}

private void ConfigureVpc(Configuration settings)
Expand Down Expand Up @@ -200,7 +200,7 @@ private string ConfigureApplication(Configuration settings)
return beanstalkApplicationName;
}

private void ConfigureBeanstalkEnvironment(Configuration settings, string beanstalkApplicationName)
private void ConfigureBeanstalkEnvironment(Configuration settings, string beanstalkApplicationName, string? environmentArchitecture)
{
if (Ec2InstanceProfile == null)
throw new InvalidOperationException($"{nameof(Ec2InstanceProfile)} has not been set. The {nameof(ConfigureIAM)} method should be called before {nameof(ConfigureBeanstalkEnvironment)}");
Expand Down Expand Up @@ -242,12 +242,22 @@ private void ConfigureBeanstalkEnvironment(Configuration settings, string beanst
{
optionSettingProperties.Add(new CfnEnvironment.OptionSettingProperty
{
Namespace = "aws:autoscaling:launchconfiguration",
OptionName = "InstanceType",
Namespace = "aws:ec2:instances",
OptionName = "InstanceTypes",
Value = settings.InstanceType
});
}

if (!string.IsNullOrEmpty(environmentArchitecture))
{
optionSettingProperties.Add(new CfnEnvironment.OptionSettingProperty
{
Namespace = "aws:ec2:instances",
OptionName = "SupportedArchitectures",
Value = environmentArchitecture.ToLower()
});
}

if (settings.EnvironmentType.Equals(ENVIRONMENTTYPE_LOADBALANCED))
{
optionSettingProperties.Add(new CfnEnvironment.OptionSettingProperty
Expand Down Expand Up @@ -336,7 +346,7 @@ private void ConfigureBeanstalkEnvironment(Configuration settings, string beanst
}
);
}

if (settings.ElasticBeanstalkRollingUpdates.RollingUpdatesEnabled)
{
optionSettingProperties.Add(new CfnEnvironment.OptionSettingProperty
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "./aws-deploy-recipe-schema.json",
"Id": "AspNetAppElasticBeanstalkLinux",
"Version": "1.0.3",
"Version": "1.1.0",
"Name": "ASP.NET Core App to AWS Elastic Beanstalk on Linux",
"DeploymentType": "CdkProject",
"DeploymentBundle": "DotnetPublishZipFile",
Expand All @@ -11,7 +11,7 @@
"Description": "This ASP.NET Core application will be built and deployed to AWS Elastic Beanstalk on Linux. Recommended if you want to deploy your application directly to EC2 hosts, not as a container image.",
"TargetService": "AWS Elastic Beanstalk",
"TargetPlatform": "Linux",
"SupportedArchitectures": [ "x86_64" ],
"SupportedArchitectures": [ "x86_64", "arm64" ],

"DisplayedResources": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,28 @@ namespace AWS.Deploy.CLI.Common.UnitTests.Extensions
public static class DirectoryCopyExtension
{
/// <summary>
/// <see cref="https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories"/>
/// Copy the contents of a directory to another location including all subdirectories.
/// </summary>
public static void CopyTo(this DirectoryInfo dir, string destDirName, bool copySubDirs)
public static void CopyTo(this DirectoryInfo dir, string destDirName)
{
if (!dir.Exists)
{
throw new DirectoryNotFoundException($"Source directory does not exist or could not be found: {dir.FullName}");
}

var dirs = dir.GetDirectories();

Directory.CreateDirectory(destDirName);

var files = dir.GetFiles();
var files = dir.GetFiles("*", SearchOption.AllDirectories);
foreach (var file in files)
{
var tempPath = Path.Combine(destDirName, file.Name);
file.CopyTo(tempPath, false);
}

if (copySubDirs)
{
foreach (var subdir in dirs)
var relativePath = Path.GetRelativePath(dir.FullName, file.FullName);
var tempPath = Path.Combine(destDirName, relativePath);
var tempDir = Path.GetDirectoryName(tempPath);
if (!string.IsNullOrEmpty(tempDir) && !Directory.Exists(tempDir))
{
var tempPath = Path.Combine(destDirName, subdir.Name);
var subDir = new DirectoryInfo(subdir.FullName);
subDir.CopyTo(tempPath, copySubDirs);
Directory.CreateDirectory(tempDir);
}
file.CopyTo(tempPath, false);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/AWS.Deploy.CLI.Common.UnitTests/IO/TestAppManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public string GetProjectPath(string path)
var sourceTestAppsDir = new DirectoryInfo("testapps");
var tempTestAppsPath = Path.Combine(tempDir, "testapps");
Directory.CreateDirectory(tempTestAppsPath);
sourceTestAppsDir.CopyTo(tempTestAppsPath, true);
sourceTestAppsDir.CopyTo(tempTestAppsPath);
return Path.Combine(tempDir, path);
}
}
Expand Down
59 changes: 56 additions & 3 deletions test/AWS.Deploy.CLI.IntegrationTests/WebAppNoDockerFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public WebAppNoDockerFileTests()

[Theory]
[InlineData("ElasticBeanStalkConfigFile-Linux.json", true)]
[InlineData("ElasticBeanStalkConfigFile-Linux-SelfContained.json", true)]
[InlineData("ElasticBeanStalkConfigFile-Windows.json", false)]
[InlineData("ElasticBeanStalkConfigFile-Windows-SelfContained.json", false)]
// [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 = $"BeanstalkTest-{Guid.NewGuid().ToString().Split('-').Last()}";
Expand Down Expand Up @@ -124,6 +124,59 @@ public async Task EBDefaultConfigurations(string configFile, bool linux)
Assert.True(await _cloudFormationHelper.IsStackDeleted(_stackName), $"{_stackName} still exists.");
}

[Fact]
public async Task BeanstalkArmDeployment()
{
_stackName = $"BeanstalkArm{Guid.NewGuid().ToString().Split('-').Last()}";

// Arrange input for deploy
await _interactiveService.StdInWriter.WriteAsync(Environment.NewLine); // Select default recommendation
await _interactiveService.StdInWriter.WriteLineAsync("7"); // Select "Environment Architecture"
await _interactiveService.StdInWriter.WriteLineAsync("2"); // Select "Arm64"
await _interactiveService.StdInWriter.WriteAsync(Environment.NewLine); // Confirm selection and deploy
await _interactiveService.StdInWriter.FlushAsync();

// Deploy
var projectPath = _testAppManager.GetProjectPath(Path.Combine("testapps", "WebAppArmDeployment", "WebAppArmDeployment.csproj"));
var deployArgs = new[] { "deploy", "--project-path", projectPath, "--application-name", _stackName, "--diagnostics" };
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(":", StringComparison.Ordinal) + 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));

// 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" };

// Delete
Assert.Equal(CommandReturnCodes.SUCCESS, await _app.Run(deleteArgs)); ;

// Verify application is deleted
Assert.True(await _cloudFormationHelper.IsStackDeleted(_stackName), $"{_stackName} still exists.");
}

public void Dispose()
{
Dispose(true);
Expand Down
20 changes: 20 additions & 0 deletions testapps/WebAppArmDeployment/Components/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="WebAppArmDeployment.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>

<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>

</html>
23 changes: 23 additions & 0 deletions testapps/WebAppArmDeployment/Components/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

<article class="content px-4">
@Body
</article>
</main>
</div>

<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}

#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}

#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
Loading

0 comments on commit fa3e83a

Please sign in to comment.