Changeset - 5b1624335e63
[Not reviewed]
0 1 0
Branko Majic (branko) - 8 years ago 2015-10-25 18:29:14
branko@majic.rs
MAR-18: Updated the usage instructions to include a full example for deploying a PHP application (including database). Picked The Bug Genie for this purpose. Fixed some http links.
1 file changed with 232 insertions and 2 deletions:
0 comments (0 inline, 0 general)
docs/usage.rst
Show inline comments
 
@@ -152,7 +152,7 @@ First of all, let's set-up some basic directory structure and configuration:
 

	
 
     [defaults]
 

	
 
     roles_path=/home/ansible/majic-ansible-roles/roles
 
     roles_path=/home/ansible/majic-ansible-roles/roles:/home/ansible/mysite/roles
 
     force_handlers = True
 
     retry_files_save_path = /home/ansible/mysite/retry
 
     inventory = /home/ansible/mysite/hosts
 
@@ -1042,7 +1042,7 @@ Nginx on the server.
 
     ansible-playbook playbooks/site.yml
 

	
 
5. If no errors have been reported, at this point you should have a default web
 
   page available and visible at `https://www.example.com/`. Feel free to try it
 
   page available and visible at https://www.example.com/. Feel free to try it
 
   out with some browser. Keep in mind you will get a warning about the
 
   untrusted certificate!
 

	
 
@@ -1092,3 +1092,233 @@ server.
 
   Of course, no database has been created for either of the web applications,
 
   but we will get to that one later (there is a dedicated ``database`` role
 
   which can be combined with web app roles for this purpose).
 

	
 

	
 
Deploying a PHP web application (The Bug Genie)
 
-----------------------------------------------
 

	
 
We have some basic infrastructure up and running now on our web server, so we
 
shall move on to setting-up a PHP web application on it. As mentioned before, we
 
will take The Bug Genie as an example.
 

	
 
For this we will create a local role in our site to take care of it. This role
 
will in turn utilise two roles coming from *Majic Ansible Roles* that will make
 
our life (a little) easier.
 

	
 
To make the example a bit simpler, no parameters will be introducd to this role
 
(not even the password for database etc).
 

	
 
Here is also a couple of useful pointers regarding the ``php_website`` role
 
we'll be using for the PHP part:
 

	
 
* 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``.
 
* 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
 
  application's group. In other words, all directories will have ``SGID`` bit
 
  set-up, allowing you to create files/directories that will have their group
 
  automatically set to the group of the parent directory.
 
* Combination of admin user membership in application group, ``SGID``
 
  permission, and the way ownership of sub-directories is set-up usually means
 
  that the administrator will be capable of managing application files, and
 
  application can be granted write permissions to a *minimum* of necessary
 
  files.
 

	
 
  .. warning::
 
     Just keep in mind that some file-management commands, like ``mv``, do *not*
 
     respect the ``SGID`` bit. In fact, I would recommend using ``cp`` when you
 
     deploy new files to the directory instead (don't simply move them from your
 
     home).
 

	
 
1. Start-off with creating the necessary directories for the new role::
 

	
 
     mkdir -p ~/mysite/roles/tbg/{tasks,meta,files}/
 

	
 
2. Let's set-up role dependencies, reusing some common roles to make our life
 
   easier.
 

	
 
   :file:`~/mysite/roles/tbg/meta/main.yml`::
 

	
 
      ---
 

	
 
      dependencies:
 
         # 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.
 
           admin: admin
 
           # This will set-up a new virtual host for our app.
 
           fqdn: tbg.example.com
 
           # Some additional packages are required in order to deploy and use TBG.
 
           packages:
 
              - php5-gd
 
              - php5-curl
 
              - git
 
              - php5-mysql
 
              - expect
 
           # Set-up URL rewriting. This is based on public/.htaccess file from
 
           # TBG.
 
           php_rewrite_urls:
 
              - ^(.*)$ /index.php?url=$1
 
           # We don't necessarily need this, but in case you have a policy on
 
           # uid/gid usage, this is useful. Take note that below value is used
 
           # for both the dedicated uid and gid for application user.
 
           uid: 2000
 
         # And this role sets up a new dedicated database for our web
 
         # application.
 
         - role: database
 
           # This is both the database name, _and_ name of the database user
 
           # that will be granted full privileges on the database.
 
           db_name: tbg
 
           # This will be the password of our user 'tbg' to access the
 
           # database. Take note the user can only login from localhost.
 
           db_password: tbg
 

	
 
3. Now for my favourite part again - creating private keys certificates! Why?
 
   Because the ``php_website`` role requires a private key/certificate pair to
 
   be deployed. So... Moving on:
 

	
 
   1. Create new template for ``certtool``:
 

	
 
      :file:`~/mysite/tls/tbg.example.com_https.cfg`::
 

	
 
         organization = "Example Inc."
 
         country = SE
 
         cn = "Exampe Inc. Issue Tracker"
 
         expiration_days = 365
 
         dns_name = "tbg.example.com"
 
         tls_www_server
 
         signing_key
 
         encryption_key
 

	
 
   2. Create the keys and certificates for the application::
 

	
 
        certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/tbg.example.com_https.key
 
        certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/tbg.example.com_https.cfg --load-privkey ~/mysite/tls/tbg.example.com_https.key --outfile ~/mysite/tls/tbg.example.com_https.pem
 

	
 
4. Time to get our hands a bit more dirty... Up until now we didn't have to write
 
   custom tasks, but at this point we need to.
 

	
 
   :file:`~/mysite/roles/tbg/tasks/main.yml`::
 

	
 
      ---
 

	
 
      - name: Define TBG version
 
        set_fact: tbg_version=4.1.0
 

	
 
      - name: Download the TBG archive
 
        get_url: url=https://github.com/thebuggenie/thebuggenie/archive/v{{ tbg_version }}.tar.gz
 
                 dest="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}.tar.gz"
 
                 sha256sum=0fd0a680ba281adc97d5d2c720e63b995225c99716a36eca6a198b8a5ebf8057
 
        become: yes
 
        become_user: admin
 

	
 
      - name: Download Composer
 
        get_url: url=https://getcomposer.org/download/1.0.0-alpha10/composer.phar
 
                 dest="/usr/local/bin/composer"
 
                 sha256sum=9f2c7d0364bc743bcde9cfe1fe84749e5ac38c46d47cf42966ce499135fd4628
 
                 owner=root group=root mode=755
 

	
 
      - name: Unpack TBG
 
        unarchive: src="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}.tar.gz"
 
                   dest="/var/www/tbg.example.com/" copy=no
 
                   creates="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}"
 
        become: yes
 
        become_user: admin
 

	
 
      - 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
 

	
 
      - name: Set-up writeable directories for TBG install
 
        file: path="{{ item }}" mode=g+w
 
        with_items:
 
           - /var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/
 
           - /var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/public/
 
           - /var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/core/config/
 

	
 
      - name: Create symbolic link to TBG application
 
        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
 
        become: yes
 
        become_user: admin
 

	
 
      - name: Install TBG dependencies
 
        composer: command=install working_dir="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}"
 
        become: yes
 
        become_user: admin
 

	
 
      - 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 group=web-tbg_example_com
 
        become: yes
 
        become_user: admin
 

	
 
      - 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
 

	
 
      - 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
 

	
 
5. Set-up the files that are deployed via task above.
 

	
 
   :file:`~/mysite/roles/tbg/files/b2db.yml`::
 

	
 
      b2db:
 
          username: "tbg"
 
          password: "tbg"
 
          dsn: "mysql:host=localhost;dbname=tbg"
 
          tableprefix: ''
 
          cacheclass: '\thebuggenie\core\framework\Cache'
 

	
 
   :file:`~/mysite/roles/tbg/files/tbg_expect_install`::
 

	
 
      #!/usr/bin/expect
 

	
 
      spawn ./tbg_cli install --accept_license=yes --url_subdir=/ --use_existing_db_info=yes --enable_all_modules=yes --setup_htaccess=yes
 

	
 
      expect "Press ENTER to continue with the installation: "
 
      send "\r"
 
      expect "Press ENTER to continue: "
 
      send "\r"
 
      interact
 

	
 
6. And... Let's add the new role to our web server.
 

	
 
   :file:`~/mysite/playbooks/web.yml`::
 

	
 
      ---
 
      - hosts: web
 
        remote_user: ansible
 
        sudo: yes
 
        roles:
 
          - common
 
          - ldap_client
 
          - mail_forwarder
 
          - web_server
 
          - database_server
 
          - tbg
 

	
 
7. Apply the changes::
 

	
 
     ansible-playbook playbooks/site.yml
 

	
 
8. At this point TBG has been installed, and you should be able to open the URL
 
   https://tbg.example.com/ (or http://tbg.example.com/) and log-in into
 
   *The Bug Genie* with username ``administrator`` and password ``admin``.
0 comments (0 inline, 0 general)