phpmyadmin_elasticbeanstalk

Install PHPMyAdmin in ElasticBeanstalk

I’ve been working with Elastic Beanstalk for a while now (I use it for this site) and I’ve always been impressed at how easy it makes creating test or development environments. So, when my brother started his own digital agency business, Kroochma, I recommended that he look at the Elastic Beanstalk platform. While it may not be the cheapest hosting solution, it’s simple enough to use and provides a lot of flexibility in how your hosting environments are configured.

One of the questions he’s asked me about Elastic Beanstalk is how to give developers access to the RDS instances created by the service. As the projects in question are PHP-based, we decided to set up phpMyAdmin on certain environments by using an custom .ebextensions file.

The major pre-requisite to using this file is that you’re running an application on an Elastic Beanstalk server that has PHP installed (e.g. any of the Amazon Linux platforms running PHP). If you’re using something else (Ruby, NodeJS, etc.), you might be able to re-purpose this, but you’ll need to add a packages section to ensure PHP gets installed.

Because I didn’t want this to be a mandatory addition to all environments, it’s possible to configure how the extension works using the following 3 environment variables, which you can set in your Elastic Beanstalk application:

  • PMA_VER – version of phpMyAdmin to install. If it’s not set, then the installation won’t happen; great for when you don’t want to set up phpMyAdmin for an environment.
  • PMA_USERNAME – username for HTTP authentication, if this isn’t set, you won’t have access to phpMyAdmin.
  • PMA_PASSWORD – password for HTTP authentication.

Assuming the above environment variables are set correctly, the extension will deploy phpMyAdmin with the database connection pre-configured using the $RDS_HOSTNAME, $RDS_USERNAME and $RDS_PASSWORD environment variables. Access to the software itself is possible by visiting the /db_admin path on your domain (e.g. http://example.com/db_admin), which is restricted by basic HTTP Auth. Ideally you’ll want to be using HTTPS for your site.

container_commands:
  01_install_pma:
    test: test -n "$PMA_VER" && test ! -f /tmp/phpmyadmin.tar.gz
    command: |
      cd /tmp
      wget https://files.phpmyadmin.net/phpMyAdmin/${PMA_VER}/phpMyAdmin-${PMA_VER}-all-languages.tar.gz
      wget https://files.phpmyadmin.net/phpMyAdmin/${PMA_VER}/phpMyAdmin-${PMA_VER}-all-languages.tar.gz.sha1
      cd /tmp && sha1sum --check phpMyAdmin-${PMA_VER}-all-languages.tar.gz.sha1
      if [[ $? == 0 ]]
      then
        cd /opt/ && tar xzf /tmp/phpMyAdmin-${PMA_VER}-all-languages.tar.gz && ln -s phpMyAdmin-${PMA_VER}-all-languages phpmyadmin
      else
        exit 1
      fi
      exit 0
 
  02_create_config_file:
    test: test ! -f /opt/phpmyadmin/config.inc.php
    command: cd /opt/phpmyadmin && cp config.sample.inc.php config.inc.php
 
  03_change_auth_type:
    test: test -f /opt/phpmyadmin/config.inc.php
    command: sed -i "s/'cookie'/\'config'/g" /opt/phpmyadmin/config.inc.php
 
  04_configure_db_host:
    test: test -f /opt/phpmyadmin/config.inc.php
    command: sed -i "s/'localhost'/\$_SERVER['RDS_HOSTNAME']/g" /opt/phpmyadmin/config.inc.php
 
  05_config_db_credentials:
     command: |
      grep -q "RDS_USERNAME" /opt/phpmyadmin/config.inc.php || sed -i "/RDS_HOSTNAME/i \
        \$cfg['Servers'][\$i]['user'] = \$_SERVER['RDS_USERNAME'];\n\$cfg['Servers'][\$i]['password'] = \$_SERVER['RDS_PASSWORD'];" /opt/phpmyadmin/config.inc.php
 
  06_configure_htauth:
    test: test -n "$PMA_USERNAME" && test -n "$PMA_PASSWORD"
    command: |
      if [[ -f /etc/httpd/htpasswd ]]
      then
        htpasswd -b /etc/httpd/htpasswd $PMA_USERNAME $PMA_PASSWORD
      else
        htpasswd -cb /etc/httpd/htpasswd $PMA_USERNAME $PMA_PASSWORD
      fi
 
files:
  "/etc/httpd/conf.d/pma.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      Alias /db_admin /opt/phpmyadmin
      <Directory /opt/phpmyadmin>
        AuthType Basic
        AuthName "Restricted Files"
        AuthBasicProvider file
        AuthUserFile "/etc/httpd/htpasswd"
        Require valid-user
        Options FollowSymLinks
      </Directory>
      <Directory /opt/phpmyadmin/libraries/>
        Require all denied
      </Directory>
      <Directory /opt/phpmyadmin/setup/lib/>
        Require all denied
      </Directory>
      <Directory /opt/phpmyadmin/setup/frames/>
        Require all denied
      </Directory>

It’s not perfect by any means, but it gets the job done. I do find the syntax for the Elastic Beanstalk customisation files to be a bit messy for more complex tasks, and I’d like to make the Apache config file be conditionally deployed, but I can tweak it later.