Reputation: 375
As usual, the simpler the operation the more AWS documentation confounds me. I want to use PHP to write and read files stored on EFS. I am experienced with using the AWS PHP library, I just need the correct code to facilitate communication. Here's my set up:
Now in the file I normally connect to other services in this manner:
use Aws\S3\S3Client;
$options = [
'region' => 'us-east-1',
'version' => '2006-03-01',
'signature_version' => 'v4',
'credentials' => [
'key' => 'key#',
'secret' => 'secret#'
]
];
$GLOBALS['s3Client'] = new S3Client($options);
$writeFile = $GLOBALS['s3Client']->putObject(array(...
I presume this should be the same for EFS. As a first guess, I tried:
$efsOptions = [
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => 'key#',
'secret' => 'secret#'
]
];
use Aws\Efs\EfsClient;
$efsClient = new EfsClient($efsOptions);
$result = $efsClient->describeFileSystems(array(
'FileSystemId' => 'fs-#'
));
But get an error:
Fatal error: Uncaught exception 'Aws\Efs\Exception\EfsException' with message 'Error executing "DescribeFileSystems" on "https://elasticfilesystem.us-east-1.amazonaws.com/2015-02-01/file-systems?FileSystemId=f#"; AWS HTTP error: Client error: `GET https://elasticfilesystem.us-east-1.amazonaws.com/2015-02-01/file-systems?FileSystemId=f#` resulted in a `403 Forbidden`
So what's the right way to do this? (Sudo Code):
use Aws\efs\EfsClient;
$options = [
'What keys need to be here' => 'paramter',
'credentials' => [
'key' => 'key#',
'secret' => 'sevret#'
]
];
$efsClient = new EfsClient($options);
$dir = "/test/";
$makeDir = $efsClient -> mkdir($dir);
$scanDir = $efsClient -> scandir($dir);
print_r($scanDir);
**/test/
I never use console or connect to the server to install packages so please constrain this to answers that allow me to do everything in the PHP file or a limited "one time" console configuration. The point of this is I need the PHP script to create and read files on EFS and to share those with other EB environments. AWS documentation I've reviewed or used so far:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/services-efs.html https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/instance-configuration/storage-efs-mountfilesystem.config https://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Efs.EfsClient.html
Upvotes: 1
Views: 1716
Reputation: 1071
Why not just mount the EFS as a share on your EC2 instance your code is running on. Then the EFS is just a regular path that your PHP app can write to. That is what we do on our Elastic Beanstalk web servers for persisting user file uploads, etc.
You have to set up the connection from the EB/EC2 instance using the AWS EBExtensions mechanism when the code is deployed. An example configuration snippet for doing that is:
# config.yml file:
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/my_config_job.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
# Load the EFS path from the EB environment settings
# (The variables are set in the "Configuration" section in the AWS
# Console under the "Environment properties" area. That area takes
# Name and Value pairs, so in our example below, the value
# "WHERE_TO_MOUNT_EFS" is the Name of the variable, and it contains
# a path on the EC2, for example "/efs". That would mount the EFS
# volume at the path /efs on the filesystem.
WHERE_TO_MOUNT_EFS=$(/opt/elasticbeanstalk/bin/get-config environment -k WHERE_TO_MOUNT_EFS)
# This is the actual AWS EFS volume name that has been set up
EFS_VOLUME_NAME=$(/opt/elasticbeanstalk/bin/get-config environment -k EFS_VOLUME_NAME)
# Now create the path for the mount on the filesystem (again, in
# our example "/efs" as specified in the WHERE_TO_MOUNT_EFS variable)
mkdir ${WHERE_TO_MOUNT_EFS}
# Now actually mount the EFS to the "/efs" folder created above
mount -t nfs4 -o nfsvers=4.1 ${EFS_VOLUME_NAME}-$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).mydomain.com:/ ${WHERE_TO_MOUNT_EFS}
This is just a sample, of course.
The "curl" commands are used to query information AWS provides at the special IP 169.254.169.154. Your domain and path would be different.
Also, this is a Bash script that runs on Linux. If you are using Windows on your EB you will have to adapt this process.
Finally, after the mount above, in our scripts we actually go on to create a symlink from a subfolder of our website to the EFS folder that was attached. We also manage the permissions with Bash commands that assign the "webapp" user the permissions it needs. Those steps are optional of course.
Now PHP will just see that folder as a path on the filesystem, but in reality it is on your EFS share. When EB environment(s) get rebuilt, this script is automatically re-ran and the EFS is reattached, so the data appears to be persistent to the app on the EC2.
I hope this helps
Upvotes: 2