2
\$\begingroup\$

I have a project which we need to migrate from an on-prem solution to the AWS cloud. Currently, the software is running on a single instance. It's working fine but the business want the software to be Highly Available (HA). As part of the HA, the program will be installed on a shared file system (AWS EFS) and mount the filesystem on the multiple EC2 instances so that the same configuration accessed by all the instances.

The challenge for me is

PHP_ETC_BASE=/etc/php/7.0
PHP_INI=${PHP_ETC_BASE}/apache2/php.ini

I can install PHP on all the AWS EC2 instances (PHP_ETC_BASE) but the PHP_INI need to be on a shared file system so that the configuration can be accessed by other instances. What I read is that I cant move /etc/php/7.0 to a shared filesystem then PHP wont work

  installDepsPhp70 () {
  debug "Installing PHP 7.0 dependencies"
  PHP_ETC_BASE=/etc/php/7.0
  PHP_INI=${PHP_ETC_BASE}/apache2/php.ini
  checkAptLock
  sudo apt install -qy \
  libapache2-mod-php \
  php php-cli \
  php-dev \
  php-json php-xml php-mysql php-opcache php-readline php-mbstring php-zip \
  php-redis php-gnupg \
  php-gd

  for key in upload_max_filesize post_max_size max_execution_time max_input_time memory_limit
  do
      sudo sed -i "s/^\($key\).*/\1 = $(eval echo \${$key})/" $PHP_INI
  done
  sudo sed -i "s/^\(session.sid_length\).*/\1 = $(eval echo \${session0sid_length})/" $PHP_INI
  sudo sed -i "s/^\(session.use_strict_mode\).*/\1 = $(eval echo \${session0use_strict_mode})/" $PHP_INI
}

Similar issue for the /var/lib/mysql

prepareDB () {
  if sudo test ! -e "/var/lib/mysql/mysql/"; then
    #Make sure initial tables are created in MySQL
    debug "Install mysql tables"
    sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
    sudo service mysql start
  fi

  if sudo test ! -e "/var/lib/mysql/misp/"; then
    debug "Start mysql"
    sudo service mysql start
\$\endgroup\$
1
\$\begingroup\$

Consider your system in three parts:

  • Core OS (all files on ec2)
  • Your App (I would keep the core app files on ec2 - reasons below - but your way would work)
  • Data (I would have only "data" on EFS)

Answer Part 1: php.ini lives with the OS.

Reasons:

  • Major: If you want to upgrade to a newer PHP without downtime, you create new EC2s with new OS one at at time and swap them in to your ELB: this can't use the shared php.ini as you propose.
  • Medium: Changes to php.ini won't bite instantly you may need to start http/fcgi to get traction - you still need to visit each server to restart.

Answer Part 2: The actual application files also live on ec2, and only data on EFS.

Reasons:

  • Major: Similar to above, you can update one at a time by swapping servers with new code in.
  • Medium: Security; it's safer to create the application instances and "lock in" the files, than rely on files on EFS that may have been connected to another EC2 by mistake.
  • Medium: Testing: you can attach your EC2s to a different data store / different ELB for testing before connecting to live.
  • Medium: If your EFS fails (it happens!) your application can still respond and say "Sorry - please come back later".
  • Medium: You want to have the EC2 in different AZs so much faster
  • Minor: Slightly faster if they all share the same AZ.
  • Downside: Updating the application is a bigger pain, but you can script this too.

How:

The great news is that you already have this scripted. Split your deploy into slightly smaller stages:

a) Create your BaseAMI (includes the OS, PHP as you have scripted above). This only changes when you do a major OS update.

b) Using your BaseAMI, you can then create a GoldenAMI which has your application on top. (Run minor OS updates at this point to maintain security if your Base AMI is older). This Golden AMI will be near identical for all EC2s

c) Using Auto-Scale Groups (ASG), use GoldenAMI as your base, and tweak if needed using userdata properties of the ASG.

When you release new code, you launch stage (b) and create new GoldenAMI and use that for the ASG. Kill the old servers and the new ones magically appear = no downtime.

If you really need to update php.ini (which will be rare), then start again at stage (a) to build the BaseAMI, then Golden AMI and swap servers in one at at time.

To "cheat" (shortcut) when updating, deploy your application code to S3, have each EC2 check S3 (or notified via SNS when updates happen) and it can pull down the code and self update. But ensure your security is rock-solid tight if you do this (as you would if putting the application code on EFS).


Regarding MySql,

  • you can't share like that at all as files need to be exclusively opened;
  • having data live on a single disk is not "HA";
  • having data live on EFS is slow.

Use the RDS solutions provided by AWS and you can add redundancy to your heart's content (multiple AZs, failovers, backups). It may cost a bit more, but HA will.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks Robbie for your answer. Let me test it and I will let you know. :) \$\endgroup\$ – spectrum Apr 26 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.