Amazon Elastic Beanstalk & DynamoDB

Permalink 2 users found helpful
Just wondering if anyone has ever tried to deploy Concrete5 (5.6.3.3) on Amazon's Elastic Beanstalk service? I am having horrible issues with PHP sessions which don't last more than 3-4 minutes. I have sessions setup to use dynamoDB (some included code in index.php) and I can see the session data going into dynamo OK. Caches are off (except overrides), sticky load balancing is off (but there's only one instance behind the load balancer anyway) and PHP and dynamo are set to have a session lifetime of 4 hours (14400 seconds). I can see the browser sending the session cookies back, but even though they're still showing and current in dynamo, they're getting ignored.

I have a simple piece of test code that runs outside of C5, sets up the session and then writes/reads the current time into a session array variable. This works without error, retrieving the previous values with no problem.

Since the AWS setup is in fact a reverse proxy, I am wondering if there are any cache headers that C5 might be sending that are causing the load balancer to not forward the requests, but to serve the request from its cache.

jero
 
jero replied on at Permalink Best Answer Reply
jero
I figured it out. The AWS load balancer changes the IP address presented to the webserver (it's always a 172.x.x.x address, not the external real world IP) periodically, so the session fixation check in concrete/startup/session.php empties the session and regenerates it. Commenting out this code fixes the problem.
goldfish replied on at Permalink Reply
goldfish
The AWS Elastic Load Balancer will pass along the user's IP as $_SERVER['HTTP_X_FORWARDED_FOR'] so you can modify session.php to use that instead.

How have you found performance to be on Elastic Beanstalk? I tried to set up a C5 install using an EC2 instance with the database on an RDS instance and found the latency between the two instances resulted in unacceptably slow performance. Running MySQL on the EC2 instance solved the problem.
jero replied on at Permalink Reply
jero
That's a thought - yeah, I might just do that. Thanks.

I actually thought the performance was quite snappy, to be honest - at least as good as my regular hosting platform which uses a localhost mysql. Maybe it's an availability zone thing. All my zones are in Sydney, which is closest to me.
misterbethel replied on at Permalink Reply
misterbethel
I'm glad there are others exploring using Elastic Beanstalk for C5. I used it three years ago for a short while and gave up. To many hurdles to jump. Just tried to give it another shot and ran into the same problem as Jero had with sessions.

I did run into the slow RDS problem. You just have to make sure your instances and RDS are in the same Availability Zone. I like to set up my own RDS instead of going through EB, and it takes an extra step to make sure they are the same.
Gyja replied on at Permalink Reply
Hi,
Would you be able to share the session management configuration to use DynamoDB as the session management. I am just starting with Concrete5 and would like to save some time ;)

Many thanks

Jason
jero replied on at Permalink Reply
jero
Yes sure. It's probably a bit of a hack, but like all good hacks, it works. Basically I altered index.php like so:

<?php
require 'aws/aws-autoloader.php';
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Session\SessionHandler;
$dynamoDb = DynamoDbClient::factory(array(
    'region' => 'ap-southeast-2',
     'credentials' => array(
     'key' => 'ZZZZZZZZZZZ, // These are also defined as AWSKEY and AWSSECRET in config/site.php
     'secret' => 'SSSSSSSSSSS' // but we need them here too before the file is loaded
     )
));
$sessionHandler = SessionHandler::factory(array(
     'session_lifetime' => 7200, // 2 hours
    'dynamodb_client' => $dynamoDb,
     'table_name' => 'sessions',


The AWS SDK for PHP can be found somewhere on Amazon's website - I recall it took a while to find the right bits, and IIRC correctly it requires composer to get it configured correctly. I can't quite remember.

You will also need a scheduled job to kill off old session files, or kill them off by some other means

<?php defined('C5_EXECUTE') or die("Access Denied.");
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Session\SessionHandler;
class Dynamo extends Job {
        public function getJobName () {
                return t("Clear Dynamo Sessions");
        }
        public function getJobDescription () {
                return t("Run the DynamoDB Garbage Collection Process");
        }
        public function run () {
                $dynamoDb = DynamoDbClient::factory(array(
                        'region' => 'ap-southeast-2',
                        'credentials' => array(
                                'key' => AWSKEY,
Gyja replied on at Permalink Reply
Thank you for the great response.

I cant help noticing that there are a number of references to apk keys in the code.

How about using Roles to spin up the instance that would have the correct access to the resources (DynamoDB) to achieve the same result?

This would also result in a more secure enviromment as there is no API key to gain should there be an unwelcome visitor :)

Thanks for all your help so far
jero replied on at Permalink Reply
jero
You're probably right. But like I said, it's a hack but it works. Hopefully it gets you on the right lines.
Gyja replied on at Permalink Reply
Thank you for the great response.

I cant help noticing that there are a number of references to apk keys in the code.

How about using Roles to spin up the instance that would have the correct access to the resources (DynamoDB) to achieve the same result?

This would also result in a more secure enviromment as there is no API key to gain should there be an unwelcome visitor :)

Thanks for all your help so far