Commit 1bf7c923 by John Jarvis

Merge pull request #110 from edx/jarv/edx-sandbox

Jarv/edx sandbox
parents a4e02c8b 33a9a931
...@@ -36,7 +36,34 @@ over time, so expect frequent changes. ...@@ -36,7 +36,34 @@ over time, so expect frequent changes.
## AWS ## AWS
### Building the stack ### Quick start - Building the stack on a single server
To deploy the entire edX platform on a single ec2 instance
run the following commands:
```
git clone git@github.com:edx/configuration
mkvirtualenv ansible
cd configuration
pip install -r ansible-requirements.txt
cd playbooks
(adjust the settings in edx_sandbox.yml)
`ansible-playbook -vvv --user=ubuntu edx_sandbox.yml -i ec2.py -e 'secure_dir=secure_example`
```
This will install the following services on a single instance
* edX lms (django/python) for courseware
* edX studio (django/python) for course authoring
* mysql (running locally)
* mongo (running locally)
* memcache (running locally)
Note: In order for mail to work properly you will need to add AWS credentials for an account that
has SES permissions, see `secure\_example/vars/edxapp\_sandbox.yml`
### Building the stack with CloudFormation
The first step is to provision the CloudFormation stack. There are The first step is to provision the CloudFormation stack. There are
several options for doing this. several options for doing this.
......
- name: Create sandbox instance
hosts: localhost
connection: local
user: root
sudo: False
gather_facts: False
vars:
keypair: continuous-integration
instance_type: m1.large
security_group: sandbox
image: ami-d0f89fb9
region: us-east-1
roles:
- launch_instance
- name: Configure instance(s)
hosts: launched
sudo: True
gather_facts: True
vars:
migrate_db: True
vars_files:
- "{{ secure_dir }}/vars/edxapp_sandbox.yml"
- "{{ secure_dir }}/vars/users.yml"
roles:
- common
- nginx
- gunicorn
- edxlocal
- edxapp
- name: Create sandbox instance
hosts: localhost
connection: local
user: root
sudo: False
gather_facts: False
vars:
keypair: continuous-integration
instance_type: m1.large
security_group: sandbox
image: ami-d0f89fb9
region: us-east-1
roles:
- launch_instance
- name: Configure instance(s)
hosts: launched
sudo: True
gather_facts: True
vars:
migrate_db: True
vars_files:
- "{{ secure_dir }}/vars/edxapp_ref_users.yml"
- "{{ secure_dir }}/vars/edxapp_sandbox.yml"
roles:
- common
- nginx
- gunicorn
- edxlocal
- edxapp
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
- update cms templates - update cms templates
- lms asset static failure check - lms asset static failure check
- cms asset static failure check - cms asset static failure check
- syncdb and migrate
- stop edxapp - stop edxapp
- start edxapp - start edxapp
tags: tags:
...@@ -236,6 +237,17 @@ ...@@ -236,6 +237,17 @@
- cms - cms
- deploy - deploy
- name: syncdb and migrate
shell: sudo -u www-data SERVICE_VARIANT=lms /opt/edx/bin/django-admin.py syncdb --migrate --noinput --settings=lms.envs.aws --pythonpath=/opt/wwc/edx-platform
when: migrate_db is defined
tags:
- deploy
- lms
- lms-xml
- lms-preview
- cms
- syncdb
- name: stop edxapp - name: stop edxapp
service: name=edxapp state=stopped service: name=edxapp state=stopped
tags: tags:
...@@ -253,3 +265,4 @@ ...@@ -253,3 +265,4 @@
- lms-preview - lms-preview
- cms - cms
- deploy - deploy
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
# when the role is included # when the role is included
--- ---
# Default nginx listen ports
# These should be overrided if you want
# to serve all content on port 80
lms_xml_nginx_port: 18030
lms_nginx_port: 80
lms_preview_nginx_port: 18020
cms_nginx_port: 18010
# These vars are for creating the application json config # These vars are for creating the application json config
# files. There are two for each service that uses the # files. There are two for each service that uses the
# 'edx-platform' code. Defining them will create the upstart # 'edx-platform' code. Defining them will create the upstart
......
# Installs packages to run edx locally on a single instance
# requires:
# - group_vars/all
# - common/tasks/main.yml
# - nginx/tasks/main.yml
---
- name: install python-pymongo (req for ansible)
pip: name=pymongo
- name: install python-mysqldb (req for ansible)
apt: pkg=python-mysqldb state=present
- name: install mysql server and recommends
apt: pkg=mysql-server-5.5 state=present install_recommends=yes
- name: create a database
mysql_db: >
db=wwc
state=present
encoding=utf8
- name: install mongo server and recommends
apt: pkg=mongodb-server state=present install_recommends=yes
- name: stop mongo service
service: name=mongodb state=stopped
- name: move mongodb to /mnt
command: mv /var/lib/mongodb /mnt/. creates=/mnt/mongodb
- name: create mongodb symlink
file: src=/mnt/mongodb dest=/var/lib/mongodb state=link
- name: start mongo service
service: name=mongodb state=started
- name: wait for mongo server to start
wait_for: port=27017 delay=2
- name: create a mongodb user
mongodb_user: >
database=wwc
name=edxapp
password=password
state=present
- name: install memcached
apt: pkg=memcached state=present
# Launches an ec2 instance and blocks until the instance is up
# adds it to the host group
- name: Launch instance
local_action: ec2 keypair=$keypair group=$security_group instance_type=$instance_type image=$image wait=true region=$region
register: ec2
- name: Add new instance to host group
local_action: add_host hostname=${item.public_ip} groupname=launched
with_items: ${ec2.instances}
- name: Wait for SSH to come up
local_action: wait_for host=${item.public_dns_name} port=22 delay=60 timeout=320 state=started
with_items: ${ec2.instances}
server { server {
# CMS configuration file for nginx, templated by ansible # CMS configuration file for nginx, templated by ansible
listen 80; listen {{cms_nginx_port}};
server_name studio.*;
server_name trace-cms.*
studio.lms-dev.m.edx.org;
access_log {{log_base_dir}}/nginx/access.log; access_log {{log_base_dir}}/nginx/access.log;
error_log {{log_base_dir}}/nginx/error.log error; error_log {{log_base_dir}}/nginx/error.log error;
# Send error response when request host isn't under our control
# We will no longer respond to proxy attempts like this with
# anything.
# curl -i -A '' -x http://www.edx.org:80 --proxy-negotiate -U u:p -u u:p http://chat.sdtz.com
set $reject 'no';
if ($host !~* (edx.org|edxonline.org)$ ) {
set $reject 'yes';
}
if ($request_uri ~ ^(/heartbeat)$) {
set $reject 'no';
}
if ( $reject = 'yes' ) {
return 444;
}
# CS184 requires uploads of up to 4MB for submitting screenshots. # CS184 requires uploads of up to 4MB for submitting screenshots.
# CMS requires larger value for course assest, values provided # CMS requires larger value for course assest, values provided
# via hiera. # via hiera.
...@@ -61,9 +41,8 @@ server { ...@@ -61,9 +41,8 @@ server {
# Check security on this # Check security on this
location ~ /static/(?P<file>.*) { location ~ /static/(?P<file>.*) {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/nginx.htpasswd;
root {{app_base_dir}}; root {{app_base_dir}};
try_files /staticfiles/$file /course_static/$file =404;
# return a 403 for static files that shouldn't be # return a 403 for static files that shouldn't be
# in the staticfiles directory # in the staticfiles directory
...@@ -73,7 +52,6 @@ server { ...@@ -73,7 +52,6 @@ server {
# Set django-pipelined files to maximum cache time # Set django-pipelined files to maximum cache time
location ~ "/static/(?P<collected>.*\.[0-9a-f]{12}\..*)" { location ~ "/static/(?P<collected>.*\.[0-9a-f]{12}\..*)" {
expires max; expires max;
# Without this try_files, files that have been run through # Without this try_files, files that have been run through
# django-pipeline return 404s # django-pipeline return 404s
try_files /staticfiles/$collected /course_static/$collected =404; try_files /staticfiles/$collected /course_static/$collected =404;
......
server { server {
# LMS-preview configuration file for nginx, templated by ansible # LMS-preview configuration file for nginx, templated by ansible
listen 80; listen {{lms_preview_nginx_port}};
server_name trace-lms-preview.* server_name preview.*;
preview.lms-dev.m.edx.org;
#
# Send error response when request host isn't under our control
# We will no longer respond to proxy attempts like this with
# anything.
# curl -i -A '' -x http://www.edx.org:80 --proxy-negotiate -U u:p -u u:p http://chat.sdtz.com
#
set $reject 'no';
#if ($host !~* (edx.org|edxonline.org)$ ) {
# set $reject 'yes';
#}
if ($request_uri ~ ^(/heartbeat)$) {
set $reject 'no';
}
if ( $reject = 'yes' ) {
return 444;
}
# CS184 requires uploads of up to 4MB for submitting screenshots. # CS184 requires uploads of up to 4MB for submitting screenshots.
# CMS requires larger value for course assest, values provided # CMS requires larger value for course assest, values provided
# via hiera. # via hiera.
...@@ -88,12 +67,4 @@ server { ...@@ -88,12 +67,4 @@ server {
if ($do_redirect = "true") { if ($do_redirect = "true") {
rewrite ^ https://$host$request_uri? permanent; rewrite ^ https://$host$request_uri? permanent;
} }
# Monitoring support for datadog.
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1/32;
deny all;
}
} }
server { server {
# LMS-preview configuration file for nginx, templated by ansible # LMS-preview configuration file for nginx, templated by ansible
listen 80; listen {{lms_xml_nginx_port}};
server_name trace-lms-xml.* # CS184 requires uploads of up to 4MB for submitting screenshots.
xml.lms-dev.m.edx.org;
#
# Send error response when request host isn't under our control
# We will no longer respond to proxy attempts like this with
# anything.
# curl -i -A '' -x http://www.edx.org:80 --proxy-negotiate -U u:p -u u:p http://chat.sdtz.com
#
set $reject 'no';
#if ($host !~* (edx.org|edxonline.org)$ ) {
# set $reject 'yes';
#}
if ($request_uri ~ ^(/heartbeat)$) {
set $reject 'no';
}
if ( $reject = 'yes' ) {
return 444;
}
# CS184 requires uploads of up to 4MB for submitting screenshots.
# CMS requires larger value for course assest, values provided # CMS requires larger value for course assest, values provided
# via hiera. # via hiera.
client_max_body_size 4M; client_max_body_size 4M;
......
server { server {
# LMS configuration file for nginx, templated by ansible # LMS configuration file for nginx, templated by ansible
listen 80; listen {{lms_nginx_port}} default;
server_name *.edx.org;
access_log {{log_base_dir}}/nginx/access.log; access_log {{log_base_dir}}/nginx/access.log;
error_log {{log_base_dir}}/nginx/error.log error; error_log {{log_base_dir}}/nginx/error.log error;
#
# Send error response when request host isn't under our control
# We will no longer respond to proxy attempts like this with
# anything.
# curl -i -A '' -x http://www.edx.org:80 --proxy-negotiate -U u:p -u u:p http://chat.sdtz.com
#
set $reject 'no';
if ($host !~* (edx.org|edxonline.org)$ ) {
set $reject 'yes';
}
if ($request_uri ~ ^(/heartbeat)$) {
set $reject 'no';
}
if ( $reject = 'yes' ) {
return 444;
}
# CS184 requires uploads of up to 4MB for submitting screenshots. # CS184 requires uploads of up to 4MB for submitting screenshots.
# CMS requires larger value for course assest, values provided # CMS requires larger value for course assest, values provided
# via hiera. # via hiera.
...@@ -34,11 +13,6 @@ server { ...@@ -34,11 +13,6 @@ server {
rewrite ^(.*)/favicon.ico$ /static/images/favicon.ico last; rewrite ^(.*)/favicon.ico$ /static/images/favicon.ico last;
# CS188 rewrite rule for Arjun 9/19/12
rewrite ^/ai$ http://$host/courses/BerkeleyX/CS188.1x/2012_Fall/about last;
# redirect /ai to the about page for CS188.1x
rewrite ^/ai$ https://$host/courses/BerkeleyX/CS188.1x/2012_Fall/about last;
location @proxy_to_lms_app { location @proxy_to_lms_app {
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
...@@ -66,8 +40,6 @@ server { ...@@ -66,8 +40,6 @@ server {
# Check security on this # Check security on this
location ~ /static/(?P<file>.*) { location ~ /static/(?P<file>.*) {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/nginx.htpasswd;
root {{app_base_dir}}; root {{app_base_dir}};
try_files /staticfiles/$file /course_static/$file =404; try_files /staticfiles/$file /course_static/$file =404;
...@@ -97,12 +69,4 @@ server { ...@@ -97,12 +69,4 @@ server {
if ($do_redirect = "true") { if ($do_redirect = "true") {
rewrite ^ https://$host$request_uri? permanent; rewrite ^ https://$host$request_uri? permanent;
} }
# Monitoring support for datadog.
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1/32;
deny all;
}
} }
###############################################
# Sandbox configuration
#
# There should be nothing in this configuration
# that would be a problem if made public !!
#
# Configuration overview:
# - mysql installed on localhost
# - mongo installed on localhost
# - memcache installed on localhost
# - SES used for email (ses only perms)
#
# You must fill in credentials for sending
# mail using AWS
#
# Set the following before using this configuration
# configuration.
#
# * AWS_ACCESS_KEY_ID
# * AWS_SECRET_ACCESS_KEY
# * SESSION_COOKIE_DOMAIN
# * FEEDBACK_SUBMISSION_EMAIL
#
#Use YAML references (& and *) and hash merge <<: to factor out shared settings
#see http://atechie.net/2009/07/merging-hashes-in-yaml-conf-files/
generic_auth_config: &generic_auth
'CONTENTSTORE':
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore'
'ANALYTICS_API_KEY': ''
'ZENDESK_USER': ''
'ZENDESK_API_KEY': ''
'CELERY_BROKER_USER': 'celery'
'CELERY_BROKER_PASSWORD': ''
# "ses-send" user on the main aws account, only
# has access to use ses
'AWS_ACCESS_KEY_ID': ''
'AWS_SECRET_ACCESS_KEY': ''
'CONTENTSTORE':
'OPTIONS':
'db': 'wwc'
'host': [ 'localhost' ]
'password': 'password'
'port': 27017
'user': 'mongo'
'DATABASES':
'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'wwc', 'USER': 'root', 'PASSWORD': '', 'HOST': 'localhost', 'PORT': '3306' }
'MODULESTORE':
'default':
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore'
'OPTIONS': &lms_modulestore_default_options
'collection': 'modulestore'
'db': 'wwc'
'default_class': 'xmodule.hidden_module.HiddenDescriptor'
'fs_root': '/opt/wwc/data'
'host': ['localhost']
'password': 'password'
'port': 27017
'render_template': 'mitxmako.shortcuts.render_to_string'
'user': 'mongo'
# Needed for the CMS to be able to run update_templates
'direct':
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore'
'OPTIONS': *lms_modulestore_default_options
'OPEN_ENDED_GRADING_INTERFACE': {
'url': '',
'password': '',
'peer_grading': 'peer_grading',
'staff_grading': 'staff_grading',
'grading_controller': 'grading_controller',
'username': 'lms'}
'PEARSON_TEST_PASSWORD': ''
'SECRET_KEY': 'secret'
'XQUEUE_INTERFACE':
'basic_auth': [ 'noauth', 'noauth']
'django_auth': { 'password': 'lms',
'username': 'lms'}
'url': ''
generic_env_config: &generic_env
'BOOK_URL': ''
'CERT_QUEUE': 'certificates'
'LOCAL_LOGLEVEL': 'INFO'
'MITX_FEATURES':
'AUTH_USE_OPENID_PROVIDER': true
'CERTIFICATES_ENABLED': true
'ENABLE_DISCUSSION_SERVICE': false
'ENABLE_INSTRUCTOR_ANALYTICS': false
'ENABLE_PEARSON_HACK_TEST': false
'SUBDOMAIN_BRANDING': false
'SUBDOMAIN_COURSE_LISTINGS': false
'WIKI_ENABLED': true
'SYSLOG_SERVER': 'syslog.a.m.i4x.org'
'SITE_NAME': 'example.com'
'LOG_DIR': '/mnt/logs/edx'
'MEDIA_URL': ''
'ANALYTICS_SERVER_URL': ''
'FEEDBACK_SUBMISSION_EMAIL': ''
'TIME_ZONE': 'America/New_York'
'CACHES': &lms_caches
'default':
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
'KEY_FUNCTION': 'util.memcache.safe_key'
'KEY_PREFIX': 'sandbox'
'LOCATION': [ 'localhost:11211' ]
'general':
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
'KEY_FUNCTION': 'util.memcache.safe_key'
'KEY_PREFIX': 'sandbox'
'LOCATION': [ 'localhost:11211' ]
'mongo_metadata_inheritance':
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
'KEY_FUNCTION': 'util.memcache.safe_key'
'KEY_PREFIX': 'sandbox'
'LOCATION': [ 'localhost:11211' ]
'staticfiles':
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
'KEY_FUNCTION': 'util.memcache.safe_key'
'KEY_PREFIX': 'sandbox'
'LOCATION': [ 'localhost:11211' ]
'celery':
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
'KEY_FUNCTION': 'util.memcache.safe_key'
'KEY_PREFIX': 'sandbox'
'LOCATION': [ 'localhost:11211' ]
'CELERY_BROKER_TRANSPORT': 'amqp'
'CELERY_BROKER_HOSTNAME': ''
'COMMENTS_SERVICE_URL': ''
'LOGGING_ENV': 'sandbox'
'SESSION_COOKIE_DOMAIN': !!null
'COMMENTS_SERVICE_KEY': ''
lms_auth_config:
<<: *generic_auth
lms_env_config:
<<: *generic_env
lms_xml_auth_config:
<<: *generic_auth
lms_xml_env_config:
<<: *generic_env
cms_auth_config:
<<: *generic_auth
cms_env_config:
<<: *generic_env
lms_preview_auth_config:
<<: *generic_auth
lms_preview_env_config:
<<: *generic_env
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment