diff --git a/README.rst b/README.rst index 92ab23f..01b2c05 100644 --- a/README.rst +++ b/README.rst @@ -45,6 +45,7 @@ Ubuntu 18.04. We have a bunch of tutorials to get you started! - `Digital Ocean `_ - `Google Cloud `_ - `Jetstream `_ + - `Amazon Web Services `_ - ... your favorite provider here, if you can contribute! - `Tutorial to install TLJH on an already running server you have root access to diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..1286e27 Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/contributing/docs.rst b/docs/contributing/docs.rst index fb0adbb..f5a7549 100644 --- a/docs/contributing/docs.rst +++ b/docs/contributing/docs.rst @@ -134,6 +134,7 @@ The documentation is organized into several categories: Writing style ============= +Typically, documentation is written in second person, referring to the reader as “you”. When using pronouns in reference to a hypothetical person, such as "a user with a running notebook", gender neutral pronouns (they/their/them) should be used. Instead of: diff --git a/docs/howto/admin/resize.rst b/docs/howto/admin/resize.rst index 95b897b..f0d0c12 100644 --- a/docs/howto/admin/resize.rst +++ b/docs/howto/admin/resize.rst @@ -1,15 +1,21 @@ .. _howto/admin/resize: -================= -Resizing a server -================= +================================================= +Resize the resources available to your JupyterHub +================================================= -As you are using your JupyterHub, you may find that you have a need to increase or decrease -the amount of resources allocated to your TLJH install. How resources can be reallocated -will depend on the server interface; consult the installation page for your provider for -more information. +As you are using your JupyterHub, you may need to increase or decrease +the amount of resources allocated to your TLJH install. The kinds of resources that can be +allocated, as well as the process to do so, will depend on the provider / interface for your +VM. We recommend consulting the installation page for your provider for more information. This +page covers the steps your should take on your JupyterHub *after* you've reallocated resources on +the cloud provider of your choice. -However, once resources have been reallocated, you must tell TLJH to make use of these resources, +Currently there are instructions to resize your resources on the following providers: + +* :ref:`Digital Ocean `. + +Once resources have been reallocated, you must tell TLJH to make use of these resources, and verify that the resources have become available. .. _tljh_verify: @@ -17,11 +23,10 @@ and verify that the resources have become available. Verifying a Resize ================== -#. Once you have resized your server, you will need to tell the JupyterHub to make use of - these new resources. To accomplish this, you will follow the instructions in - :ref:`topic/tljh-config` to edit :ref:`tljh-set-user-limits`, and - reload the hub. These steps can be completed using the terminal in the JupyterHub. - They can also be completed through the terminal. +#. Once you have resized your server, tell the JupyterHub to make use of + these new resources. To accomplish this, follow the instructions in + :ref:`topic/tljh-config` to set new memory or CPU limits and reload the hub. This can be completed + using the terminal in the JupyterHub (or via SSH-ing into your VM and using this terminal). #. TLJH configuration options can be verified by viewing the tljh-config output. @@ -29,28 +34,29 @@ Verifying a Resize sudo tljh-config show + Double-check that your changes are reflected in the output. -#. If you have changed your memory availability successfully, this will be reflected - in the `nbresuse `_ extension in the upper-right - when you open a Jupyter notebook on the Hub. +#. **To verify changes to memory**, confirm that it worked by starting + a new server (if you had one previously running, click "Control Panel -> Stop My Server" to + shut down your active server first), opening a notebook, and checking the value of the + `nbresuse `_ extension in the upper-right. .. image:: ../../images/nbresuse.png :alt: nbresuse demonstration -#. If you have changed the number of cores, this can be verified at the command line. - ``nproc`` displays the number of available cores, and should be equal to the +#. **To verify changes to CPU**, use the ``nproc`` from a terminal. + This command displays the number of available cores, and should be equal to the number of cores you selected in your provider's interface. .. code-block:: bash nproc --all - -#. Disk space changes can be verified, as well. The ``df`` command shows how much disk - space is available. The ``-hT`` argument allows us to have this printed in a human readable - format, and condenses the output to show one storage volume. +#. **To verify currently-available disk space**, use the ``df`` command in a terminal. This shows + how much disk space is available. The ``-hT`` argument allows us to have this printed in a human readable + format, and condenses the output to show one storage volume. Note that currently you cannot + change the disk space on a per-user basis. .. code-block:: bash df -hT /home - diff --git a/docs/howto/env/server-resources.rst b/docs/howto/env/server-resources.rst new file mode 100644 index 0000000..1295672 --- /dev/null +++ b/docs/howto/env/server-resources.rst @@ -0,0 +1,10 @@ +.. _howto/env/server-resources: + +====================================== +Configure resources available to users +====================================== + +To configure the resources that are available to your users (such as RAM, CPU +and Disk Space), see the section :ref:`tljh-set-user-limits`. For information +on **resizing** the environment available to users *after* you've created your +JupyterHub, see :ref:`howto/admin/resize`. diff --git a/docs/images/.DS_Store b/docs/images/.DS_Store new file mode 100644 index 0000000..1c30720 Binary files /dev/null and b/docs/images/.DS_Store differ diff --git a/docs/images/providers/.DS_Store b/docs/images/providers/.DS_Store new file mode 100644 index 0000000..6c20ed2 Binary files /dev/null and b/docs/images/providers/.DS_Store differ diff --git a/docs/images/providers/amazon/change_size_type.png b/docs/images/providers/amazon/change_size_type.png new file mode 100644 index 0000000..00d58ee Binary files /dev/null and b/docs/images/providers/amazon/change_size_type.png differ diff --git a/docs/images/providers/amazon/compute_services.png b/docs/images/providers/amazon/compute_services.png new file mode 100644 index 0000000..d1dd032 Binary files /dev/null and b/docs/images/providers/amazon/compute_services.png differ diff --git a/docs/images/providers/amazon/create_key_pair.png b/docs/images/providers/amazon/create_key_pair.png new file mode 100644 index 0000000..f92234b Binary files /dev/null and b/docs/images/providers/amazon/create_key_pair.png differ diff --git a/docs/images/providers/amazon/finally_launch.png b/docs/images/providers/amazon/finally_launch.png new file mode 100644 index 0000000..bd08c82 Binary files /dev/null and b/docs/images/providers/amazon/finally_launch.png differ diff --git a/docs/images/providers/amazon/get_system_log.png b/docs/images/providers/amazon/get_system_log.png new file mode 100644 index 0000000..2f65bfd Binary files /dev/null and b/docs/images/providers/amazon/get_system_log.png differ diff --git a/docs/images/providers/amazon/instances_from_console.png b/docs/images/providers/amazon/instances_from_console.png new file mode 100644 index 0000000..172d066 Binary files /dev/null and b/docs/images/providers/amazon/instances_from_console.png differ diff --git a/docs/images/providers/amazon/launch_instance_button.png b/docs/images/providers/amazon/launch_instance_button.png new file mode 100644 index 0000000..de3e43b Binary files /dev/null and b/docs/images/providers/amazon/launch_instance_button.png differ diff --git a/docs/images/providers/amazon/launch_now.png b/docs/images/providers/amazon/launch_now.png new file mode 100644 index 0000000..35618ab Binary files /dev/null and b/docs/images/providers/amazon/launch_now.png differ diff --git a/docs/images/providers/amazon/launch_status_screen.png b/docs/images/providers/amazon/launch_status_screen.png new file mode 100644 index 0000000..5a02fc8 Binary files /dev/null and b/docs/images/providers/amazon/launch_status_screen.png differ diff --git a/docs/images/providers/amazon/name_hub.png b/docs/images/providers/amazon/name_hub.png new file mode 100644 index 0000000..5cc4e1f Binary files /dev/null and b/docs/images/providers/amazon/name_hub.png differ diff --git a/docs/images/providers/amazon/public_ip.png b/docs/images/providers/amazon/public_ip.png new file mode 100644 index 0000000..efe271e Binary files /dev/null and b/docs/images/providers/amazon/public_ip.png differ diff --git a/docs/images/providers/amazon/running_server.png b/docs/images/providers/amazon/running_server.png new file mode 100644 index 0000000..4fa7204 Binary files /dev/null and b/docs/images/providers/amazon/running_server.png differ diff --git a/docs/images/providers/amazon/script_in_user_data.png b/docs/images/providers/amazon/script_in_user_data.png new file mode 100644 index 0000000..68a61cb Binary files /dev/null and b/docs/images/providers/amazon/script_in_user_data.png differ diff --git a/docs/images/providers/amazon/select_ubuntu_18.png b/docs/images/providers/amazon/select_ubuntu_18.png new file mode 100644 index 0000000..2624c54 Binary files /dev/null and b/docs/images/providers/amazon/select_ubuntu_18.png differ diff --git a/docs/images/providers/amazon/set_security_groups.png b/docs/images/providers/amazon/set_security_groups.png new file mode 100644 index 0000000..c6c2a0f Binary files /dev/null and b/docs/images/providers/amazon/set_security_groups.png differ diff --git a/docs/images/providers/amazon/system_log_example.png b/docs/images/providers/amazon/system_log_example.png new file mode 100644 index 0000000..57bd2b4 Binary files /dev/null and b/docs/images/providers/amazon/system_log_example.png differ diff --git a/docs/images/providers/digitalocean/power-off.png b/docs/images/providers/digitalocean/power-off.png new file mode 100644 index 0000000..7b6bbe6 Binary files /dev/null and b/docs/images/providers/digitalocean/power-off.png differ diff --git a/docs/index.rst b/docs/index.rst index 98f1c1f..bab5bd8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,6 +30,7 @@ Ubuntu 18.04. We have a bunch of tutorials to get you started. install/digitalocean install/jetstream install/google + install/amazon install/custom-server Once you are ready to run your server for real, @@ -58,6 +59,7 @@ The user environment howto/env/user-environment howto/env/notebook-interfaces + howto/env/server-resources Authentication -------------- @@ -123,6 +125,7 @@ here to better support your favorite provider! :titlesonly: troubleshooting/providers/google + troubleshooting/providers/amazon Contributing ============ diff --git a/docs/install/amazon.rst b/docs/install/amazon.rst new file mode 100644 index 0000000..5402350 --- /dev/null +++ b/docs/install/amazon.rst @@ -0,0 +1,277 @@ +.. _install/amazon: + +================================= +Installing on Amazon Web Services +================================= + +Goal +==== + +By the end of this tutorial, you should have a JupyterHub with some admin +users and a user environment with packages you want installed running on +`Amazon Web Services `_. + +Prerequisites +============= + +#. An Amazon Web Services account. When you set it up, it will probably ask you + to set your default region. + + There is a tier of compute use that is free for the first year that is fully + capable of running a minimal littlest Jupyterhub for testing purposes. + +Step 1: Installing The Littlest JupyterHub +========================================== + +Let's create the server on which we can run JupyterHub. + +#. Go to `Amazon Web Services `_ and click the gold + button 'Sign In to the Console' in the upper right. Log in with your Amazon Web + Services account. + + If you need to adjust your region from your default, there is a drop-down + menu between your name and the **Support** menu on the far right of the dark + navigation bar across the top of the window. Adjust the region of the + services you want to interact with now to match the closest one to the + majority of your users. + +#. On the screen listing all the availabe services, pick **EC2** under **Compute** + on the left side at the top of the first column. + + .. image:: ../images/providers/amazon/compute_services.png + :alt: Select EC2 + + This will take you to the **EC2 Management Console**. + +#. From the navigation menu listing on the far left side of the **EC2 Management + Console**, choose **Instances** under the light gray **INSTANCES** sub-heading. + + .. image:: ../images/providers/amazon/instances_from_console.png + :alt: Select Instances from console + +#. In the main window of the **EC2 Management Console**, towards the top left, + click on the bright blue **Launch Instance** button. + + .. image:: ../images/providers/amazon/launch_instance_button.png + :alt: Click launch instance + + This will start the 'launch instance wizard' process. This lets you customize + the kind of server you want, the resources it will have & what it'll be called. + + +#. On the page **Step 1: Choose an Amazon Machine Image (AMI)** you are going + to pick the base image your remote server machine will have. The view will + default to the 'Quick-start' tab selected and just a few down the page, select + **Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-0ac019f4fcb7cb7e6**. + + .. image:: ../images/providers/amazon/select_ubuntu_18.png + :alt: Click Ubuntu server 18.04 + + The `ami` alpha-numeric at the end references the specific Amazon machine + image. It may be different as Amazon updates these routinely. The + **Ubuntu Server 18.04 LTS (HVM)** is the important part. + + +#. After selecting the AMI, you'll be at **Step 2: Choose an Instance Type**. + + There will be a long listing of the types and numbers of CPUs that Amazon + offers. Select the one you want and then select the button + `Next: Configure Instance Details` in the lower right corner. + + Check out our guide on How To :ref:`howto/admin/resource-estimation` to help pick + how much Memory / CPU your server needs. + + You may wish to consult the listing `here `_ + because it shows cost per hour. The **On Demand** price is the pertinent cost. + + (For point of reference, I was able to get a minimal hub that worked for + developing this tutorial using **t2.micro** tier. That tier is free for + Amazon users the first year they sign up. Two users were able to concurrently + access this development hub.) + + If you want to **GPUs**, you'll have to scroll down about half way to find + the `GPU graphics` and `GPU compute` products. + +#. Under **Step 3: Configure Instance Details**, scroll to the bottom of the page + and toggle the arrow next to **Advanced Details** to get the rest of the page to + drop down. Scroll down further to reveal a section entitled 'User data'. Copy + the text below, and paste it into the **User data** text box. Replace + ```` with the name of the first **admin user** for this + JupyterHub. This admin user can log in after the JupyterHub is set up, and + can configure it to their needs. **Remember to add your username**! + + .. code-block:: bash + + #!/bin/bash + curl https://raw.githubusercontent.com/jupyterhub/the-littlest-jupyterhub/master/bootstrap/bootstrap.py \ + | sudo python3 - \ + --admin + + .. image:: ../images/providers/amazon/script_in_user_data.png + :alt: Install JupyterHub with the script in the User data textbox + + .. note:: + + See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing. + :ref:`topic/customizing-installer` documents other options that can be passed to the installer. + +#. Under **Step 4: Add Storage**, you can change the **size** and **type of your + disk by adjusting the value in **Size (GiB)** and selecting **Volume Type**. + + .. image:: ../images/providers/amazon/change_size_type.png + :alt: Selecting disk size and type + + Check out our guide on How To :ref:`howto/admin/resource-estimation` to help pick + how much Disk space your server needs. + + Hover over the encircled `i` next to **Volume Type** for an explanation of + each. Leaving the default as is is fine. `General Purpose SSD (gp2)` is + recommended for most workloads. With `Provisioned IOPS SSD (io1)` being the + highest-performance SSD volume. Magnetic (standard) is a previous generation + volume and not suited for a hub for multi-users. + + When finished, click **Next: Add Tags** in the bottom right corner. + +#. Under **Step 5: Add Tags**, click **Add Tag** and enter **Name** under the + **Key** field. In the **Value** field in the **Name** row, give your new + server a memorable name that identifies what purpose this JupyterHub will be + used for. + + .. image:: ../images/providers/amazon/name_hub.png + :alt: Use tags to name the hub. + +#. Under **Step 6: Configure Security Group**, you'll set the firewall rules + that control the traffic for your instance. Specifically you'll want to add + rules can add rules to allow both **HTTP Traffic** and **HTTPS Traffic**. For + advanced troubleshooting, it will be helpful to set rules so you can use + SSH to connect (port 22). + + If you have never used your Amazon account before, you'll have to select + **Create a new security group**. You should give it a disitnguishing name + under **Security group name** + such as `ssh_web` for future reference. If you have, one from before you can + selectit and adjust it to have the rules you need, if oyu prefer. + + The rules will default to include `SSH`. Leave that there, and then click on + the **Add Rule** button. Under **Type** for the new rule, change the field + to **HTTP**. The other boxes will get filled in appropritely. Again, click on + the **Add Rule** button. This time under **Type** for the new rule, change + the field to **HTTPS**. + + The warning is there to remind you this opens things up to some degree but + this is necessary in order to let your users connect. However, this warning + is a good reminder that you should monitor your server to insure it is + available for users who may need it. + + .. image:: ../images/providers/amazon/set_security_groups.png + :alt: Allow HTTP & HTTPS traffic to your server + +#. When the security rules are set, click on the blue button in the bottom + right **Review and Launch**. This will give you a chance to review things + because very soon you'll be launching and start paying for any resources you + use. + + Note that you'll see two HTTP listings and two HTTPS listings under + **Security Groups** even though you only made one for each. This is normal & + necessary to match both IPv4 & IPv6 types of IP addresses. + + When you are happy, press the blue **Launch** button in the bottom right + corner to nearly conclude your journey through the instance launch wizard. + + .. image:: ../images/providers/amazon/finally_launch.png + :alt: Launch your server + +#. In the dialog box that pops up as the last step before launching is + triggered, you need to choose what to do about an identifying key pair and + acknowledge your choice in order to proceed. If you already have a key pair you + can select to associate it with this instance, otherwise you need to + **Create a new key pair**. Choosing to `Proceed with a key pair` is not + recommended as you'll have no way to access your server if anything goes wrong + with the Jupyterhub amd no way to recover files via download. + + Download and keep the key pair file unless you are associating one you already + have. + + .. image:: ../images/providers/amazon/create_key_pair.png + :alt: Associate key pair + +#. With the key pair associated, click the **Launch instances** button to + start creating the server that'll run TLJH. + + .. image:: ../images/providers/amazon/launch_now.png + :alt: Trigger actual launch + + +#. Following the launch initiation, you'll be taken to a **Launch Status** + notification screen. You can see more information about the details if you + click on the alphanumeric link to the launching instance following the text, + "`The following instance launches have been initiated:`". + + .. image:: ../images/providers/amazon/launch_status_screen.png + :alt: Launch status notice + +#. That link will take you back to the **EC2 Management Console** with settings + that will limit the view in the console to just that instance. (Delete the + filter in the search bar if you want to see any other instances you may + have.) At first the server will be starting up, and then when the + **Instance state** is green the server is running. + + .. image:: ../images/providers/amazon/running_server.png + :alt: Server is running. + + If you already have instances running in your account, the screen will look + different if you disable that filter. But you want to pay attention to the + row with the name of the server you made. + +#. In a few seconds your server will be created, and you can see the + **Public IP** used to access it in the panel at the bottom of the console. + If it isn't displayed, click on the row for that instance in the console. It + will look like a pattern similar to **12.30.230.127**. + + .. image:: ../images/providers/amazon/public_ip.png + :alt: public IP + +#. The Littlest JupyterHub is now installing in the background on your new + server. It takes around 10 minutes for this installation to complete. + +#. Check if the installation is complete by copying the **Public IP** + of your server, and trying to access it from within a browser. If it has been + 10 minutes, paste the public IP into the URL bar of your browser and hit + return to try to connect. + + Accessing the JupyterHub will fail until the installation is complete, + so be patient. The next step below this one shows the login window you are + expecting to see when trying the URL and things work. + While waiting until the appropriate time to try, another way to check if + things are churning away, is to open the **System Log**. To do this, go to + the **EC2 Management Console** & highlight the instance by clicking on that + row and then right-click **Instance Settings** > **Get System Log**. + + .. image:: ../images/providers/amazon/get_system_log.png + :alt: Getting system log. + + When the Jupyterhub creation process works and the hub is ready to show you + the login the **System Log** will look like the image below if you scroll to + the bottom. Note the line **Starting TLJH installer**. (Somtimes I would + also see **Started jupyterhub.service** shortly after that, but not always.) + +#. When the installation is complete, it should give you a JupyterHub login page. + + .. image:: ../images/first-login.png + :alt: JupyterHub log-in page + +#. Login using the **admin user name** you used in step 6, and a password. Use a + strong password & note it down somewhere, since this will be the password for + the admin user account from now on. + +#. Congratulations, you have a running working JupyterHub! + +Step 2: Adding more users +========================== + +.. include:: add_users.txt + +Step 3: Install conda / pip packages for all users +================================================== + +.. include:: add_packages.txt \ No newline at end of file diff --git a/docs/install/digitalocean.rst b/docs/install/digitalocean.rst index 363f5e2..a4e316e 100644 --- a/docs/install/digitalocean.rst +++ b/docs/install/digitalocean.rst @@ -118,16 +118,38 @@ Step 3: Install conda / pip packages for all users .. include:: add_packages.txt +.. _digitalocean/resize: + Step 4: Resizing and editing the droplet ======================================== -#. As you are using your JupyterHub, you may find that you need more memory, - disk space, or CPUs. Digital Ocean servers can be resized in the - "Resize Droplet" panel. +As you use your JupyterHub, you may find that you need more memory, +disk space, or CPUs. Digital Ocean servers can be resized in the +"Resize Droplet" panel. These instructions take you through the process. + +#. First, click on the name of your newly-created + Droplet to enter its configuration page. + +#. Next, **turn off your Droplet**. This allows DigitalOcean to make + modifications to your VM. This will shut down your JupyterHub (temporarily). + + .. image:: ../images/providers/digitalocean/power-off.png + :alt: Power off your Droplet + :width: 200px + +#. Once your Droplet has been turned off, click "Resize", + which will take you to a menu with options to resize your VM. .. image:: ../images/providers/digitalocean/resize-droplet.png :alt: Resize panel of digital ocean - Further information on making more resources available to TLJH and verifying resource - availability can be found in the How-To :ref:`howto/admin/resize`. +#. Decide what kinds of resources you'd like to resize, then click on a new VM + type in the list below. Finally, click "Resize". This may take a few moments! + +#. Once your Droplet is resized, **turn your Droplet back on**. This makes your JupyterHub + available to the world once again. This will take a few moments to complete. + +Now that you've resized your Droplet, you may want to change the resources available +to your users. Further information on making more resources available to +users and verifying resource availability can be found in :ref:`howto/admin/resize`. diff --git a/docs/install/google.rst b/docs/install/google.rst index 817d33c..0447cb5 100644 --- a/docs/install/google.rst +++ b/docs/install/google.rst @@ -136,7 +136,7 @@ Let's create the server on which we can run JupyterHub. This displays a lot of advanced options, but we'll be only using one of them. -#. Copy the text below, and paste it into the **Starup script** text box. Replace +#. Copy the text below, and paste it into the **Startup script** text box. Replace ```` with the name of the first **admin user** for this JupyterHub. This admin user can log in after the JupyterHub is set up, and can configure it to their needs. **Remember to add your username**! diff --git a/docs/topic/customizing-installer.rst b/docs/topic/customizing-installer.rst index 359baea..2fb2f50 100644 --- a/docs/topic/customizing-installer.rst +++ b/docs/topic/customizing-installer.rst @@ -68,7 +68,7 @@ research, a stack for a praticular class, etc. ``--plugin `` installs and activates a plugin. You can pass it however many times you want. Since plugins are distributed as python packages, ```` can be anything that can be passed to ``pip install`` - -``plugin-name-on-pypy==`` and ``git+https://github.com/user/repo@tag`` +``plugin-name-on-pypi==`` and ``git+https://github.com/user/repo@tag`` are the most popular ones. Specifying a version or tag is highly recommended. For example, to install the PANGEO Plugin version 0.1 in your new TLJH install, @@ -84,4 +84,4 @@ you would use: .. note:: Plugins are extremely powerful and can do a large number of arbitrary things. - Only install plugins you trust. \ No newline at end of file + Only install plugins you trust. diff --git a/docs/troubleshooting/.DS_Store b/docs/troubleshooting/.DS_Store new file mode 100644 index 0000000..4f10a9c Binary files /dev/null and b/docs/troubleshooting/.DS_Store differ diff --git a/docs/troubleshooting/providers/amazon.rst b/docs/troubleshooting/providers/amazon.rst new file mode 100644 index 0000000..a39f1f9 --- /dev/null +++ b/docs/troubleshooting/providers/amazon.rst @@ -0,0 +1,32 @@ +============================================= +Troubleshooting issues on Amazon Web Services +============================================= + +This is an incomplete list of issues people have run into when running +TLJH on Amazon Web Services (AWS), and how they have fixed them! + +'Connection Refused' error after restarting server +================================================== + +If you restarted your server from the EC2 Management Console & then try to access +your JupyterHub from a browser, you might get a **Connection Refused** error. +This is most likely because the **External IP** of your server has changed. + +Check the **IPv4 Public IP** dislayed in the bottom of the `EC2 Management Console` +screen for that instance matches the IP you are trying to access. If you have a +domain name pointing to the IP address, you might have to change it to point to +the new correct IP. + +You can prevent public IP changes by `associating a static IP +`_ +with your server. In the Amazon Web Services ecosystem, the public static IP +addresses are handled under `Elastic IP addresses` category of AWS; these +addresses are tied to the overall AWS account. `This guide +`_ might be helpful. Notice +there can be a cost to this. Although `the guide +`_ is outdated (generally +half that `price now `_), +Amazon describes `here `_ +how the Elastic IP address feature is free when associated with a running +instance, but that you'll be charged by the hour for maintaining that specific +IP address when it isn't associated with a running instance.