diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md new file mode 100644 index 0000000000..4a1ea97eec --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md @@ -0,0 +1,41 @@ +--- +title: Using Arm-powered Virtual Machines in Amazon Web Services and Google Cloud Platform for running .NET Aspire applications + +minutes_to_complete: 60 + +who_is_this_for: This learning path is for software developers interested in learning how to deploy .NET Aspire applications in AWS and GCP + +learning_objectives: + - Learn about the .NET Aspire. + - Create a project and deploy it to the ARM-powered Virtual Machines in the Cloud. + +prerequisites: + - A Windows on Arm computer such as [Windows Dev Kit 2023](https://learn.microsoft.com/en-us/windows/arm/dev-kit), a Lenovo Thinkpad X13s running Windows 11 or a Windows on Arm [virtual machine](/learning-paths/cross-platform/woa_azure/). + - Any code editor. [Visual Studio Code for Arm64](https://code.visualstudio.com/docs/?dv=win32arm64user) is suitable. + +author_primary: Dawid Borycki + +### Tags +skilllevels: Introductory +subjects: Cloud +cloud_service_providers: AWS, GCP + +armips: + - Neoverse + +tools_software_languages: + - .NET + - C# + - Visual Studio Code + +operatingsystems: + - Windows + - Linux + + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/_next-steps.md new file mode 100644 index 0000000000..7a10611edf --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/_next-steps.md @@ -0,0 +1,40 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +next_step_guidance: > + You can continue learning about how to deploy serverless applications using the Serverless Framework and AWS. +# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended. + +recommended_path: "/learning-paths/servers-and-cloud-computing/serverless-framework-aws-lambda-dynamodb" +# Link to the next learning path being recommended(For example this could be /learning-paths/servers-and-cloud-computing/mongodb). + + +# further_reading links to references related to this path. Can be: + # Manuals for a tool / software mentioned (type: documentation) + # Blog about related topics (type: blog) + # General online references (type: website) + +further_reading: + - resource: + title: .NET Aspire Overview + link: https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview + type: Documentation + - resource: + title: Compute Service - Amazon EC2 + link: https://aws.amazon.com/pm/ec2 + type: Documentation + - resource: + title: Compute Service - Google GCP + link: https://cloud.google.com/products/compute/ + type: Documentation + + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +weight: 21 # set to always be larger than the content in this path, and one more than 'review' +title: "Next Steps" # Always the same +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/_review.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/_review.md new file mode 100644 index 0000000000..64b1d38efe --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/_review.md @@ -0,0 +1,42 @@ +--- +review: + - questions: + question: > + Which command do you use to install the Aspire workload on an Arm-powered VM? + answers: + - sudo apt install aspire + - dotnet workload install aspire + - dotnet install aspire --arm64 + correct_answer: 2 + explanation: > + The correct command to install the Aspire workload is `dotnet workload install aspire`, as it uses the .NET CLI to manage workloads. + + - questions: + question: > + When creating an AWS EC2 instance, which step ensures secure remote access to the VM? + answers: + - Creating a new key pair in the "Key pair (login)" section + - Selecting the appropriate security group for the instance + - Allowing HTTP and HTTPS traffic in the network settings + correct_answer: 1 + explanation: > + Creating a new key pair in the "Key pair (login)" section generates a private key file that is essential for secure SSH access to the EC2 instance. + + - questions: + question: > + In Google Cloud Platform, what series should you select to use an Arm64 processor for your VM? + answers: + - T2A (Ampere Altra Arm) + - E2 (General Purpose) + - N2D (Compute Optimized) + correct_answer: 1 + explanation: > + The T2A series (Ampere Altra Arm) is designed specifically for Arm64 processors and provides cost-effective, high-performance computing in GCP. + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +title: "Review" # Always the same title +weight: 20 # Set to always be larger than the content in this path +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/aws.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/aws.md new file mode 100644 index 0000000000..e0e121721f --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/aws.md @@ -0,0 +1,136 @@ +--- +title: Deploy to AWS EC2 +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +### Objective +The goal of this task is to deploy a .NET Aspire application onto an AWS Virtual Machine (using Amazon Elastic Compute Cloud (EC2)) powered by Arm-based processors, such as AWS Graviton. This involves leveraging the cost and performance benefits of Arm architecture while demonstrating the seamless deployment of cloud-native applications on modern infrastructure. + +Amazon Elastic Compute Cloud (EC2) is a highly scalable and flexible cloud computing service provided by AWS that allows users to run virtual servers, known as instances, on demand. EC2 offers a wide variety of instance types optimized for different workloads, including general-purpose, compute-intensive, memory-intensive, and GPU-enabled tasks. It supports both x86 and Arm architectures, with Arm-powered Graviton instances providing significant cost and performance advantages for specific workloads. EC2 integrates seamlessly with other AWS services, enabling applications to scale automatically, handle varying traffic loads, and maintain high availability. + +### EC2 Instance +Follow these steps to deploy an app to an Arm-powered EC2 instance:: +1. Log in to AWS Management Console [here](http://console.aws.amazon.com) +2. Navigate to EC2 Service. In the search box type "EC2". Then, click EC2: + +![fig5](figures/05.png) + +3. In the EC2 Dashboard, click “Launch Instance” and fill out the following details: +* Name: type arm-server +* AMI: Select Arm-compatible Amazon Machine Image, Ubuntu 22.04 LTS for Arm64. +* Architecture: Select 64-bit (Arm). +* Instance Type: Select t4g.small. + +The configuration should look as follows: + +![fig6](figures/06.png) + +4. Scroll down to "Key pair (login)", and click "Create new key pair". This will display the "Create key pair" window, in which you configure the following: +* Key pair name: arm-key-pair +* Key pair type: RSA +* Private key format: .pem +* Click the Create key pair button, and download the key pair to your computer + +![fig7](figures/07.png) + +5. Scroll down to "Network Settings", where: +* VPC: use default +* Subnet: select no preference +* Auto-assign public IP: Enable +* Firewall: Check Create security group +* Security group name: arm-security-group +* Description: arm-security-group +* Inbound security groups + +![fig8](figures/08.png) + +5. Configure "Inbound Security Group Rules". Specifically, click "Add Rule" and set the following details: +* Type: Custom TCP +* Protocol: TCP +* Port Range: 7133. +* Source: Select Anywhere (0.0.0.0/0) for public access or restrict access to your specific IP for better security. +* Repeat this step for all three ports the application is using. Here I have 7133, 7511, 17222. These must match the values we had, when we run the app locally. + +The configuration should look as follows: + +![fig9](figures/09.png) + +6. Launch an instance by clicking "Launch instance" button. You should see the green box with the Success label. This box also contains a link to the EC2 instance. Click it. It will take you to the instance dashboard, which looks like the one below: + +![fig10](figures/10.png) + +### Deploying an app +Once the EC2 instance is ready, we can connect to it and deploy the application. Follow these steps to connect: +1. Locate the instance public IP (e.g. 98.83.137.101 in my case). +2. Use an SSH client to connect: +* Open the terminal +* Set appropriate permissions for the key pair file (remember to use your IP address) +```console +chmod 400 arm-key-pair.pem +ssh -i arm-key-pair.pem ubuntu@98.83.137.101 +``` + +![fig11](figures/11.png) + +We can now install required components, pull the application code from git, and launch the app: +1. In the EC2 terminal type +```console +sudo apt update && sudo apt upgrade -y +``` + +This will update the package list and upgrade the installed packages. + +2. Install .NET SDK using the following commands: +```console +wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +sudo dpkg -i packages-microsoft-prod.deb +sudo apt update +sudo apt install -y dotnet-sdk-8.0 +``` + +Verify the installation: +```console +dotnet --version +``` + +3. Install the Aspire workload using the dotnet CLI +```console +dotnet workload install aspire +``` + +4. Install git: +```console +sudo apt install -y git +``` + +5. Clone the repository: +```console +git clone https://github.com/dawidborycki/NetAspire.Arm.git +cd NetAspire.Arm/ +``` + +6. Trust trust the development certificate: +```console +dotnet dev-certs https --trust +``` + +7. Build and run the project +```console +dotnet restore +dotnet run --project NetAspire.Arm.AppHost +``` + +The application will run the same way as locally. You should see the following: + +![fig12](figures/12.png) + +Finally, open the application in the web browser (using the EC2's public IP): + +![fig13](figures/13.png) + +### Summary +You have successfully deployed the Aspire app onto an Arm-powered AWS EC2 instance. This demonstrates the compatibility of .NET applications with Arm architecture and AWS Graviton instances, offering high performance and cost-efficiency. + diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/background.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/background.md new file mode 100644 index 0000000000..b5c93ba49c --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/background.md @@ -0,0 +1,22 @@ +--- +title: Background +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +### What is the .NET Aspire +.NET Aspire is a comprehensive suite of powerful tools, templates, and packages designed to simplify the development of cloud-native applications using the .NET platform. Delivered through a collection of NuGet packages, .NET Aspire addresses specific cloud-native concerns, enabling developers to build observable and production-ready apps efficiently. + +Cloud-native applications are typically composed of small, interconnected services or microservices rather than a single monolithic codebase. These applications often consume a variety of services such as databases, messaging systems, and caching mechanisms. .NET Aspire provides a consistent and opinionated set of tools and patterns that help developers build and run distributed applications, taking full advantage of the scalability, resilience, and manageability of cloud infrastructures. + +.NET Aspire enhances the local development experience by simplifying the management of your app’s configuration and interconnections. It abstracts low-level implementation details, streamlining the setup of service discovery, environment variables, and container configurations. Specifically, with a few helper method calls, you can create local resources (like a Redis container), wait for them to become available, and configure appropriate connection strings in your projects. + +.NET Aspire offers integrations for popular services like Redis and PostgreSQL, ensuring standardized interfaces and seamless connections with your app. These integrations handle cloud-native concerns such as health checks and telemetry through consistent configuration patterns. By referencing named resources, configurations are injected automatically, simplifying the process of connecting services. + +.NET Aspire provides project templates that include boilerplate code and configurations common to cloud-native apps, such as telemetry, health checks, and service discovery. It offers tooling experiences for Visual Studio, Visual Studio Code, and the .NET CLI to help you create and interact with .NET Aspire projects. The templates come with opinionated defaults to help you get started quickly, reducing setup time and increasing productivity. + +By providing a consistent set of tools and patterns, .NET Aspire streamlines the development process of cloud-native applications. It manages complex applications during the development phase without dealing with low-level implementation details. .NET Aspire easily connects to commonly used services with standardized interfaces and configurations. There are also various templates and tooling to accelerate project setup and development cycles. Finally, with .NET Aspire, you can create applications that are ready for production with built-in support for telemetry, health checks, and service discovery. + +Here, we will explain how to create a .NET Aspire application, describe the project, and modify the code. Finally, we will deploy the application to AWS and then to GCP using virtual machines. \ No newline at end of file diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/01.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/01.png new file mode 100644 index 0000000000..250fcd1d86 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/01.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/02.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/02.png new file mode 100644 index 0000000000..784e3e469a Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/02.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/03.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/03.png new file mode 100644 index 0000000000..301aed0b10 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/03.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/04.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/04.png new file mode 100644 index 0000000000..4ee4b017ec Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/04.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/05.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/05.png new file mode 100644 index 0000000000..0d4ebd65b0 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/05.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/06.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/06.png new file mode 100644 index 0000000000..4e3f7b5850 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/06.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/07.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/07.png new file mode 100644 index 0000000000..a1f5b0fb72 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/07.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/08.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/08.png new file mode 100644 index 0000000000..b5fa8b6a2e Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/08.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/09.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/09.png new file mode 100644 index 0000000000..a7f89808ba Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/09.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/10.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/10.png new file mode 100644 index 0000000000..aeef1a5c0b Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/10.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/11.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/11.png new file mode 100644 index 0000000000..97996d5486 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/11.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/12.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/12.png new file mode 100644 index 0000000000..59aa71a361 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/12.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/13.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/13.png new file mode 100644 index 0000000000..d043a36aba Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/13.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/14.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/14.png new file mode 100644 index 0000000000..9a089acd85 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/14.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/15.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/15.png new file mode 100644 index 0000000000..bc99c30dcb Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/15.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/16.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/16.png new file mode 100644 index 0000000000..78834c217a Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/16.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/17.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/17.png new file mode 100644 index 0000000000..4886d5489a Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/17.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/18.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/18.png new file mode 100644 index 0000000000..961b085813 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/18.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/19.png b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/19.png new file mode 100644 index 0000000000..ffabd6a938 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/net-aspire/figures/19.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/gcp.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/gcp.md new file mode 100644 index 0000000000..2583f0b13f --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/gcp.md @@ -0,0 +1,122 @@ +--- +title: Deploy to GCP +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +### Objective +The goal of this task is to deploy a .NET Aspire application onto Google Cloud Platform (GCP). GCP is a suite of cloud computing services that provides scalable, secure, and highly available infrastructure for a wide range of applications. One of its core offerings is the Compute Engine service, which enables users to create and manage virtual machines (VMs) with customizable configurations, including CPU, memory, storage, and operating systems. Compute Engine supports various architectures, such as x86 and Arm-based processors like Google’s Axion or Ampere Altra Arm. + +We will start by creating an Arm64 virtual machine. Then, we will connect to it, install the required software, and run the application. + +### Create an Arm64 Virtual Machine +Follow these steps to create an Arm64 VM: +1. Create a Google Cloud Account. If you don’t already have an account, sign up for Google Cloud. +2. Open the Google Cloud Console [here](https://console.cloud.google.com) +3. Navigate to Compute Engine. In the Google Cloud Console, open the Navigation menu and go to Compute Engine > VM Instances. Enable any relevant APIs if prompted. +4. Click “Create Instance”. +5. Configure the VM Instance as follows: +* Name: arm-server +* Region/Zone: Choose a region and zone where Arm64 processors are available (e.g., us-central1). +* Machine Family: Select General-purpose. +* Series: T2A (Ampere Altra Arm). +* Machine Type: Select t2a-standard-1. +The configuration should resemble the following: + +![fig14](figures/14.png) + +6. Configure the Remaining Settings. +* Availability Policies: Standard. +* Boot Disk: Click Change, then select Ubuntu as the operating system. +* Identity and API Access: Keep the default settings. +* Firewall Settings: Check Allow HTTP traffic and Allow HTTPS traffic. + +![fig15](figures/15.png) + +7. Click the Create Button and wait for the VM to be created. + +### Connecting to VM +After creating the VM, connect to it as follows: +1. In Compute Engine, click the SSH dropdown next to your VM, and select “Open in browser window”: + +![fig16](figures/16.png) + +2. This will open a browser window. First, click the Authorize button: + +![fig17](figures/17.png) + +3. You will then see the terminal of your VM: + +![fig18](figures/18.png) + +### Installing dependencies and deploying an app +Once the connection is established, you can install the required dependencies (.NET SDK, Aspire workload, Git), fetch the application code, and deploy it: +1. Update the Package List: +```console +sudo apt update && sudo apt upgrade -y +``` + +2. Install .NET SDK 8.0 or later: +```console +wget https://dot.net/v1/dotnet-install.sh +bash dotnet-install.sh --channel 8.0 +``` + +3. Add .NET to PATH: +```console +export DOTNET_ROOT=$HOME/.dotnet +export PATH=$PATH:$HOME/.dotnet:$HOME/.dotnet/tools +``` + +4. Verify the installation: +```console +dotnet --version +``` + +5. Install the .NET Aspire workload: +```console +dotnet workload install aspire +``` + +6. Install git: +```console +sudo apt install -y git +``` + +7. Clone the repository: +```console +git clone https://github.com/dawidborycki/NetAspire.Arm.git +cd NetAspire.Arm/ +``` + +7. Trust trust the development certificate: +```console +dotnet dev-certs https --trust +``` + +8. Build and run the project +```console +dotnet restore +dotnet run --project NetAspire.Arm.AppHost +``` + +You will see output similar to this: +![fig19](figures/19.png) + +### Exposing the Application to the Public +To make your application accessible publicly, configure firewall rules: +1. In the Google Cloud Console, go to VPC Network > Firewall. +2. Click “Create Firewall Rule” and configure the following: +* Name: allow-dotnet-ports +* Target Tags: dotnet-app +* Source IP Ranges: 0.0.0.0/0 (for public access). +* Protocols and Ports: allow TCP on ports 7133, 7511, and 17222. +* Click the Create button. +3. Go back to your VM instance. +4. Click Edit, and under Networking find Network Tags, add the tag dotnet-app. +5. Click the Save button. + +### Summary +You have successfully deployed the Aspire app onto an Arm-powered GCP Virtual Machine. This deployment demonstrates the compatibility of .NET applications with Arm architecture and GCP, offering high performance and cost-efficiency. \ No newline at end of file diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/project.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/project.md new file mode 100644 index 0000000000..e49578decd --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/project.md @@ -0,0 +1,153 @@ +--- +title: Application +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +In this section, you will set up the project. This involves several steps, including installing the Aspire workload. Then, you will learn about the project structure and launch it locally. Finally, you will modify the project to add additional computations to mimic computationally intensive work. + +## Create a Project +To create a .NET Aspire application, first ensure that you have .NET 8.0 or later installed on your system. Next, install the Aspire workload by opening your terminal and running: + +```console +dotnet workload install aspire +``` + +Once the Aspire workload is installed, you can create a new application by executing: + +```console +dotnet new aspire-starter -o NetAspire.Arm +``` + +This command generates a solution with the following structure: +* NetAspire.Arm.AppHost - the orchestrator, or coordinator, project serves as the backbone of your distributed application. Its primary responsibilities include defining how services connect to one another, configuring ports and endpoints to ensure seamless communication, managing service discovery to enable efficient interactions between components, and handling container orchestration to streamline the deployment and operation of services within your application. + +* NetAspire.Arm.ApiService - the sample REST API service, built with ASP.NET Core, acts as a core component of your application by implementing business logic and managing data access. The default implementation comes preconfigured with essential features, including a WeatherForecast endpoint for demonstration purposes, built-in health checks to monitor the service’s status, and telemetry setup to track performance and usage metrics. + +* NetAspire.Arm.Web - the web frontend application, implemented with Blazor, serves as the user-facing layer of your application. It communicates with the API service to provide an interactive experience. This application includes a user interface for presenting data, client-side logic for handling interactions, and preconfigured patterns for consuming services. + +* NetAspire.Arm.ServiceDefaults - the shared library provides a centralized foundation for common service configurations across your application. It includes a default middleware setup, preconfigured telemetry settings for tracking performance, standard health check implementations, and logging configurations to ensure consistent and efficient monitoring and debugging. + +The structure of this project is designed to enhance efficiency and simplify the development of cloud-native applications. At its core, it incorporates features to ensure seamless service interactions, robust monitoring, and an exceptional development experience. + +One of the foundational elements is service discovery, which enables automatic service registration, dynamic endpoint resolution, and load balancing. These features ensure that services communicate effectively and handle traffic efficiently, even in complex, distributed environments. + +For monitoring and telemetry, the architecture integrates tools like built-in health checks, OpenTelemetry for monitoring, and metrics collection with distributed tracing. These features provide developers with deep insights into application performance, helping to maintain reliability and optimize system operations. + +Configuration management offers environment-based settings that make deploying applications across different stages straightforward. Secure secrets management safeguards sensitive information, while standardized service-to-service communication simplifies interactions between microservices. + +The architecture is also tailored to improve the development experience. Developers can benefit from local debugging support and a powerful monitoring dashboard. This dashboard provides a detailed view of service health, logs, metrics, trace information, resource usage, and service dependencies. Additionally, hot reload capability allows real-time updates during development, and container support ensures consistency across local and production environments. + +This thoughtfully crafted architecture embodies microservices best practices, promoting scalability, maintainability, and service isolation. It not only simplifies deployment and monitoring but also fosters developer productivity by streamlining workflows and providing intuitive tools for building modern, distributed applications. + +## Running the Project +To run the project, type the following +```console +dotnet run --project NetAspire.Arm.AppHost +``` + +The output will look like below: +```output +Building... +info: Aspire.Hosting.DistributedApplication[0] + Aspire version: 8.2.2+5fa9337a84a52e9bd185d04d156eccbdcf592f74 +info: Aspire.Hosting.DistributedApplication[0] + Distributed application starting. +info: Aspire.Hosting.DistributedApplication[0] + Application host directory is: /Users/db/Repos/NetAspire.Arm/NetAspire.Arm.AppHost +info: Aspire.Hosting.DistributedApplication[0] + Now listening on: https://localhost:17222 +info: Aspire.Hosting.DistributedApplication[0] + Login to the dashboard at https://localhost:17222/login?t=81f99566c9ec462e66f5eab5aa9307b0 +``` + +Click on the link provided: https://localhost:17222/login?t=81f99566c9ec462e66f5eab5aa9307b0. This will direct you to the application dashboard, as shown below: + +![fig1](figures/01.png) + +Once on the dashboard, locate and click the endpoint link for NetAspire.Arm.Web. This will take you to the Blazor-based web application. In the Blazor app, navigate to the Weather section to access and display data retrieved from the WeatherForecast API: + +![fig2](figures/02.png) + +Finally, return to the dashboard and select the Traces option. This section provides detailed telemetry tracing, allowing you to view the flow of requests, track service dependencies, and analyze performance metrics for your application: + +![fig3](figures/03.png) + +By following these steps, you’ll explore the key components of the .NET Aspire application, including its dashboard, data interaction through APIs, and telemetry tracing capabilities. + +## Modify the Project +You will now include the additional code that will mimic computation intense work. Go to NetAspire.Arm.ApiService project, and create a new file ComputationService.cs. Modify this file as follows: + +```cs +static class ComputationService +{ + public static void PerformIntensiveCalculations(int matrixSize) + { + var matrix1 = GenerateMatrix(matrixSize); + var matrix2 = GenerateMatrix(matrixSize); + + // Matrix multiplication + var matrixResult = Enumerable.Range(0, matrixSize) + .SelectMany(i => Enumerable.Range(0, matrixSize) + .Select(j => + { + double sum = 0; + for (int k = 0; k < matrixSize; k++) + { + sum += matrix1[i * matrixSize + k] * matrix2[k * matrixSize + j]; + } + return sum; + })) + .ToArray(); + } + + private static double[] GenerateMatrix(int matrixSize) { + return Enumerable.Range(1, matrixSize * matrixSize) + .Select(x => Random.Shared.NextDouble()) + .ToArray(); + } +} +``` + +This code defines a static class, ComputationService, designed to perform computationally intensive tasks, specifically matrix multiplication. It contains a public method, PerformIntensiveCalculations, which generates two matrices of a specified size, multiplies them, and stores the resulting matrix. + +The private method GenerateMatrix creates a one-dimensional array representing a matrix of the given size (matrixSize x matrixSize). Each element in the matrix is initialized with a random double value generated using Random.Shared.NextDouble(). + +The public method PerformIntensiveCalculations multiplies two matrices (matrix1 and matrix2) element by element using nested loops and LINQ. It iterates through each row of the first matrix and each column of the second matrix, calculating the dot product for each element in the resulting matrix. The result of the multiplication is stored in a flattened one-dimensional array, matrixResult. + +This code is provided for demonstrating heavy computational operations, such as large matrix manipulations, and can simulate workloads in scenarios that mimic intensive data processing or scientific calculations. + +Then, open the Program.cs of the NetAspire.Arm.ApiService, and use the above code: + +```cs +app.MapGet("/weatherforecast", () => +{ + ComputationService.PerformIntensiveCalculations(matrixSize: 1000); + + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; +}); +``` + +This will trigger matrix multiplications when you click Weather in the web frontend application. + +To test the code, re-run the application using the following command: + +```console +dotnet run --project NetAspire.Arm.AppHost +``` + +Next, navigate to the web frontend, click Weather, and then return to the dashboard. Click Traces to observe that the operation now takes significantly longer to complete—approximately 4 seconds in the example below: + +![fig4](figures/04.png) + +Now, when project is ready, and we can deploy it to the cloud. \ No newline at end of file