{"id":2281,"date":"2017-10-17T11:00:03","date_gmt":"2017-10-17T08:00:03","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/getting-started-libcloud-compute-nodes\/"},"modified":"2026-02-17T09:33:29","modified_gmt":"2026-02-17T09:33:29","slug":"getting-started-libcloud-compute-nodes","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/getting-started-libcloud-compute-nodes\/","title":{"rendered":"How to get started with Libcloud compute nodes"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/libcloud.apache.org\/\" target=\"_blank\" rel=\"noopener\">Apache Libcloud<\/a> is a Python programming&nbsp;language&nbsp;library&nbsp;that unifies supported cloud provider APIs under a single interface. The Libcloud&nbsp;compute driver for UpCloud allows you to deploy and manage cloud servers using simple functions. Follow the instructions below to install the Libcloud library and check the usage examples to get started.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Test hosting on UpCloud!<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Enable API permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before you begin, allowing Libcloud to connect to your UpCloud account requires you to enable the API permissions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We recommend creating a new workspace member account just for the API communication. Log in to your UpCloud account and go to the&nbsp;<em>People<\/em> tab. You can check out the instructions on how to do this in our <a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/getting-started-upcloud-api\/\" target=\"_blank\" rel=\"noreferrer noopener\">getting started guide for the API<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that you should restrict the API account&nbsp;from your other UpCloud services. <tt id=\"quickstart\"><\/tt>Take care&nbsp;handling your credentials when programming automation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To begin developing with Libcloud, you will need to have a Python programming environment configured on your computer. You can find instructions to install Python for your operating system in their\u00a0<a href=\"https:\/\/wiki.python.org\/python\/BeginnersGuide(2f)Download.html\" target=\"_blank\" rel=\"noreferrer noopener\">beginner\u2019s guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing Libcloud<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Libcloud is available for most Linux distributions with the package managers or directly from the <a href=\"https:\/\/libcloud.apache.org\/downloads.html\" target=\"_blank\" rel=\"noopener\">Libcloud downloads page<\/a> on other operating systems as well.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, the easiest and most universal way to install Libcloud is using the&nbsp;Python Package Index. It is the official third-party software repository for the Python programming language and contains almost everything you could ever need.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In most cases, the command line client <tt>pip<\/tt>\u00a0should have been installed together with the Python environment. If it was not, follow <a href=\"https:\/\/pip.pypa.io\/en\/stable\/installation\/\" target=\"_blank\" rel=\"noreferrer noopener\">the install instructions in their\u00a0documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With <tt>pip<\/tt>&nbsp;installed, getting the Libcloud libraries is a simple task. Use the following command to install the <tt>apache-libcloud<\/tt>&nbsp;package.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install apache-libcloud<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you already had a version of Libcloud installed, you can upgrade it with the next command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install --upgrade apache-libcloud<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To get the most up-to-date packages, you will need to use the development version. The Libcloud driver for UpCloud will initially be only available on the development&nbsp;channel until it gets included in the stable release.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Install the Libcloud development version with the command underneath.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install -e git+https:\/\/git-wip-us.apache.org\/repos\/asf\/libcloud.git@trunk#egg=apache-libcloud<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With the libraries installed, you are then ready to start programming. Continue below with examples of how to create and manage nodes on UpCloud using the Libcloud API.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Instantiating a new driver<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To issue commands to the UpCloud services, you first need to instantiate a driver with your credentials. Begin by creating a file called <tt>libctest.py<\/tt> with the following content.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/usr\/bin\/env python\nimport os\nimport libcloud\nfrom pprint import pprint\n\ncls = libcloud.get_driver(libcloud.DriverType.COMPUTE,libcloud.DriverType.COMPUTE.UPCLOUD)\ndriver = cls(os.environ['UpCloud_API_username'], os.environ['UpCloud_API_password'])\n\npprint(driver.list_locations())<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, assign&nbsp;your credentials to environmental variables named&nbsp;<tt>UpCloud_API_username<\/tt>&nbsp;and <tt>UpCloud_API_password<\/tt>. For example on Linux use the following commands.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">export&nbsp;<tt>UpCloud_API_username='username'\nexport&nbsp;<tt>UpCloud_API_password='password'\n<\/tt><\/tt><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These can also be stored permanently in your&nbsp;<tt>.bashrc<\/tt> or <tt>.zshrc<\/tt>&nbsp;profiles avoiding having to rerun the export commands manually on every new terminal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Set the test program as executable with the next command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">chmod +x libctest.py<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then run the short program on the terminal to test that it connects to the UpCloud API correctly using the&nbsp;command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">.\/<tt>libctest<\/tt>.py<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">[&lt;NodeLocation: id=de-fra1, name=Frankfurt #1, country=DE, driver=Upcloud&gt;,\n &lt;NodeLocation: id=fi-hel1, name=Helsinki #1, country=FI, driver=Upcloud&gt;,\n &lt;NodeLocation: id=fi-hel2, name=Helsinki #2, country=FI, driver=Upcloud&gt;,\n &lt;NodeLocation: id=nl-ams1, name=Amsterdam #1, country=NL, driver=Upcloud&gt;,\n &lt;NodeLocation: id=sg-sin1, name=Singapore #1, country=SG, driver=Upcloud&gt;,\n &lt;NodeLocation: id=uk-lon1, name=London #1, country=UK, driver=Upcloud&gt;,\n &lt;NodeLocation: id=us-chi1, name=Chicago #1, country=US, driver=Upcloud&gt;]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you see an output like the above, your driver is working!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a new server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The basic process of creating a new server requires the following minimum parameters: system image, configuration size, data centre location, and a name for the server. Below are some examples of how to select the parameters for the deployment call.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Get the Ubuntu 16.04 public template\nfor image in driver.list_images():\n    if image.name.startswith('Ubuntu') \n    and image.name.count('16.04') \n    and image.id.endswith('0'):\n        break\n\n# Select the node size from the preconfigured instances\nfor size in driver.list_sizes():\n    if size.name == '1xCPU-1GB':\n        break\n\n# Pick the zone by the city name\nfor location in driver.list_locations():\n    if location.name.startswith('London'):\n        break\n\nnode = driver.create_node(\n    image=image,\n    size=size,\n    location=location,\n    name='Libcloud Example',\n    ex_hostname='libcloud.example.com'\n    )\n\npprint(node.state)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Simply add the above code to the end of your <tt>libctest.py<\/tt> test file. Then run the program as before to deploy the first server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rebooting a server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Issuing a reboot command requires you to first get the right node object. Afterwards, you have the following two options to restart the node.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Asking the driver to reboot the node.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node = [node for node in driver.list_nodes() if node.name == 'Libcloud Example'][0]\ndriver.reboot_node(node)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Alternatively, you can command the node object directly.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node = [node for node in driver.list_nodes() if node.name == 'Libcloud Example'][0]\nnode.reboot()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The functions will return <tt>True<\/tt> once the server has been rebooted successfully. If something went wrong, you will get <tt>False<\/tt> instead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Destroying a server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly to the reboot commands, a node can be destroyed using either of the two methods below. The process will shut down the target node and remove the server without deleting the storage device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Select the node you wish to destroy and ask the driver to remove it.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node = [node for node in driver.list_nodes() if node.name == 'Libcloud Example'][0]\ndriver.destroy_node(node)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or tell the node to destroy itself.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node = [node for node in driver.list_nodes() if node.name == 'Libcloud Example'][0]\nnode.destroy()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The functions will return <tt>True<\/tt> once the server has been successfully&nbsp;deleted. In case the server could not be removed, you will get <tt>False<\/tt> as a response.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that after destroying a server, the state of the node object will no longer be up to date. You should always refresh the list of nodes after creating or destroying nodes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Including SSH keys at deployment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH keys are a safe and convenient way to authenticate when logging in to your cloud servers. You can include the public half of your SSH key pair when deploying a new node by reading it from the key file into the <tt>auth<\/tt> parameter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By default, the public key is added to the <tt>root<\/tt> user account. If you wish to define a custom username, you can add it to the&nbsp;<tt>ex_username<\/tt> parameter. The new username is created at deployment and given <tt>sudo<\/tt> privileges.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from libcloud.compute.base import NodeAuthSSHKey\n\nwith open('\/path\/to\/public_ssh_key', 'r') as public:\n    public_ssh_key = public.read().replace('n', '')\n\nnode = driver.create_node(\n    image=image,\n    size=size,\n    location=location,\n    name='Libcloud Example',\n    ex_hostname='libcloud.example.com',\n    auth=NodeAuthSSHKey(public_ssh_key),\n    ex_username='username'\n    )<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Defining a username already at deployment allows you to skip the hassle of setting up <tt>sudo<\/tt> access manually.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using init scripts&nbsp;at deployment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Libcloud also supports running custom scripts at server deployment. The scripts can contain any normal Linux commands and tasks but will only work with Linux system templates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using an init script&nbsp;will require a private SSH key that corresponds to your public SSH key. The Libcloud driver needs to connect to the new server over SSH to run the script. Include the file path to your private SSH key in the <tt>ssh_key<\/tt> parameter as shown in the example below.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You also have the option to run the init script under a specific user account by defining the <tt>ssh_username<\/tt> parameter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the init script and deployment time SSH details are only available in the <tt>deploy_node()<\/tt> function.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from libcloud.compute.deployment import ScriptDeployment\nfrom libcloud.compute.base import NodeAuthSSHKey\n\n# Create an init script that is run during deployment\ninitscript = ScriptDeployment('echo \"Deployed with Libcloud\" &gt; ~\/libcloud.out')\n\n# Include SSH keys that are used to authenticate on the server\nprivate_ssh_key_file = '\/path\/to\/private_ssh_key'\nwith open('\/path\/to\/public_ssh_key', 'r') as public:\n    public_ssh_key = public.read().replace('n', '')\n\nnode = driver.deploy_node(\n    ssh_key=private_ssh_key_file,\n    ssh_username='root',\n    deploy=initscript,\n    image=image,\n    size=size,\n    location=location,\n    name='Libcloud Example',\n    ex_hostname='libcloud.example.com',\n    auth=NodeAuthSSHKey(public_ssh_key)\n    )<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once deployed, the process will attempt to connect to the server and run the init script.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In case the SSH connection fails, the function will raise an HTTP exception.<\/p>\n","protected":false},"author":3,"featured_media":27277,"comment_status":"open","ping_status":"closed","template":"","community-category":[256,223],"class_list":["post-2281","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2281","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2281"}],"version-history":[{"count":2,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2281\/revisions"}],"predecessor-version":[{"id":3987,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2281\/revisions\/3987"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2281"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}