Getting started on Azure Ampere VMs with OpenSUSE using Terraform
May, 2023
In this tutorial we will show how you can automate the deployment of OpenSUSE on Ampere Altra-based Dps v5 and Eps v5 VMs on Microsoft Azure, using Terraform and Cloud-Init. Last year, Microsoft announced the general availablity of Ampere Altra based processors in Azure. Since OpenSUSE provides AArch64 builds of the operating system, OpenSUSE is one of the operating systems you can use on Azure Dps and Eps v5 VMs, which are based on our Ampere(R) Altra(TM) cloud-native processors.
If you have seen my previous session from Microsoft Build on Cloud Workload Automation, I built a Terraform module to quickly get you started using Ampere platforms on Azure. Today we are going to use that module to launch an Ampere(R) Altra(TM) based virtual machine on Azure, booting into OpenSUSE while passing in some metadata to configure it, dynamically. To begin, you will need a couple of things listed below.
The azure-ampere-vm terraform module code supplies the minimal amount of information to quickly have working Ampere A1 instances on Azure. It has been updated to include the ability to easily select OpenSUSE by passing the appropriate parameter during usage. Additional tasks performed by the azure-ampere-vm terraform module.
For the purpose of this we will quickly configure Terraform using a terraform.tfvars in your project directory. The following is an example of what terraform.tfvars should look like:
subscription_id = "12345678-abcd-1234-abcd-1234567890ab" tenant_id = "87654321-dcba-4321-dcba-ba0987654321"
For more information regarding how to get your Azure credentials working with terraform please refer to the following reading material:
To use the terraform module you must open your favorite text editor and create a file called main.tf. Copy the following code which allows you to supply a custom cloud-init template at launch:
variable "subscription_id" {} variable "tenant_id" {} locals { cloud_init_template_path = "${path.cwd}/cloud-init.yaml.tpl" } module "azure-ampere-vm" { source = "github.com/amperecomputing/terraform-azure-ampere-vm" subscription_id = var.subscription_id tenant_id = var.tenant_id # Optional # resource_group = var.resource_group # rg_prefix = var.rg_prefix # virtual_network_name = var.virtual_network_name # address_space = var.address_space # subnet_prefix = var.subnet_prefix # vm_size = var.vm_size location = "westus2" azure_vm_count = 1 azure_os_image = "opensuse11" instance_prefix = "azure-ampere-vm-opensuse-11" cloud_init_template_file = local.cloud_init_template_path } output "azure_ampere_vm_private_ips" { value = module.azure-ampere-vm.azure_ampere_vm_private_ipaddresses } output "azure_ampere_vm_public_ips" { value = module.azure-ampere-vm.azure_ampere_vm_public_ipaddresses }
The cloud-init template will get your OpenSUSE instance to install and configure itself the first time it boots. To begin open your favorite text editor and create a file named cloud-init.yaml.tpl in the same directory as the main.tf you previously created. The following example content will add an external ‘apt’ repository which will allow us to install the upstream Docker packages as well as some others, it will create a “docker” group and then add default user it, then we will run a simple container registry on the OpenSUSE host.
#cloud-config
package_update: true
package_upgrade: true
packages:
- screen
- rsync
- git
- curl
- docker
- python3-pip
- python3-dev
- python3-selinux
- python3-setuptools
- python3-venv
- libffi-dev
- gcc
- libssl-dev
groups:
- docker
system_info:
default_user:
groups: [docker]
runcmd:
- systemctl enable docker
- systemctl start docker
- docker run -d --name registry --restart=always -p 4000:5000 -v registry:/var/lib/registry registry:2
- echo 'Azure Ampere VM OpenSUSE Leap Example' >> /etc/motd
Executing a terraform workflow is essentially broken into three steps. First, you must initialize the terraform project with the modules and necessary plugins to support proper execution. The following command will do that:
terraform init
Below is output from a ‘terraform init’ execution within the project directory.
Once ‘terraform init’ is executed it is necessary to ‘plan’ next. The plan phase performs a dry-run of your Terraform scripts to verify the tasks, steps, objects and operations that will be created and executed when interacting with the cloud APIs. This planning step helps ensure that app steps of your script can execute, so that when we apply our scripts, we will not leave a system in a partially configured state. It also allows you to save the output for usage at a later time which can then be passed into the final phase. Executing the following from a command line from within the project directory will execute the “plan” operation:
terraform plan
The output from a ‘terraform plan’ execution in the project directory will look similar to the following:
Finally, you will execute the ‘apply’ phase of the terraform execution sequence. This will interact directly with the cloud APIs creating all the objects, executing all the tasks locally on the local host and remotely against the cloud APIs and created virtual instances. Defined output will show important information on the screen. Executing the following command from the project directory will automatically execute without requiring any additional interaction:
terraform apply -auto-approve
The following is an example of output from a ‘apply’ run of terraform from within the project directory:
Once everything is finished deploying, you’ll need to login using the dynamically generated sshkey that will be located in your project directory. This terraform code created that key during the ‘apply’ phase to use specifically for logging into any of the created instances. To log in take the ip address from the output displayed during the terraform run and run the following ssh command:
ssh -i ./azure-id_rsa opensuse@20.69.123.141
You should be automatically logged in after running the command. The following is output from sshing into an instance.
You now should have a fully running and configured OpenSUSE instance. When you are finished you can remove any trace of the created cloud objects by executing the ‘destroy’ command. This will completely remove all created objects in a ‘leave no trace’ manner. Execute the following from a command from the project directory when you are finished:
terraform destroy -auto-approve
The following is sample output of ‘terraform destroy’ when used on this project.
For those unfamiliar with OpenSUSE, it is a popular linux distribution, which launched in 2005, as a free, community-built distribution based on SUSE Linux. SUSE Linux is one of the oldest Linux distributions, with an initial release, based on Slackware, in 1992. The distribution has developed over time to use a standard package management system (RPM), and it builds and integrates most popular open source software and tooling.
OpenSUSE Leap rebuilds the packages of SUSE Linux Enterprise (SLE) from their source code, which gives Leap a level of stability similar to a commercially-supported Enterprise operating system, and combines that with community developments to give users, developers and sysadmins a stable Linux experience. The OpenSUSE Leap release approach is one major release each year, with a minor release every six months, and ongoing security updates and bugfixes in between releases.
OpenSUSE supports the industry-standard metadata interfaces for Linux instance configuration in the cloud, Cloud-Init. You can use Cloud-Init to automate the creation and configuration of OpenSUSE instances, making OpenSUSE an easy-to-use option as a base operating system for cloud-native applications.
By now you can see how simply modifying the cloud-init file and then performing the same workflow will allow you to get iterating quickly with your own deployment. Now with what you have learned to this point you should definitely know how to quickly get automating using OpenSUSE on Ampere platforms in Azure!