Search code examples
aws-cloudformationamazon-efs

AWS WordPress with EFS


I building an AutoScaling WordPress Enviroment but have a question on EFS while setting up a CF Template. Am I suppose to mount the EFS on top of the existing WP Directory i.e /var/www/html or copy the WordPress Files to the EFS and then mount it to /var/www/html?


Solution

  • So WordPress backed by EFS.

    Firstly you will create the EFS, then mounting is done. After that one cron job will be written to copy all the Wordpress files from var/www/html to mounted directory.

    creating EFS

    option_settings:
      aws:elasticbeanstalk:customoption:
        EFSVolumeName: "EFS_Wordpress"
        VPCId: "vpc-xxxx"
    ## Subnet Options
        SubnetA: "subnet-xxxx"
        SubnetB: "subnet-xxxx"
        SubnetC: "subnet-xxxx"
      aws:elasticbeanstalk:application:environment:
        FILE_SYSTEM_ID: '`{"Ref" : "FileSystem"}`'
        MOUNT_DIRECTORY: '/wpfiles'
        REGION: '`{"Ref": "AWS::Region"}`'
    Resources:
    ## Mount Target Resources
      MountTargetA:
        Type: AWS::EFS::MountTarget
        Properties:
          FileSystemId: {Ref: FileSystem}
          SecurityGroups:
          - {Ref: MountTargetSecurityGroup}
          SubnetId:
            Fn::GetOptionSetting: {OptionName: SubnetA}
      MountTargetB:
        Type: AWS::EFS::MountTarget
        Properties:
          FileSystemId: {Ref: FileSystem}
          SecurityGroups:
          - {Ref: MountTargetSecurityGroup}
          SubnetId:
            Fn::GetOptionSetting: {OptionName: SubnetB}
      MountTargetC:
        Type: AWS::EFS::MountTarget
        Properties:
          FileSystemId: {Ref: FileSystem}
          SecurityGroups:
          - {Ref: MountTargetSecurityGroup}
          SubnetId:
            Fn::GetOptionSetting: {OptionName: SubnetC}
    
    ##############################################
    #### Do not modify values below this line ####
    ##############################################
    
      FileSystem:
        Type: AWS::EFS::FileSystem
        Properties:
          FileSystemTags:
          - Key: Name
            Value:
              Fn::GetOptionSetting: {OptionName: EFSVolumeName, DefaultValue: "EFS_Wordpress"}
    
      MountTargetSecurityGroup:
        Type: AWS::EC2::SecurityGroup
        Properties:
          GroupDescription: Security group for mount target
          SecurityGroupIngress:
          - FromPort: '2049'
            IpProtocol: tcp
            SourceSecurityGroupId:
              Fn::GetAtt: [AWSEBSecurityGroup, GroupId]
            ToPort: '2049'
          VpcId:
            Fn::GetOptionSetting: {OptionName: VPCId}
    

    mounting EFS

    container_commands:
      1chown:
        command: "chown webapp:webapp /wpfiles"
      2create:
        command: "sudo -u webapp mkdir -p wp-content/uploads"
      3link:
        command: "sudo -u webapp ln -s /wpfiles wp-content/uploads"
    option_settings:
      aws:elasticbeanstalk:application:environment:
        FILE_SYSTEM_ID: '`{"Ref" : "FileSystem"}`'
        MOUNT_DIRECTORY: '/wpfiles'
        REGION: '`{"Ref": "AWS::Region"}`'
    
    packages:
      yum:
        nfs-utils: []
        jq: []
    
    commands:
      01_mount:
        command: "/tmp/mount-efs.sh"
    
    files:
      "/tmp/mount-efs.sh":
          mode: "000755"
          content : |
            #!/bin/bash
    
            EFS_REGION=$(/opt/elasticbeanstalk/bin/get-config environment | jq -r '.REGION')
            EFS_MOUNT_DIR=$(/opt/elasticbeanstalk/bin/get-config environment | jq -r '.MOUNT_DIRECTORY')
            EFS_FILE_SYSTEM_ID=$(/opt/elasticbeanstalk/bin/get-config environment | jq -r '.FILE_SYSTEM_ID')
    
            echo "Mounting EFS filesystem ${EFS_DNS_NAME} to directory ${EFS_MOUNT_DIR} ..."
    
            echo 'Stopping NFS ID Mapper...'
            service rpcidmapd status &> /dev/null
            if [ $? -ne 0 ] ; then
                echo 'rpc.idmapd is already stopped!'
            else
                service rpcidmapd stop
                if [ $? -ne 0 ] ; then
                    echo 'ERROR: Failed to stop NFS ID Mapper!'
                    exit 1
                fi
            fi
    
            echo 'Checking if EFS mount directory exists...'
            if [ ! -d ${EFS_MOUNT_DIR} ]; then
                echo "Creating directory ${EFS_MOUNT_DIR} ..."
                mkdir -p ${EFS_MOUNT_DIR}
                if [ $? -ne 0 ]; then
                    echo 'ERROR: Directory creation failed!'
                    exit 1
                fi
            else
                echo "Directory ${EFS_MOUNT_DIR} already exists!"
            fi
    
            mountpoint -q ${EFS_MOUNT_DIR}
            if [ $? -ne 0 ]; then
                echo "mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${EFS_FILE_SYSTEM_ID}.efs.${EFS_REGION}.amazonaws.com:/ ${EFS_MOUNT_DIR}"
                mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${EFS_FILE_SYSTEM_ID}.efs.${EFS_REGION}.amazonaws.com:/ ${EFS_MOUNT_DIR}
                if [ $? -ne 0 ] ; then
                    echo 'ERROR: Mount command failed!'
                    exit 1
                fi
                chmod 777 ${EFS_MOUNT_DIR}
                runuser -l  ec2-user -c "touch ${EFS_MOUNT_DIR}/it_works"
                if [[ $? -ne 0 ]]; then
                    echo 'ERROR: Permission Error!'
                    exit 1
                else
                    runuser -l  ec2-user -c "rm -f ${EFS_MOUNT_DIR}/it_works"
                fi
            else
                echo "Directory ${EFS_MOUNT_DIR} is already a valid mountpoint!"
            fi
    
            echo 'EFS mount complete.'
    

    Copying files to Mount Directory

    files:
      "/tmp/wpcopysymlink.sh":
          mode: "000755"
          content : |
            #!/bin/bash
    
            ## ebextensions check if Symlink and wp is already installed if not copy it to EFS
    
            echo "Time: $(date). Checking to see Wordpress is already in EFS or not..."
            if [ ! -d /wpfiles/wp-admin ]; then
                echo "Wordpress isn't installed I'm going to copy the base install to the EFS Shared directory /wpfiles ..."
                cp -r /var/app/current/* /wpfiles
                if [ $? -ne 0 ]; then
                    echo 'ERROR: Directory Copy failed!'
                    exit 1
                fi
            else
                echo "Wordpress is already there /wpfiles/wp-admin already exists!"
            fi
    
            echo 'Checking to see if the symlink is there from the app dir to EFS or not...'
    
            if [ -L /var/app/current ] ; then
            echo "Good link so your good to go"
                else
                    echo "No link so I'm removing the directory and creating the symlink in it's place to EFS"
                    rm -rf /var/app/current
                    ln -s /wpfiles /var/app/current
            fi
    
            echo "Time: $(date). All done for EFS"
    

    Now you can write a cron job which will run after every 5min to copy all the files to mount directory.

    For ref:- https://github.com/karan6190/WordpressAutoScalable-EFS