Create a Node on Azure & Sign Transactions with Azure Key Vault and Python
Azure has created a cloud storage solution for storing secrets. With tightly controlled access, you won’t have to worry about storing passwords, API Keys, or Private Keys on your local machine.
Requirements
- Azure Pay-As-You-Go subscription, or better
- Selection of Azure VM with at least the minimum node system requirements specified by the Algorand Foundation
- 2-4 vCPU
- 4-8GB RAM
- 100 - 200GB SSD
- 100 Mbps broadband
Background
To achieve high availability and fault tolerance, running your Algorand node on Microsoft Azure is one of your best options. Azure makes it easy to configure a virtual machine with specifications that won’t burn through your money. For this tutorial, we will deploy a virtual machine that meets the minimum system requirements of an Algorand node.
We will also be configuring Azure Key Vault to hold our Private Key used for signing Algorand transactions. All python code, and an Azure template, will be available at this GitHub Repository.
Steps
- Optional - Use an Azure Arm Template to deploy all resources needed for this tutorial
- 1. Create A Virtual Machine
- 2. Connect to Virtual Machine using SSH
- 3. Install Algorand node
- 4. Create an Azure Key Vault
- 5. Create Python Virtual Environment, and clone Tutorial GitHub Repository
- 6. Create Algorand accounts
- 7. Use Algorand Dispenser to fill account with ALGO
- 8. Create and Sign an Algorand Transaction
- Conclusion
Optional - Use an Azure Arm Template to deploy all resources needed for this tutorial
In steps one and four of this tutorial, we’ll create two resources, a Linux virtual machine and an azure KeyVault. Everything, including the permissions needed for the Virtual Machine to access Azure Keyvault, can be made using an Azure arm template. ARM stands for Azure Resource Manager, and it enables you to create, update, and delete resources in your Azure account.
If you would like to create all the resources required for this tutorial using the Azure Portal, skip this section and start at Step One, otherwise after clicking Deploy to Azure
prepare to do the following:
- For Resource Group, Click Create New and use this Name
AlgorandOnAzureTutorial-VM_group
- For
Key pair name
, use the following name
AlgorandOnAzureTutorial-VM_key
- Last, make sure that the Region is correct, if not select the proper region from the dropdown field
Figure 0-1 highlights the fields that need modifying, and what your Custom Deployment
page should look like
Figure 0-1: modify the highlighted fields
On the Review + create
page check to see the Template Passes Validation then click create
, as shown in Figure 0-2
Figure 0-2: Check if template is valid then click create
Finally, download your private key as shown in figure 0-3
Figure 0-3: Download private key
Tip
Right-click on Deploy to Azure
and open in New Tab
or New Window
; if you don’t, you will be redirected off this tutorial to the Custom Deployment
azure page.
Important
If you did not run into any problems with your Deployment, then you can skip Step one
and Step four
.
1. Create A Virtual Machine
Search for Virtual machines on the Azure Portal Home page, then Select Virtual machines under Services as shown in Figure 1-1.
Figure 1-1: Search for and Select Virtual machines
On the Virtual machines page, select Create followed by Azure virtual machine as shown in Figure 1-2.
Figure 1-2: Select Create then Azure virtual machine
Tip
It is easiest to work with many different resources when they all have a common naming convention.
For this tutorial, let’s name our Virtual Machine AlgorandOnAzureTutorial-VM, as shown in Figure 1-3.
AlgorandOnAzureTutorial-VM
Figure 1-3: Enter Virtual machine name
Tip
In this tutorial we will be using image: Ubuntu Server 20.04 LTS - Gen2
- To meet the requirements of 2-4 vCPU, 4-8GB RAM we will be using:
- VM Size: Standard_D2s_v3
+ 2 VCPUs
+ 8GB ram
Tip
Select a Region closest to your location.
To find a location that is closest to you Click Here
Currently, you should have the same configurations selected as in Figure 1-4, Except for the region, which depends on your location. Select a Region closest to your location. After making sure you configurations look like those of Figure 1-4, click Next : Disks >.
Figure 1-4: Verify your Configuration
Tip
Azure Virtual Machines come with very little storage, so we are going to have to add a disk
Click on Create and attach a new Disk as shown in Figure 1-5.
Figure 1-5: Select Create and attach a new Disk
Click on Change Size as shown in Figure 1-6.
Figure 1-6: Select Change Size
To meet the minimum storage requirements dictated by the Algorand Foundation, we will create a 256GB Standard SSD. Once your drive selection looks like Figure 1-7, click OK.
Figure 1-7: Create 256GB Standard SSD
Click OK once more on the Create a new disk page, shown in Figure 1-8.
Figure 1-8: Create a new disk page, click OK
Tip
This is just a basic tutorial, so Networking, Management, advanced, and tags will be left with their default settings.
From Disks, we will head straight to Review + create , as highlighted in Figure 1-9.
Figure 1-9: Click on Review + create, to review the Virtual Machines final configuration
On the Create a virtual machine page, Check the top of the page to see if you configuration is valid, then select Create. Figure 1-10 highlights a configuration that passes validation.
Figure 1-10: Validate configuration then press Create.
Once you click Create, you are given the option to Download the Key Pair for SSH click Download private key and create resource as shown in figure 1-11.
Figure 1-11: Download Private Key and Create Resources
Alert
When Azure generates a key pair, you may not get a .PEM file, but something else such as a .cer or .crt. The key generated by Azure will be usable for the creation of an SSH Connection regardless of the extension.
Once the SSH private key is downloaded, as shown in figure 1-12, the creation of the Resources required for your virtual machine should be nearly complete.
Figure 1-12: Download SSH Key
Create an Identity for your Virtual Machine
By default, our Virtual Machine Doesn’t come with an Identity, which means that it won’t be able to access other Azure Resources in the Resource Group. Before we connect to our Virtual Machine using SSH, let’s give our Virtual Machine an identity.
When your Virtual Machine deployment is complete, select the drop-down arrow to the left of the words Deployment details. Now you should see a list of resources; choose your virtual machine. Figure 1-13 highlights the drop-down arrow and your Virtual Machine in the Resource List.
Figure 1-13: Find you Virtual Machine in Drop Down list
Now in the search bar under the name of your Virtual Machine, type identity. Then click on Identity, as shown in figure 1-14.
Figure 1-14: Search for identity, then click Identity
We are going to turn On System Assigned Managed Identity. Set status to Onon the Identity page, then click Save. Figure 1-15 shows the Status switch, which must be turned on, and the save button must be clicked for the status to be changed.
Figure 1-15: Set status switch to On, then click Save
There will be one more prompt asking if you would like to Enable System Assigned Managed Identity, click Yes as shown in figure 1-16.
Figure 1-16 Click Yes Enabling system assigned Identity
2. Connect to Virtual Machine using SSH
In figure 1-11, we downloaded a private key that we will use to connect to our Virtual Machine using SSH.
Alert
Azure doesn’t always output a .PEM file when it Generates an SSH key pair. Do not be alarmed if you receive a .cer or a .crt file.
When we created the Virtual Machine, we created an Administrative user named azureuser.
Figure 2-1 is a snippet of figure 1-4 where we can find the name of our user.
Figure 2-1: Username location
Now we need to get the Public IP Address to our Virtual Machine. On the Azure Portal Home Page select Virtual Machines as shown in Figure 2-2.
Figure 2-2: Click on Virtual Machines on Azure Portal Home Page
On the Record for the AlgorandOnAzureTutorial-VM, take note of the Public IP address. Figure 2-3 shows where you can find the Public IP Address.
Figure 2-3: take note of the Public IP Address
The following commands assume that you haven’t moved your Private Key out of the Downloads folder.
This SSH Command should work for Mac and Linux. Make sure to change the file extension; if it is not .pem, replace XYZ with your Public IP Address.
ssh -i ~/Downloads/AlgorandOnAzureTutorial-VM_key.pem azureuser@XYZ
The following SSH command is for Windows 10 & 11 (Windows Powershell). Make sure to change the file extension; if it is not .pem, replace XYZ with your Public IP Address.
ssh -i $HOME"\Downloads\AlgorandOnAzureTutorial-VM_key.pem" azureuser@XYZ
SSH Private Key Permissions
SSH keys are a single user’s identity, so OpenSSH will not allow you to use a key it considers “too open.” OpenSSH (Client \ Server) is now integrated into operating systems such as Microsoft Windows, macOS, and most Linux distributions.
Figure 2-4 illustrates the error you will get if your Private key is Accessible to others. The area highlighted in green shows that the private key has Permissions 0644. Permissions 0644 means that the User has read and write permissions, the group associated with the file has read permissions, and All other users have Read Permission.
Figure 2-4: Private Key permissions are “too open”
The very least the User needs is Read Permissions, while the group associated with the file and everyone else should have no permissions.
Assuming that the Private Key downloaded in Step 1 is still in the Downloads directory, the following commands should help you change the Permission of your private key. Please Change File Extension if the Private Key you have is not .pem
.
For macOS and Linux:
chmod 600 ~/Downloads/AlgorandOnAzureTutorial-VM_key.pem
For Windows 10 (Powershell):
icacls.exe $HOME\Downloads\AlgorandOnAzureTutorial-VM_key.pem /reset
icacls.exe $HOME\Downloads\AlgorandOnAzureTutorial-VM_key.pem /grant:r "$($env:username):(r)"
icacls.exe $HOME\Downloads\AlgorandOnAzureTutorial-VM_key.pem /inheritance:r
3. Install Algorand node
Use the following command to update and upgrade the currently installed Ubuntu packages.
sudo apt update && sudo apt upgrade
Now we can create a Directory for our node and install the update script. If there is no node installed on your system, the update script pulls the latest Algorand update package from AWS s3 and installs it on your system.
mkdir ~/node
cd ~/node
curl https://raw.githubusercontent.com/algorand/go-algorand-doc/master/downloads/installers/update.sh -O
After downloading the update script it will only have read, and write permissions. We will have to change the permissions so we can read and execute the script. The following command gives our user read and execute permissions
sudo chmod 544 ~/node/update.sh
Now we are going to run the script.
./update.sh -i -c stable -p ~/node -d ~/node/data -n
Tip
-n = no automatic start after download
For this tutorial, I will install a Testnet node, but the default configuration is on the Mainnet, so modifications will have to be made to the data files. Configuration files for four different networks are available in the ~/node/genesisfiles
folder.
Let’s create a directory for our testnet data and then copy the Testnet configuration file to that directory
mkdir ~/node/testnet_data
cp ~/node/genesisfiles/testnet/genesis.json ~/node/testnet_data/genesis.json
We will need to append the ~/node
directory to the PATH
Environmental Variable and create an Environmental Variable with the location of our testnet data. The best way to modify, add, or manage Environmental Variable in linux is by adding them to ~/.bashrc.
The following commands append the modified PATH
and the created ALGORAND_DATA
Environmental Variable to the bottom of the ~/.bashrc
file. The last command reads and executes ~/.bashrc.
echo 'export PATH="$HOME/node:$PATH"' >> ~/.bashrc
echo 'export ALGORAND_DATA="$HOME/node/testnet_data"' >> ~/.bashrc
source ~/.bashrc
Now you can start your node with the following command.
goal node start
To see the status of your node, use the following command.
goal node status
When Sync Time, highlighted in figure 3-1, equals 0.0, your node is fully synced.
Figure 3-1: Check node status
Later in this tutorial, we will need the Node HTTP Address and the node Rest API Token. Now that your node is up and running, you can see these values with the following command.
printf "HTTP ADDRESS = http://$(cat ~/node/testnet_data/algod.net) \nREST API Token = $(cat ~/node/testnet_data/algod.token)\n"
Now we can add these values as environmental variables for later use. We will append these new Environmental variables to the bottom of ~/.bashrc.
echo "export ALGORAND_NODE_ADDRESS=\"http://$(cat ~/node/testnet_data/algod.net)\"" >> ~/.bashrc
echo "export ALGORAND_NODE_REST_TOKEN=\"$(cat ~/node/testnet_data/algod.token)\"" >> ~/.bashrc
source ~/.bashrc
Fast Catchup
Fast Catchup allows for rapid node updates by using snapshots. If you don’t use this feature, your node could take hours or days to synchronize.
The catchup point for the testnet network is available at the following address.
https://algorand-catchpoints.s3.us-east-2.amazonaws.com/channel/testnet/latest.catchpoint
The code for the catchup point should look like a string of numbers and letters, as shown in figure 3-2.
Figure 3-2: Testnet catchup point
Enter the following command to use Fast Catchup.
goal node catchup $(curl https://algorand-catchpoints.s3.us-east-2.amazonaws.com/channel/testnet/latest.catchpoint)
4. Create an Azure Key Vault
On the Azure Portal Home Page, Search for Key vaults, then click Key Vaults as Highlighted in Figure 4-1.
Figure 4-1: Search for Key vaults then click Key vaults under services
In the center of the Key vaults Page, Click Create key vault, as shown in Figure 4-2.
Figure 4-2: Click Create key vault on the center of the page
Now we are at the Create a key vault page. For the Resource group , select the same group your virtual machine is in. The Region should be the same as your Resource group, and the Key vault name used for this tutorial is:
algo-tutorial-secrets
Make sure that your configuration looks like Figure 4-3, except for the region if it is different.
Figure 4-3: Set Resource group, region, Key vault name, then click Next: Access policy >
On the Access Policy page, select Add Access Policy as highlighted in Figure 4-4.
Figure 4-4: click on Add Access Policy
In the Configure from template Drop-Down, select Secret Management as shown in Figure 4-5.
Figure 4-5: Select Secret Management from Configure from template Drop-Down
Now select None selected under Select Principal as highlighted in Figure 4-6.
Figure 4-6: select None selected under Select Principal
On the right side of the page, you will be asked to select a principal. Our principal will be our Virtual Machine. Select our virtual machine, then click Select as illustrated in Figure 4-7.
Figure 4-7: Select Virtual Machine then click Select
Now click add, as highlighted in Figure 4-8.
Figure 4-8: Click add to add Access Policy
On the Create a key vault page, you will see the Access Policy you just created under Applications. Click on Review + create, as illustrated in Figure 4-9.
Figure 4-9: Click on Review + create
Now confirm that your configuration is valid, click Create as shown in Figure 4-10.
Figure 4-10: Confirm configuration is valid then click Create
5. Create Python Virtual Environment, and clone Tutorial GitHub Repository
Let’s create a virtual environment for our python code in this step. This environment will hold all the packages we need to run the scripts we will be downloading from GitHub.
First, let’s download Virtualenv for Linux using the following command:
sudo apt install python3.8-venv
Then let’s create a directory for our python project and create a Virtual Environment inside it.
mkdir ~/algorand_on_azure_project
cd ~/algorand_on_azure_project
python3 -m venv algorand_on_azure_env
Now lets ACTIVATE our Virtual Environment.
source ~/algorand_on_azure_project/algorand_on_azure_env/bin/activate
Alert
If you have successfully activated your Virtual Environment, you will see the name of your Virtual Environment appended to the beginning of your command line.
Now that the Virtual Environment is Activated; let’s add all the python packages we will need for this tutorial
pip3 install py-algorand-sdk azure-identity azure-keyvault-secrets python-dotenv
Last we will clone this tutorials GitHub repository into your algorand_on_azure_project
Directory with the following command.
git clone https://github.com/pmartinez8241/Create-an-Algorand-Node-on-Microsoft-Azure-and-Sign-Transactions-with-Azure-Key-Vault.git
6. Create Algorand accounts
For this tutorial, we will be creating two accounts, one account that will send ALGO, and another account that will receive ALGO. Inside the git hub repository, you downloaded a file called create_algorand_account.py
, and run the following command to create both accounts.
python ~/algorand_on_azure_project/Create-an-Algorand-Node-on-Microsoft-Azure-and-Sign-Transactions-with-Azure-Key-Vault/create_algorand_account.py
So now, in the .env
file, that is in your ~/algorand_on_azure_project/Create-an-Algorand-Node-on-Microsoft-Azure-and-Sign-Transactions-with-Azure-Key-Vault/
directory, you will see 2 Environmental Variable ALGORAND_SENDER_ACCOUNT_ADDRESS
, and ALGORAND_RECEIVER_ACCOUNT_ADDRESS
.
azure_keyvault_helpers.py
from azure.identity import ManagedIdentityCredential
from azure.keyvault.secrets import SecretClient
credentials = ManagedIdentityCredential()
secret_client = SecretClient(r'https://algo-tutorial-secrets.vault.azure.net/',credentials)
def set_keyvault_secret(secret_name, secret_value):
result = secret_client.set_secret(secret_name,secret_value)
created_secret = "Secret created\nName = {}\nDate Create = {}".format(result.name,result.properties.created_on)
print(created_secret)
def get_keyvault_secret(secret_name):
result = secret_client.get_secret(secret_name)
return result.value
In step one, we enable System Managed Identity
, which is used to Authenticate our Secret client. When we created an Azure keyvault, we added an Access Policy that allows our Virtual Machine to access it. So ManagedIdentityCredential()
retrieves the Managed Identity Credentials of our Virtual Machine then, and then we input them into our Secret Client for Authentication. The Secret Client is a Python library used to manage Azure KeyVault. Setting secrets only requires a name for your secret and the value of your secret to create it. To get a secret, all that is needed is the name of your secret.
create_algorand_account.py
from algosdk import account, mnemonic
import azure_keyvault_helpers as azure_kv
import os
def create_algorand_account(env_variable_name):
# CREATE the PRIVATE KEY and ACCOUNT ADDRESS
account_private_key, account_address = account.generate_account()
# CREATE a MNEMONIC
account_mnemonic = mnemonic.from_private_key(account_private_key)
# ADD PRIVATE KEY to KEYVAULT
azure_kv.set_keyvault_secret(secret_name="{}-PK".format(account_address),secret_value=account_private_key)
# ADD MNEMONIC KEY to KEYVAULT
azure_kv.set_keyvault_secret(secret_name="{}-MNEMONIC".format(account_address),secret_value=account_mnemonic)
# ADD ALGORAND_ACCOUNT_ADDRESS Environmental Variable to .env
os.system(r'echo ALGORAND_{}_ACCOUNT_ADDRESS=\"{}\" >> ./.env'.format(env_variable_name,account_address))
create_algorand_account("SENDER")
create_algorand_account("RECEIVER")
The algosdk
has a function that generates an account for you, consisting of a Private Key
and an Address
. If you need to create a mnemonic
for your account, there is a mnemonic class that requires only the private key of your account in order to generate one. In the code above we save the private key
and the mnemonic
to Azure Keyvault, when we want to get the private key we will use the the account address with a -PK
appended to the end. You can get the mnemonic key by appending a `-MNEMONIC’ to the end of your account address.
The create_algorand_account.py
file creates two environment variables, ALGORAND_SENDER_ACCOUNT_ADDRESS
and ALGORAND_RECEIVER_ACCOUNT_ADDRESS,
both of which hold the Account Address of an Algorand Account. Both environmental variables are stored in the .env
file, which will be located in the same directory as the create_algorand_account.py
python script.
7. Use Algorand Dispenser to fill account with ALGO
We will fill the SENDER
account with 20 ALGO for this step. To fill the Account with ALGO, we will need the Account Address located in the directory of the GitHub repository we downloaded; run the following command from inside that directory.
grep "ALGORAND_SENDER" .env | cut -d "=" -f2 | sed 's/"//g'
The output from the command above is shown in figure 7-1.
Figure 7-1: Account Address for the send account
The Address that was output from Figure 7-1 needs to be copied and pasted into the Algorand dispenser. The Algorand dispenser outputs Algo that is usable only in the Test Network.
Once copy the Account Address, go to the following website.
https://dispenser.testnet.aws.algodev.network/
Once at the site above, verify that you are not a robot, paste your Account Address into the Text Field, and last click dispense. Once you click dispense, you should see Status: Code 200 success
as illustrated in figure 7-2.
Figure 7-2: Verify not a robot, paste account address, click dispense
Each time you put your address into the Algorand Dispenser, you will get 5 algo. Refresh your browser after each use. You will need to use the Algorand Dispenser four times to get the 20 Algo you will need for this tutorial.
8. Create and Sign an Algorand Transaction
We have all of the variables we will need to create a transaction and sign it. Run the following command to broadcast the signed transaction throughout the Test Network.
python ~/algorand_on_azure_project/Create-an-Algorand-Node-on-Microsoft-Azure-and-Sign-Transactions-with-Azure-Key-Vault/create_algorand_transaction.py
The command above outputs a Transaction ID,
as shown in Figure 8-1.
Figure 8-1: Transaction Id
Now let’s head to the Algorand Testnet explorer.
https://testnet.algoexplorer.io/
Finally, type your Transaction ID
in the Search Field to see the Transaction Overview, shown in Figure 8-2.
Figure 8-2: Transaction Overview
create_algorand_transaction.py
import os
from algosdk.future import transaction
from algosdk.future.transaction import PaymentTxn
from algosdk import constants
import azure_keyvault_helpers as kv_helpers
from algosdk.v2client import algod
from dotenv import load_dotenv
load_dotenv()
#NODE VARIABLES
#NODE HTTP ADDRESS
algorand_node_address = os.environ['ALGORAND_NODE_ADDRESS']
#NODE REST API TOKEN
algorand_node_rest_token = os.environ['ALGORAND_NODE_REST_TOKEN']
#ACCOUNT VARIABLES
algorand_sender_account_address = os.environ['ALGORAND_SENDER_ACCOUNT_ADDRESS']
algorand_account_private_key = kv_helpers.get_keyvault_secret(algorand_sender_account_address+"-PK")
#RECEIVER ACCOUNT ADDRESS
algorand_receiver_account = os.environ['ALGORAND_RECEIVER_ACCOUNT_ADDRESS']
algod_client = algod.AlgodClient(algorand_node_rest_token,algorand_node_address)
my_address = algorand_sender_account_address
params = algod_client.suggested_params()
params.flat_fee = True
params.fee = constants.MIN_TXN_FEE
note = "Algorand on Azure Tutorial Transaction".encode()
amount = 10000000
# PREPARE THE TRANSACTION FOR SIGNING
unsigned_txn = transaction.PaymentTxn(algorand_sender_account_address, params, algorand_receiver_account, amount, None, note)
# NOW WE CAN SIGN THE TRANSACTION WITH OUR PRIVATE KEY
signed_txn = unsigned_txn.sign(algorand_account_private_key)
# LAST WE WILL SEND OUR TRANSACTION AND PRINT THE TRANSACTION NUMBER
transaction_id = algod_client.send_transaction(signed_txn)
print(transaction_id)
- Portions of create_algorand_transaction.py came from Algorand Developer Partal
In the create_algorand_transaction.py script, we sent 10 ALGOS from the Sender Account to the Receiver Account. The amount is 10,000,000 because the amount sent is in MicroAlgos; 1,000,000 MicroAlgo equals 1 Algo. For the transaction fee, I used the constant MIN_TXN_FEE, which is equal to .001 Algo.
Once the prepared transaction is made, inserting the Private Key
of your Algorand key into the sign()
function makes it ready to be broadcast through the Algorand Testnet. To finalize the transaction, all that is needed is to send the transaction using the send_transaction()
function.
Conclusion
In this tutorial, we learned about some of the services azure provides and how to secure those services. We now know the basics of storing Secrets in Azure Key Vault and Deploying a Linux virtual machine. Storing API Keys, SSH Key, and Cryptocurrency Private keys in Azure Key Vault will significantly reduce the burden of keeping these values safe. We have also learned how to deploy an Algorand node and synchronize it using Fast Catchup. If you did this tutorial using Azure Web Portal, try at least once deploying your Azure web resources using the template in this GitHub Repository to see how much less complicated it makes deployments.