Deploying a multi-node environment
To deploy a multi-node Open edX environment, use the
edx-multi-node.yaml
template. You must set three mandatory
parameters when invoking Heat:
public_net_id
, which must be set to the UUID of your external network;app_count
, which is the number of application servers you want to spin up;key_name
, which is the name of the Nova keypair that you'll be using to log in once the machines have spun up.
In addition, you must set the name of the stack.
stack=<stack_name> openstack stack create \ --template heat-templates/hot/edx-multi-node.yaml \ --parameter public_net_id=<uuid> \ --parameter app_count=<num> \ --parameter key_name=<name> \ $stack
To verify that the stack has reached the CREATE_COMPLETE
state, run:
openstack stack show $stack
Once stack creation is complete, you can use openstack stack output show
to
retrieve the IP address of your deployment host, and then to connect to it,
making sure to forward your SSH authentication agent:
openstack stack output show $stack deploy_ip
ssh ubuntu@<deploy_ip> -A
Before you continue, you'll need the hastexo/integration/base
fork of
edx-configuration
. Clone it, and then enable the sample group and host
variables, which will configure this deployment of Open edX. Due to how
Ansible variable precedence works, it is recommended that you copy the sample
ones to a separate directory:
git clone https://github.com/hastexo/edx-configuration.git -b hastexo/integration/base cp -a edx-configuration/playbooks/openstack edx-configuration-secrets cd edx-configuration-secrets/group_vars for i in *.example; do cp $i ${i%.example}; done cd ../host_vars for i in 192*.example; do cp $i ${i%.example}; done
It is recommended that you use the hastexo edX repositories, and in particular
the hastexo/integration/hastexo
branch of edx-platform
. These are known to
work correctly in an OpenStack cluster. To do so, edit
edx-configuration-secrets/group_vars/all
, and replace the repository
variables with the following:
# Repos edx_platform_repo: "https://{{ COMMON_GIT_MIRROR }}/hastexo/edx-platform.git" edx_platform_version: "hastexo/integration/hastexo" CERTS_REPO: "https://{{ COMMON_GIT_MIRROR }}/hastexo/edx-certificates.git" certs_version: "master" forum_source_repo: "https://{{ COMMON_GIT_MIRROR }}/hastexo/edx-forum.git" forum_version: "master" xqueue_source_repo: "https://{{ COMMON_GIT_MIRROR }}/hastexo/edx-xqueue.git" xqueue_version: "hastexo/integration/hastexo" NOTIFIER_SOURCE_REPO: "https://{{ COMMON_GIT_MIRROR }}/hastexo/edx-notifier.git" NOTIFIER_VERSION: "master"
At this point, make sure to create a Swift container for this deployment: it'll
be needed during the initial playbook run. You can do so from your own
computer, as long as the openstack
command line client is installed and the
appropriate OpenStack credentials are loaded into the environment. By default,
the sample Ansible variables will configure edX to use the "lms.example.com"
container. Run the following to create the container with read permissions for
connections originating from the site itself:
Note: You can change the site name by editing
edx-configuration-secrets/group_vars/all
and replacing
EDXAPP_SITE_NAME
with the desired domain.
site=lms.example.com openstack container create $site openstack container set --property "read_acl=.r:$site" $site
Take the opportunity to set the SWIFT_LOG_SYNC_*
variables in
group_vars/all
, even if you're not actually enabling Swift log
synchronization. These Swift authentication variables will also be used by
default for edX report storage.
Note: If you intend to use the hastexo XBlock, refer to the "Multiple nodes with the hastexo XBlock" section below, before continuing. Avoid actually running the playbook in the last step therein: this will be accomplished in in this section.
Now, generate a passphrase-less keypair, copy it over to the other nodes, and add the nodes to the host list so one doesn't have to manually confirm them later. Note that this will only work if authentication forwarding is properly configured, and if you're logged in as the default user, "ubuntu".
# Create a new key pair export KEYFILE=~/.ssh/id_rsa ssh-keygen -t rsa -N "" -f $KEYFILE # Disable strict host key checking echo "StrictHostKeyChecking no" > ~/.ssh/config # Deploy it ips=$(ansible -i ~/edx-configuration-secrets/inventory.py all --list-hosts) for ip in $ips; do ssh-keyscan $ip >> ~/.ssh/known_hosts ssh-copy-id -i $KEYFILE $ip done
At this point, it is best if you reconnect to the deploy node without agent forwarding, as the latter can interfere with the Ansible deployment. Ideally, start a screen session as well, so a disconnection will not stop the Ansible run:
exit
ssh ubuntu@<deploy_ip>
screen
Be sure to run the inventory.py
dynamic inventory generator, as opposed to
the static intentory.ini
, meant for single node deployments. Also, set
migrate_db=yes
on this first run, to ensure that the databases and tables are
properly created.
cd ~/edx-configuration/playbooks ansible-playbook -i ../../edx-configuration-secrets/inventory.py openstack-multi-node.yml -e migrate_db=yes
This playbook run may take one hour or more. After it's done, log out of the
deploy node and edit your local /etc/hosts. If you didn't change any of the
example variables, enter the following, substituting app_ip
for the IP
address of the app server pool you can obtain with the following command:
openstack stack output show $stack app_ip
vim /etc/hosts
---
<app_ip> lms.example.com studio.example.com
You should now be able to access both the LMS and Studio using the following HTTPS URLs, respectively:
To deploy additional application servers within a previously deployed
stack, use the openstack stack update
command to increase the app_count
stack parameter:
openstack stack update --existing --parameter app_count=<new_num> $stack
If you removed app servers, there's nothing else you need to do.
If you added app servers, however, log back into the deploy node, and run the multi-node playbook again, limiting the run to the app servers and avoiding database migrations:
cd /var/tmp/edx-configuration/playbooks
ansible-playbook -i ../../edx-configuration-secrets/inventory.py openstack-multi-node.yml --limit app_servers
Multiple nodes with the hastexo XBlock
If you want to deploy the hastexo XBlock together with Open edX to your multi node cluster, go back to your deploy node and:
- Locate the following variables in
/var/tmp/edx-configuration-secrets/group_vars/all
(which you created above) and change them as described. Set theos_*
variables to the OpenStack cloud of your choice.
EDXAPP_EXTRA_REQUIREMENTS: - name: "git+https://github.com/hastexo/hastexo-xblock.git@master#egg=hastexo-xblock" EDXAPP_ADDL_INSTALLED_APPS: - 'hastexo' EDXAPP_XBLOCK_SETTINGS: hastexo: providers: default: os_auth_url: "" os_auth_token: "" os_username: "" os_password: "" os_user_id: "" os_user_domain_id: "" os_user_domain_name: "" os_project_id: "" os_project_name: "" os_project_domain_id: "" os_project_domain_name: "" os_region_name: ""
- Add the
gateone
role toopenstack-multi-node.yml
under theapp_servers
section (the last one).
$ cd ~/edx-configuration/playbooks
$ vim openstack-multi-node.yaml
...
- certs
- demo
- gateone
- Run that playbook, limitting the run to the
app_servers
:
$ ansible-playbook -i ../../edx-configuration-secrets/inventory.py openstack-multi-node.yml --limit app_servers