diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md new file mode 100644 index 0000000000..8f1eda67f6 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md @@ -0,0 +1,63 @@ +--- +title: Deploy Ruby on Rails on Google Cloud C4A (Arm-based Axion VMs) + +draft: true +cascade: + draft: true + +minutes_to_complete: 40 + +who_is_this_for: This learning path is intended for software developers deploying and optimizing Ruby on Rails workloads on Linux/Arm64 environments, specifically using Google Cloud C4A virtual machines powered by Axion processors. + +learning_objectives: + - Provision an Arm-based SUSE SLES virtual machine on Google Cloud (C4A with Axion processors) + - Install Ruby/Rails on a SUSE Arm64 (C4A) instance + - Validate Ruby on Rails functionality using PostgreSQL as the database + - Benchmark Rails performance using the built-in Ruby Benchmark library on Arm64 (Aarch64) architecture + + +prerequisites: + - A [Google Cloud Platform (GCP)](https://cloud.google.com/free) account with billing enabled + - Basic familiarity with Ruby programming, the Rails framework, and [relational databases](https://www.postgresql.org/) + +author: Pareena Verma + +##### Tags +skilllevels: Introductory +subjects: Web +cloud_service_providers: Google Cloud + +armips: + - Neoverse + +tools_software_languages: + - Ruby + - Rails + - PostgreSQL + +operatingsystems: + - Linux + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +further_reading: + - resource: + title: Google Cloud documentation + link: https://cloud.google.com/docs + type: documentation + + - resource: + title: Ruby on Rails documentation + link: https://guides.rubyonrails.org/ + type: documentation + + - resource: + title: Ruby built-in Benchmark documentation + link: https://github.com/ruby/benchmark?tab=readme-ov-file#benchmark + type: documentation + +weight: 1 +layout: "learningpathall" +learning_path_main_page: "yes" +--- diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/background.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/background.md new file mode 100644 index 0000000000..d624bbc87b --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/background.md @@ -0,0 +1,23 @@ +--- +title: Getting started with Ruby/Rails on Google Axion C4A (Arm Neoverse-V2) + +weight: 2 + +layout: "learningpathall" +--- + +## Google Axion C4A Arm instances in Google Cloud + +Google Axion C4A is a family of Arm-based virtual machines built on Google’s custom Axion CPU, which is based on Arm Neoverse-V2 cores. Designed for high-performance and energy-efficient computing, these virtual machines offer strong performance for modern cloud workloads such as CI/CD pipelines, microservices, media processing, and general-purpose applications. + +The C4A series provides a cost-effective alternative to x86 virtual machines while leveraging the scalability and performance benefits of the Arm architecture in Google Cloud. + +To learn more about Google Axion, refer to the [Introducing Google Axion Processors, our new Arm-based CPUs](https://cloud.google.com/blog/products/compute/introducing-googles-new-arm-based-cpu) blog. + +## Ruby on Rails + +Ruby on Rails (Rails) is an open-source, server-side web application framework written in Ruby. + +It allows developers to build database-backed web applications quickly using convention over configuration, MVC (Model-View-Controller) architecture, and built-in tools for routing, database migrations, and view rendering. + +Rails is widely used for web applications, APIs, and full-stack development projects. Learn more from the [Ruby on Rails official website](https://rubyonrails.org/) and its [guides and documentation](https://guides.rubyonrails.org/). diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/baseline.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/baseline.md new file mode 100644 index 0000000000..74686121e2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/baseline.md @@ -0,0 +1,213 @@ +--- +title: Ruby on Rails Baseline Testing on Google Axion C4A Arm Virtual Machine +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Baseline Setup for Ruby on Rails with PostgreSQL +This section covers the installation and configuration of **PostgreSQL** and a **Rails application** on a SUSE Arm-based GCP VM. It includes setting up PostgreSQL, creating a Rails app, configuring the database, and starting the Rails server. + +### Install and Configure PostgreSQL +PostgreSQL is used with Ruby on Rails as a robust, production-ready relational database that reliably stores and manages application data. + +```console +sudo zypper install postgresql-devel postgresql-server +sudo systemctl start postgresql +sudo systemctl enable postgresql +``` +- `postgresql-devel` is required to compile the pg gem for Rails. + +Verify that the PostgreSQL service is active and running: + +```console +systemctl status postgresql +``` + +This command creates a new PostgreSQL role (user) named `gcpuser` with **superuser privileges**. + +```console +sudo -u postgres createuser --superuser gcpuser +``` +- `sudo -u postgres` → Runs the command as the `postgres` user (default PostgreSQL superuser). +- `createuser --superuser gcpuser` → Creates a PostgreSQL role named `gcpuser` with full admin privileges. + - Can create databases + - Can create other roles/users + - Can grant privileges + +This role will be used by Rails to connect to the PostgreSQL database. + +### Create a Rails App with PostgreSQL +Creates a new Rails application configured to use PostgreSQL as its database. + +```console +rails new db_test_rubyapp -d postgresql +cd db_test_rubyapp +bundle install +``` +- Creates a new Rails application called `db_test_app`. +- `d postgresql` → Tells Rails to use PostgreSQL as the database instead of the default SQLite. +- `bundle install` ensures all required gems are installed. + +{{% notice Note %}} +Check `config/database.yml` to ensure the `username` and `password` match your PostgreSQL role `(gcpuser)`. +{{% /notice %}} + +### Verify and Update Database Configuration +Open the Rails database configuration file: + +```console +nano config/database.yml +``` +Find the `default`: and `development`: sections. +Ensure the username matches the PostgreSQL user you created (gcpuser): + +You should see output similar to: +```output +default: &default + adapter: postgresql + encoding: unicode + username: gcpuser + password: + host: localhost + pool: 5 + +development: + <<: *default +``` +### Create and Initialize the Database +Initializes and creates the development and test databases for your Rails app using PostgreSQL. + +```console +rails db:create +``` +You should see output similar to: +```output +Created database 'db_test_rubyapp_development' +Created database 'db_test_rubyapp_test' +``` +This means Rails successfully connected to PostgreSQL and created both dev and test databases. + +### Generate a Scaffold for Testing +A database and Scaffold are required to create the actual PostgreSQL database for your Rails app and quickly generate the model, controller, views, and migrations for your data. +Let’s create a small test model and table — for example, a simple Task tracker: + +```console +rails generate scaffold task title:string due_date:date +``` +This command automatically generates: +- Database migration for the tasks table +- A model (task.rb) +- A controller and views for CRUD operations +- **Scaffold** → Automatically generates boilerplate code for CRUD operations, saving time and ensuring your app has working forms and routes. + +Then apply the migration: + +```console +rails db:migrate +``` + +You should see output similar to: +```output +== 20251006101717 CreateTasks: migrating ====================================== +-- create_table(:tasks) + -> 0.0127s +== 20251006101717 CreateTasks: migrated (0.0128s) ============================= +``` + +Database schema successfully updated. + +### Verify Table and Database Connectivity +The previous command `rails generate scaffold task title:string due_date:date` created a `tasks` table in your PostgreSQL database. + +Now, verify that the table exists and has the correct structure following the steps below: + +```console +sudo -u postgres psql +\c db_test_rubyapp_development +\d tasks +``` +- `sudo -u postgres psql` → Launches the PostgreSQL shell as the superuser `postgres`. +- `\c db_test_rubyapp_development` → Connects to the Rails app’s development database. +- `\d tasks` → Displays the schema (columns and types) of the `tasks` table. + +You should see output similar to: +```output +psql (15.10) +Type "help" for help. + +postgres=# \c db_test_rubyapp_development +You are now connected to database "db_test_rubyapp_development" as user "postgres". +db_test_rubyapp_development=# \d tasks + Table "public.tasks" + Column | Type | Collation | Nullable | Default +------------+--------------------------------+-----------+----------+----------------------------------- + id | bigint | | not null | nextval('tasks_id_seq'::regclass) + title | character varying | | | + due_date | date | | | + created_at | timestamp(6) without time zone | | not null | + updated_at | timestamp(6) without time zone | | not null | +Indexes: + "tasks_pkey" PRIMARY KEY, btree (id) +``` + +### Run Rails Server +Before proceeding to run the Rails server, you need to allow port 3000 from your GCP console. Below are the steps to do that: + +a. On the GCP console, navigate to **Firewall** -> **Create Firewall Rule** + + ![Firewall Info alt-text#center](images/firewall1.png "Figure 1: Firewall Create") + +b. Fill in the details as below: + +Give a **name** for your desired port (e.g., `allow-3000-ingress`). + +![Allow Ingress alt-text#center](images/firewall2.png "Figure 2: Allow-3000-ingress ") + + +Set **Direction of Traffic** to **"Ingress"**. + +Set **Target** to **"All Instances in the Network"**. You can also choose **"Specific Tags"**. + +Set the **Source IPv4 range** to **"0.0.0.0/0"**, for global access. + +![Set Direction of Traffic alt-text#center](images/firewall3.png "Figure 3: Target Set") + +In the **"Protocols and Ports"**, click on **"TCP"**, and mention the port number **"3000"**. + +![Set Protocols and Ports alt-text#center](images/firewall4.png "Figure 4: Protocols and Ports") + + +Click on **"Create"**. The Firewall rule will be created successfully and can be viewed in the Firewall Policies Page: + +![ Create Firewall rule alt-text#center](images/firewall5.png "Figure 5: Create Firewall rule") + +Once done, go back to the VM, and execute the below commands to allow port 3000: + +```console +sudo firewall-cmd --permanent --add-port=3000/tcp +sudo firewall-cmd --reload +``` +Now that port 3000 is allowed in your VM’s ingress firewall rules, you can start the Rails server using the following command: + +```console +rails server -b 0.0.0.0 +``` +- `rails server -b 0.0.0.0` → Starts the Rails server and binds it to all network interfaces, not just `localhost`. +- Binding to `0.0.0.0` allows other machines (or your local browser) to access the Rails app running on the VM using its external IP. + + +### Access the Application: +Open a web browser on your local machine (Chrome, Firefox, Edge, etc.) and enter the following URL in the address bar: + +```console +http://[YOUR_VM_EXTERNAL_IP]:3000 +``` +- Replace `` with the public IP of your GCP VM. + +You will see a Rails welcome page in your browser if everything is set up correctly. It looks like this: + +![Rails-info page alt-text#center](images/rails-web.png "Figure 6: Ruby/Rails Welcome Page") + +This verifies the basic functionality of the Ruby/Rails installation before proceeding to the benchmarking. diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/benchmarking.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/benchmarking.md new file mode 100644 index 0000000000..bb96e05e79 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/benchmarking.md @@ -0,0 +1,121 @@ +--- +title: Ruby on Rails Benchmarking +weight: 6 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + + +## Ruby on Rails Benchmarking with built-in Benchmark +This section benchmarks Ruby on Rails using Ruby’s built-in `Benchmark` library to measure execution time for database inserts, queries, and CPU computations on GCP SUSE VMs, providing insights into performance metrics and bottlenecks. + +### Go into your Rails app folder +You need to navigate into the folder of your Rails application. This is where Rails expects your application code, models, and database configurations to be located. All commands related to your app should be run from this folder. + +```console +cd ~/db_test_rubyapp +```` + +### Create the benchmark file inside the app +We create a new Ruby file named `benchmark.rb` where we will write code to measure performance. + +```console +nano benchmark.rb +``` + +### Benchmark code for measuring Rails app performance +Below mentioned code (`benchmark.rb` file) measures database inserts, queries, and CPU computations in your Rails application using Ruby’s Benchmark library. + +```ruby +require 'benchmark' + +n = 1000 + +Benchmark.bm do |x| + x.report("DB Insert:") do + n.times do + Task.create(title: "Benchmark Task", due_date: Date.today) + end + end + + x.report("DB Query:") do + n.times do + Task.where(title: "Benchmark Task").to_a + end + end + + x.report("Computation:") do + n.times do + (1..10_000).reduce(:+) + end + end +end +``` +- `require 'benchmark'` → Loads Ruby’s built-in benchmarking library. +- `n = 1000` → Sets the number of iterations for each task. You can increase or decrease this number to simulate heavier or lighter workloads. +- `Benchmark.bm` → Starts a block to measure performance of different tasks. +- **DB Insert** → Creates 1,000 new `Task` records in the database. Measures how long it takes to insert data. +- **DB Query** → Retrieves the 1,000 `Task` records from the database. Measures how long it takes to query data. +- **Computation** → Performs a simple calculation 1,000 times. Measures pure CPU performance (without database interactions). + +This code gives you a basic understanding of how your Rails app performs under different types of workloads. + +### Run the benchmark inside Rails +Now that your benchmark file is ready, run it **within the Rails environment** using the following command: + +```console +rails runner benchmark.rb +``` +- `rails runner` runs any Ruby script in the context of your Rails application. + +- It automatically loads your **Rails environment**, including: + - All models (like `Task`) + - Database connections + - Configuration and dependencies + +- This ensures that your benchmark can interact with the **PostgreSQL database** through ActiveRecord, rather than running as a plain Ruby script. + +You should see an output similar to: + +```output + user system total real +DB Insert: 2.271645 0.050236 2.321881 ( 2.721631) +DB Query: 3.379849 0.009345 3.389194 ( 3.389613) +Computation: 0.410907 0.000000 0.410907 ( 0.410919) +``` + +### Benchmark Metrics Explained + +- **user** → Time spent executing your Ruby code (**CPU time in user mode**). +- **system** → Time spent in **system calls** (I/O, database, kernel interactions). +- **total** → `user + system` (sum of CPU processing time). +- **real** → The **wall-clock time** (actual elapsed time, includes waiting for DB, I/O, etc). + +### Benchmark summary on x86_64 +To compare the benchmark results, the following results were collected by running the same benchmark on a `x86 - c4-standard-4` (4 vCPUs, 15 GB Memory) x86_64 VM in GCP, running SUSE: + +| Task | user (sec) | system (sec) | total (sec) | real (sec) | +|--------------|------------|--------------|-------------|------------| +| DB Insert | 1.902564 | 0.061805 | 1.964369 | 2.606764 | +| DB Query | 2.725923 | 0.009513 | 2.735436 | 2.735956 | +| Computation | 0.331519 | 0.000083 | 0.331602 | 0.331610 | + +### Benchmark summary on Arm64 +Results from the earlier run on the `c4a-standard-4` (4 vCPU, 16 GB memory) Arm64 VM in GCP (SUSE): + + +| Task | user (sec) | system (sec) | total (sec) | real (sec) | +|--------------|----------|----------|----------|----------| +| DB Insert | 2.271645 | 0.050236 | 2.321881 | 2.721631 | +| DB Query | 3.379849 | 0.009345 | 3.389194 | 3.389613 | +| Computation | 0.410907 | 0.000000 | 0.410907 | 0.410919 | + + +### Ruby/Rails performance benchmarking comparison on Arm64 and x86_64 + +When you compare the benchmarking results, you will notice that on the Google Axion C4A Arm-based instances: + +- **Database operations are the main bottleneck:** DB Insert and DB Query take the most time. +- **DB Query has the highest latency:** It is the slowest operation at 3.39 seconds. +- **Core computation is fast:** Pure Ruby/Rails calculations complete quickly at 0.41 seconds. diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall1.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall1.png new file mode 100644 index 0000000000..63efb19dc3 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall1.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall2.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall2.png new file mode 100644 index 0000000000..5419beb2d3 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall2.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall3.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall3.png new file mode 100644 index 0000000000..3f9b15187d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall3.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall4.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall4.png new file mode 100644 index 0000000000..20212ec627 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall4.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall5.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall5.png new file mode 100644 index 0000000000..1395e748de Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/firewall5.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/gcp-vm.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/gcp-vm.png new file mode 100644 index 0000000000..0d1072e20d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/gcp-vm.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/rails-web.png b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/rails-web.png new file mode 100644 index 0000000000..a41f6f85be Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/images/rails-web.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/installation.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/installation.md new file mode 100644 index 0000000000..a7bedb2e6f --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/installation.md @@ -0,0 +1,92 @@ +--- +title: Install Ruby on Rails +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Install Ruby on Rails +In this section, you will learn how to install Ruby, Rails, and related tools (like rbenv and Bundler) on a SUSE Arm-based virtual machine. This guide will also cover installing the necessary dependencies to compile Ruby and run Rails applications smoothly. + + +### Update System Packages +Updates all system packages to the latest versions to ensure stability and security. + +```console +sudo zypper update +``` + +### Install Required Dependencies +These packages are essential for compiling Ruby and its native extensions. + +```console +sudo zypper install git curl gcc make patch libyaml-devel libffi-devel libopenssl-devel readline-devel zlib-devel gdbm-devel bzip2 bzip2-devel +``` + +### Install rbenv +**rbenv** is a lightweight Ruby version manager that allows multiple Ruby versions on the same system. + +```console +git clone https://github.com/rbenv/rbenv.git ~/.rbenv +echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc +echo 'eval "$(rbenv init -)"' >> ~/.bashrc +source ~/.bashrc +``` +- Clones the rbenv repository to manage Ruby versions +- Updates `PATH` so your shell can find rbenv +- Initializes rbenv in your shell session + +### Install ruby-build Plugin +**ruby-build** is an rbenv plugin that provides the `rbenv install` command to compile and install different Ruby versions from source. + +```console +git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build +``` + +### Install Ruby +Installs Ruby and sets it as the default version for your environment. + +```console +rbenv install 3.4.6 +rbenv global 3.4.6 +ruby -v +``` +- Installs Ruby 3.4.6 from source +- Sets it as the default Ruby version for your user +- `ruby -v` verifies the installed Ruby version + +You should see output similar to: +```output +ruby 3.4.6 (2025-09-16 revision dbd83256b1) +PRISM [aarch64-linux] +``` +{{% notice Note %}} +Ruby 3.4.0 introduced significant performance enhancements, notably improvements to YJIT (Yet Another Ruby JIT), a Ruby just-in-time compiler. These enhancements are particularly beneficial for Arm architectures, as YJIT has been optimized to deliver better performance on such platforms. To leverage these improvements, it is recommended that you upgrade to Ruby 3.4.0 or later. +You can view [this release note](https://www.ruby-lang.org/en/news/2024/12/25/ruby-3-4-0-released/) + +The [Arm Ecosystem Dashboard](https://developer.arm.com/ecosystem-dashboard/) recommends Ruby version 3.4.0, the minimum recommended on the Arm platforms. +{{% /notice %}} + +### Install Bundler +**Bundler** manages Ruby project dependencies and ensures consistent gem versions across environments. + +```console +gem install bundler +``` + +### Install Rails +Rails is a full-stack web application framework for Ruby that simplifies building database-backed web applications with convention over configuration. + +```console +gem install rails +rails -v +``` +- Installs the Rails framework +- `rails -v` verifies the installed Rails version + +You should see output similar to: +```output +Rails 8.0.3 +``` + +Ruby/Rails installation is complete. You can now proceed with the baseline testing. diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/instance.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/instance.md new file mode 100644 index 0000000000..2b93bc950d --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/instance.md @@ -0,0 +1,31 @@ +--- +title: Create a Google Axion C4A Arm virtual machine on GCP +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Overview + +In this section, you will learn how to provision a Google Axion C4A Arm virtual machine on Google Cloud Platform (GCP) using the `c4a-standard-4` (4 vCPUs, 16 GB memory) machine type in the Google Cloud Console. + +{{% notice Note %}} +For support on GCP setup, see the Learning Path [Getting started with Google Cloud Platform](https://learn.arm.com/learning-paths/servers-and-cloud-computing/csp/google/). +{{% /notice %}} + +## Provision a Google Axion C4A Arm VM in Google Cloud Console + +To create a virtual machine based on the C4A instance type: +- Navigate to the [Google Cloud Console](https://console.cloud.google.com/). +- Go to **Compute Engine > VM Instances** and select **Create Instance**. +- Under **Machine configuration**: + - Populate fields such as **Instance name**, **Region**, and **Zone**. + - Set **Series** to `C4A`. + - Select `c4a-standard-4` for machine type. + + ![Create a Google Axion C4A Arm virtual machine in the Google Cloud Console with c4a-standard-4 selected alt-text#center](images/gcp-vm.png "Creating a Google Axion C4A Arm virtual machine in Google Cloud Console") + +- Under **OS and Storage**, select **Change**, then choose an Arm64-based OS image. For this Learning Path, use **SUSE Linux Enterprise Server**. Pick the preferred version for your Operating System. Ensure you select the **Arm image** variant. Click **Select**. +- Under **Networking**, enable **Allow HTTP traffic**. +- Click **Create** to launch the instance.