From 3af07319e2f3594db13e01c717453b0da00c572a 2016-06-14 17:28:35 From: Branko Majic Date: 2016-06-14 17:28:35 Subject: [PATCH] MAR-59: Removed ability to specify admin user for php_website and wsgi_website roles. Updated testsite and usage instructions. Updated role reference. --- diff --git a/docs/rolereference.rst b/docs/rolereference.rst index c47623001dc4d6cac995935c66b757847d139793..2c89f31ccb64b159b0d7503596abe15ee056c46e 100644 --- a/docs/rolereference.rst +++ b/docs/rolereference.rst @@ -1173,6 +1173,7 @@ reducing the workload. The role implements the following: * Creates a dedicated user/group for running the PHP scripts. +* Creates a dedicated administrator user for maintaining the website. * Creates a base directory where the website-specific code and data should be stored at. * Adds nginx to website's group, so nginx could read the necessary files. @@ -1188,6 +1189,10 @@ The role is implemented with the following layout/logic in mind: website, in format of ``web-ESCAPEDFQDN``, where ``ESCAPEDFQDN`` is equal to ``FQDN`` where dots have been replaced by underscores (for example, ``web-cloud_example_com``). +* Administrator users are named after the ``FQDN`` (fully qualified domain name) + of website, in format of ``admin-ESCAPEDFQDN``, where ``ESCAPEDFQDN`` is equal + to ``FQDN`` where dots have been replaced by underscores (for example, + ``admin-cloud_example_com``). * All websites reside within a dedicated sub-directory in ``/var/www``. The sub-directory name is equal to the ``FQDN`` used for accessing the website. Owner of the directory is set to be the application administrator, @@ -1229,10 +1234,9 @@ Parameters **value** (string, mandatory) Configuration option. -**admin** (string, optional, ``web-{{ fqdn | replace('.', '_') }}``) - Name of the operating system user in charge of maintaining the website. This - user is capable of making modifications to website configuration and data - stored within the website directory. +**admin_uid** (integer, optional, ``whatever OS picks``) + UID of the dedicated website administrator user. The user will be member of + website group. **deny_files_regex** (list, optional, ``[]``) List of regular expressions for matching files/locations to which the web @@ -1301,7 +1305,6 @@ running *ownCloud* and *The Bug Genie* applications): - role: php_website fqdn: cloud.example.com uid: 2001 - admin: admin php_file_regex: \.php($|/) rewrites: - ^/\.well-known/host-meta /public.php?service=host-meta @@ -1327,7 +1330,6 @@ running *ownCloud* and *The Bug Genie* applications): - comment: Use custom page for non-existing locations/files. value: error_page 404 /core/templates/404.php; - role: php_website - admin: admin deny_files_regex: - ^\..* php_rewrite_urls: @@ -1354,6 +1356,7 @@ common base and reducing the workload. The role implements the following: * Creates a dedicated user/group for running the WSGI application. +* Creates a dedicated administrator user for maintaining the website. * Creates a base directory where the website-specific code and data should be stored at. * Adds nginx to website's group, so nginx could read the necessary files. @@ -1377,6 +1380,10 @@ The role is implemented with the following layout/logic in mind: website, in format of ``web-ESCAPEDFQDN``, where ``ESCAPEDFQDN`` is equal to ``FQDN`` where dots have been replaced by underscores (for example, ``web-wiki_example_com``). +* Administrator users are named after the ``FQDN`` (fully qualified domain name) + of website, in format of ``admin-ESCAPEDFQDN``, where ``ESCAPEDFQDN`` is equal + to ``FQDN`` where dots have been replaced by underscores (for example, + ``admin-cloud_example_com``). * All websites reside within a dedicated sub-directory in ``/var/www``. The sub-directory name is equal to the ``FQDN`` used for accessing the website. Owner of the directory is set to be the application administrator, @@ -1388,9 +1395,8 @@ The role is implemented with the following layout/logic in mind: directly, or copied to the directory in order to make sure the ``SGID`` gets honored. **Do not move the files, the permissions will not be set correctly.** * Within the website directory, Python virtual environment can be found within - the ``virtualenv`` sub-directory. The virtual environment is also symlinked to - website admin's ``~/.virtualenvs/`` directory for easier access (and - auto-completion with virtualenvwrapper). + the ``virtualenv`` sub-directory. Switching to administrator user via login + shell will automatically activate the virtual environment. * Within the website directory, nginx will expect to find the static files within the ``htdocs`` sub-directory (this can be symlink too). Locations/aliases can be configured for static file serving. @@ -1426,10 +1432,9 @@ Parameters **value** (string, mandatory) Configuration option. -**admin** (string, optional, ``web-{{ fqdn | replace('.', '_') }}``) - Name of the operating system user in charge of maintaining the website. This - user is capable of making modifications to website configuration anda data - stored within the website directory. +**admin_uid** (integer, optional, ``whatever OS picks``) + UID of the dedicated website administrator user. The user will be member of + website group. **enforce_https** (boolean, optional, ``True``) Specify if HTTPS should be enforced for the website or not. If enforced, @@ -1503,7 +1508,6 @@ running a bare Django project): .. code-block:: yaml - role: wsgi_website - admin: admin fqdn: django.example.com static_locations: - /static diff --git a/docs/usage.rst b/docs/usage.rst index 85a89a32e7363f2556568dd69908333c4a6698ac..8dc0e1893806f5d7c3f4d0be3ad5b6d4c9d0e3a2 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1213,11 +1213,13 @@ Before we start, here is a couple of useful pointers regarding the * The role is designed to execute every application via dedicated user and group. The user/group name is automatically derived from the FQDN of website, for example ``web-tbg_example_com``. +* An administrative user is created as well, and this user should be used when + running maintenance and installation commands. Similar to application user, + the name is also derived from the FQDN of website, for example + ``admin-tbg_example_com``. Administrative user does not have a dedicated + group, and instead belongs to same group as the application user. * PHP applications are executed via FastCGI, using the ``php5-fpm`` package. * Static content (non-PHP) is served directly by *Nginx*. -* For administrative purposes you can use a separate user that you have created - before (for example via the ``common`` role). This user will get added to - application's group. * Each web application gets distinct sub-directory under ``/var/www``, named after the FQDN. All sub-directories created under there are created with ``2750`` permissions, with ownership set to admin user, and group set to the @@ -1257,11 +1259,6 @@ Before we start, here is a couple of useful pointers regarding the # Ok, so this role helps us set-up Nginx virtual host for serving our # app. - role: php_website - # We shall let our admin account be able to read/write files - # belonging to the application. This allows us to use regular user - # (admin in this case) without sudo for managing and accessing - # application files. - admin: admin # Our virtual host will for PHP website will respond to this name. fqdn: tbg.example.com # Some additional packages are required in order to deploy and use TBG. @@ -1328,7 +1325,7 @@ Before we start, here is a couple of useful pointers regarding the dest="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}.tar.gz" sha256sum=0fd0a680ba281adc97d5d2c720e63b995225c99716a36eca6a198b8a5ebf8057 become: yes - become_user: admin + become_user: admin-tbg_example_com - name: Download Composer get_url: url=https://getcomposer.org/download/1.0.0-alpha10/composer.phar @@ -1341,12 +1338,12 @@ Before we start, here is a couple of useful pointers regarding the dest="/var/www/tbg.example.com/" copy=no creates="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}" become: yes - become_user: admin + become_user: admin-tbg_example_com - name: Create TBG cache directory file: path="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/cache" state=directory mode=2770 become: yes - become_user: admin + become_user: admin-tbg_example_com - name: Set-up the necessary write permissions for TBG directories file: path="{{ item }}" mode=g+w @@ -1359,30 +1356,30 @@ Before we start, here is a couple of useful pointers regarding the file: src="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/public" path="/var/www/tbg.example.com/htdocs" state=link - owner="admin" group="web-tbg_example_com" mode=2750 + owner="admin-tbg_example_com" group="web-tbg_example_com" mode=2750 become: yes - become_user: admin + become_user: admin-tbg_example_com - name: Install TBG dependencies composer: command=install working_dir="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}" become: yes - become_user: admin + become_user: admin-tbg_example_com - name: Deploy database configuration file for TBG copy: src="b2db.yml" dest="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/core/config/b2db.yml" - mode=640 owner=admin group=web-tbg_example_com + mode=640 owner=admin-tbg_example_com group=web-tbg_example_com - name: Deploy expect script for installing TBG copy: src="tbg_expect_install" dest="/var/www/tbg.example.com/tbg_expect_install" mode=750 become: yes - become_user: admin + become_user: admin-tbg_example_com - name: Run TBG installer via expect script command: /var/www/tbg.example.com/tbg_expect_install chdir=/var/www/tbg.example.com/thebuggenie-{{ tbg_version }} creates=/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/installed become: yes - become_user: admin + become_user: admin-tbg_example_com 5. Set-up the files that are deployed by our role. @@ -1452,14 +1449,16 @@ on the safe side: * The role is designed to execute every application via dedicated user and group. The user/group name is automatically derived from the FQDN of website, for example ``web-wiki_example_com``. +* An administrative user is created as well, and this user should be used when + running maintenance and installation commands. Similar to application user, + the name is also derived from the FQDN of website, for example + ``admin-wiki_example_com``. Administrative user does not have a dedicated + group, and instead belongs to same group as the application user. As + convenience, whenever you switch to this user the Python virtual environment + will be automatically activated for you. * WSGI applications are executed via *Gunicorn*. The WSGI server listens on a Unix socket, making the socket accessible by *Nginx*. * Static content is served directly by *Nginx*. -* For administrative purposes you can use a separate user that you have created - before (for example via the ``common`` role). This user will get added to - application's group. The administrator will also be able to switch to website - virtual environment using the ``workon`` command from ``virtualenv-wrapper`` - package. * Each web application gets distinct sub-directory under ``/var/www``, named after the FQDN. All sub-directories created under there are created with ``2750`` permissions, with ownership set to admin user, and group set to the @@ -1499,7 +1498,6 @@ on the safe side: dependencies: - role: wsgi_website - admin: admin fqdn: wiki.example.com # In many cases you need to have some development packages available # in order to build Python packages installed via pip @@ -1570,7 +1568,7 @@ on the safe side: - name: Create Django project directory file: dest="/var/www/wiki.example.com/code" state=directory - owner=admin group=web-wiki_example_com + owner=admin-wiki_example_com group=web-wiki_example_com mode=2750 - name: Start Django project for the Wiki website @@ -1578,7 +1576,7 @@ on the safe side: chdir=/var/www/wiki.example.com creates=/var/www/wiki.example.com/code/wiki_example_com become: yes - become_user: admin + become_user: admin-wiki_example_com - name: Deploy settings for wiki website copy: src="{{ item }}" dest="/var/www/wiki.example.com/code/wiki_example_com/{{ item }}" @@ -1594,7 +1592,7 @@ on the safe side: app_path="/var/www/wiki.example.com/code/" virtualenv="/var/www/wiki.example.com/virtualenv/" become: yes - become_user: admin + become_user: admin-wiki_example_com with_items: - syncdb - migrate @@ -1602,13 +1600,13 @@ on the safe side: - name: Deploy the superadmin creation script copy: src="create_superadmin.py" dest="/var/www/wiki.example.com/code/create_superadmin.py" - owner=admin group=web-wiki_example_com mode=750 + owner=admin-wiki_example_com group=web-wiki_example_com mode=750 - name: Create initial superuser command: /var/www/wiki.example.com/virtualenv/bin/exec ./create_superadmin.py chdir=/var/www/wiki.example.com/code/ become: yes - become_user: admin + become_user: admin-wiki_example_com register: wiki_superuser changed_when: wiki_superuser.stdout == "Created superuser." diff --git a/roles/php_website/defaults/main.yml b/roles/php_website/defaults/main.yml index aa7686c08c1ee0ddff9534ce29fa3cd8e5061c70..52ed524d1820f842f12da62921c41a6009c1af3e 100644 --- a/roles/php_website/defaults/main.yml +++ b/roles/php_website/defaults/main.yml @@ -8,6 +8,5 @@ packages: [] php_file_regex: \.php$ php_rewrite_urls: [] rewrites: [] -admin: "web-{{ fqdn | replace('.', '_') }}" https_tls_certificate: "{{ lookup('file', tls_certificate_dir + '/' + fqdn + '_https.pem') }}" https_tls_key: "{{ lookup('file', tls_private_key_dir + '/' + fqdn + '_https.key') }}" diff --git a/roles/php_website/tasks/main.yml b/roles/php_website/tasks/main.yml index 9d34ef482b7316ab65314f5abbf797a2fb3e81b5..056ab2772f4d58e5cf76637ea388385d3613bb81 100644 --- a/roles/php_website/tasks/main.yml +++ b/roles/php_website/tasks/main.yml @@ -2,12 +2,17 @@ - name: Calculate username and home set_fact: + admin: "admin-{{ fqdn | replace('.', '_') }}" user: "web-{{ fqdn | replace('.', '_') }}" home: "/var/www/{{ fqdn }}" - name: Create PHP website group group: name="{{ user }}" gid="{{ uid | default(omit) }}" state=present +- name: Create PHP website admin user + user: name="{{ admin }}" uid="{{ admin_uid | default(omit) }}" group="{{ user }}" + shell=/bin/bash createhome=no home="{{ home }}" state=present + - name: Create home directory for the user (avoid populating with skeleton) file: path="{{ home }}" state=directory owner="{{ admin }}" group="{{ user }}" mode=2750 diff --git a/roles/wsgi_website/files/bashrc b/roles/wsgi_website/files/bashrc new file mode 100644 index 0000000000000000000000000000000000000000..793fe112ed64b50eea3f36b234f2a59334484e12 --- /dev/null +++ b/roles/wsgi_website/files/bashrc @@ -0,0 +1,2 @@ +# Activate the virtual environment. +. "$HOME/virtualenv/bin/activate" \ No newline at end of file diff --git a/roles/wsgi_website/tasks/main.yml b/roles/wsgi_website/tasks/main.yml index 69c37af9c1abd13cf09a9ebe96f8b9fb6c279a94..317f56550c4b8d07364e04819c5c6a355b78d2d9 100644 --- a/roles/wsgi_website/tasks/main.yml +++ b/roles/wsgi_website/tasks/main.yml @@ -1,12 +1,17 @@ --- - set_fact: + admin: "admin-{{ fqdn | replace('.', '_') }}" user: "web-{{ fqdn | replace('.', '_') }}" home: "/var/www/{{ fqdn }}" - name: Create WSGI website group group: name="{{ user }}" gid="{{ uid | default(omit) }}" state=present +- name: Create WSGI website admin user + user: name="{{ admin }}" uid="{{ admin_uid | default(omit) }}" group="{{ user }}" + shell=/bin/bash createhome=no home="{{ home }}" state=present + - name: Create home directory for the user (avoid populating with skeleton) file: path="{{ home }}" state=directory owner="{{ admin }}" group="{{ user }}" mode=2750 @@ -39,18 +44,17 @@ template: src="venv_project.j2" dest="{{ home }}/virtualenv/.project" owner="{{ admin }}" group="{{ user }}" mode="640" -- name: Create directory where virtualenvs will be symlinked to - become_user: "{{ admin }}" - file: path="~/.virtualenvs" state=directory mode=750 - -- name: Create convenience symlink for Python virtual environment wrapper utility - become_user: "{{ admin }}" - file: src="{{ home }}/virtualenv" dest="~/.virtualenvs/{{ fqdn }}" state=link - - name: Deploy virtualenv wrapper template: src="venv_exec.j2" dest="{{ home }}/virtualenv/bin/exec" owner="{{ admin }}" group="{{ user }}" mode="750" +- name: Deploy minimalistic bashrc for auto-activating the virtual environment + copy: src="bashrc" dest="{{ item }}" + owner="root" group="{{ user }}" mode="640" + with_items: + - "{{ home }}/.bashrc" + - "{{ home }}/.profile" + - name: Install futures package for use with Gunicorn thread workers become_user: "{{ admin }}" pip: name=futures version="{{ futures_version }}" state=present virtualenv="{{ home }}/virtualenv" diff --git a/testsite/playbooks/roles/phpinfo/meta/main.yml b/testsite/playbooks/roles/phpinfo/meta/main.yml index 2a7b20c0e8c129fc88798cac037c144171abd3f0..8d33d615d13e466a9c4a025e880f2e0789db85d9 100644 --- a/testsite/playbooks/roles/phpinfo/meta/main.yml +++ b/testsite/playbooks/roles/phpinfo/meta/main.yml @@ -2,10 +2,10 @@ dependencies: - role: php_website - admin: admin fqdn: phpinfo.{{ testsite_domain }} php_rewrite_urls: - ^(.*) /index.php + admin_uid: 3000 uid: 2000 enforce_https: False https_tls_key: "{{ lookup('file', inventory_dir + '/tls/phpinfo.' + testsite_domain + '_https.key') }}" diff --git a/testsite/playbooks/roles/wsgihello/meta/main.yml b/testsite/playbooks/roles/wsgihello/meta/main.yml index de254e21d6daa42438cb3bd2d8288f4b99803fd0..9d227cce900869db714d454fab06841c564b13ee 100644 --- a/testsite/playbooks/roles/wsgihello/meta/main.yml +++ b/testsite/playbooks/roles/wsgihello/meta/main.yml @@ -4,6 +4,7 @@ dependencies: - role: wsgi_website admin: admin fqdn: wsgi.{{ testsite_domain }} + admin_uid: 3001 uid: 2001 wsgi_application: wsgi:application static_locations: