aws-samples / eb-php-drupal

Configuration files and instructions for installing Drupal securely and running it in a load balanced AWS Elastic Beanstalk environment with an EFS file system for shared assets.
Apache License 2.0
45 stars 24 forks source link

Fails: Command 01_mount failed #13

Open David-Slack opened 1 year ago

David-Slack commented 1 year ago

On using this I get the error: [ERROR] An error occurred during execution of command [app-deploy] - [PreBuildEbExtension]. Stop running the command. Error: EbExtension build failed. Please refer to /var/log/cfn-init.log for more details.

In cfn-init.log this leads to: [ERROR] Unhandled exception during build: Command 01_mount failed

To fix this:

  1. Create an EFS
  2. Set new Environment property as EFS_VOLUME_ID with the value of the File System ID

There will be a config change in efs-mount.config to fix this which will need looking at

David-Slack commented 1 year ago

I have been at this for a few days now and I've found quite a bit. I don't understand it but it may help someone. If anyone can give me reasons for this I'd appreciate it.

If a deploy takes place it will fail (either via upload or from the Application versions list). However, if after the fail I update the config, the deploy runs and works. e.g. Run on "HelloWorld" app and deploy fails then reverts back to sample app. Change the config and the deploy runs all works fine.

Running a deploy the my "HelloWorld" app to test this August 25, 2023 15:21:05 (UTC+1)INFOEnvironment update is starting. Failed!

Going to add the EFS back to the config and see if it works EFS_VOLUME_ID = [fs-07632cf9ee852a???

After adding in the volume ID the deploy runs again August 25, 2023 15:26:20 (UTC+1)INFOEnvironment update is starting.

This has worked with no changes to the package.

Going to try the same with the "EmptyDrupal" app August 25, 2023 15:28:51 (UTC+1)INFOEnvironment update is starting.

This has failed, the system is in a status of Degraded The "HelloWorld" app is live again Status is:

Incorrect application version "EmptyDrupal" (deployment 19). Expected version "Sample" (deployment 18). Going to change the config by removing EFS_VOLUME_ID

The build has restarted August 25, 2023 15:36:40 (UTC+1)INFOEnvironment update is starting.

And this has completed and I can see the Drupal setup page

NB. "HelloWorld" test app is this repo (configured to my VPN and IP) with an index.php and <?php echo "Hello World", the EmptyDrupal app is the same but with Drupal 10.1.2 added.

David-Slack commented 1 year ago

A little more info on this after developing/testing for a week. Always the same error no matter what I do:

2023-08-24 12:32:06,965 [INFO] -----------------------Starting build-----------------------
2023-08-24 12:32:06,984 [INFO] Running configSets: _OnInstanceBoot
2023-08-24 12:32:06,988 [INFO] Running configSet _OnInstanceBoot
2023-08-24 12:32:06,994 [INFO] Running config AWSEBBaseConfig
2023-08-24 12:32:07,767 [INFO] Command clearbackupfiles succeeded
2023-08-24 12:32:07,772 [INFO] Running config AWSEBCfnHupEndpointOverride
2023-08-24 12:32:07,788 [INFO] Command clearbackupfiles succeeded
2023-08-24 12:32:07,790 [INFO] ConfigSets completed
2023-08-24 12:32:07,790 [INFO] -----------------------Build complete-----------------------
2023-08-24 12:32:16,822 [INFO] -----------------------Starting build-----------------------
2023-08-24 12:32:16,836 [INFO] Running configSets: Infra-EmbeddedPreBuild
2023-08-24 12:32:16,851 [INFO] Running configSet Infra-EmbeddedPreBuild
2023-08-24 12:32:16,855 [INFO] Running config prebuild_0_HuytonWeb_CMS
2023-08-24 12:32:16,860 [INFO] Running config prebuild_1_HuytonWeb_CMS
2023-08-24 12:32:16,862 [INFO] ConfigSets completed
2023-08-24 12:32:16,862 [INFO] -----------------------Build complete-----------------------
2023-08-24 12:32:19,892 [INFO] -----------------------Starting build-----------------------
2023-08-24 12:32:19,924 [INFO] Running configSets: Infra-EmbeddedPostBuild
2023-08-24 12:32:19,931 [INFO] Running configSet Infra-EmbeddedPostBuild
2023-08-24 12:32:19,931 [INFO] ConfigSets completed
2023-08-24 12:32:19,931 [INFO] -----------------------Build complete-----------------------
2023-08-24 12:49:14,403 [INFO] -----------------------Starting build-----------------------
2023-08-24 12:49:14,410 [INFO] Running configSets: Infra-EmbeddedPreBuild
2023-08-24 12:49:14,412 [INFO] Running configSet Infra-EmbeddedPreBuild
2023-08-24 12:49:14,417 [INFO] Running config prebuild_0_HuytonWeb_CMS
2023-08-24 12:49:16,652 [ERROR] Command 01_mount (/tmp/mount-efs.sh) failed
2023-08-24 12:49:16,652 [ERROR] Error encountered during build of prebuild_0_HuytonWeb_CMS: Command 01_mount failed
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 579, in run_config
    CloudFormationCarpenter(config, self._auth_config, self.strict_mode).build(worklog)
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 277, in build
    changes['commands'] = CommandTool().apply(
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/command_tool.py", line 127, in apply
    raise ToolError(u"Command %s failed" % name)
cfnbootstrap.construction_errors.ToolError: Command 01_mount failed
2023-08-24 12:49:16,654 [ERROR] -----------------------BUILD FAILED!------------------------
2023-08-24 12:49:16,654 [ERROR] Unhandled exception during build: Command 01_mount failed
Traceback (most recent call last):
  File "/opt/aws/bin/cfn-init", line 181, in <module>
    worklog.build(metadata, configSets, strict_mode)
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 137, in build
    Contractor(metadata, strict_mode).build(configSets, self)
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 567, in build
    self.run_config(config, worklog)
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 579, in run_config
    CloudFormationCarpenter(config, self._auth_config, self.strict_mode).build(worklog)
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 277, in build
    changes['commands'] = CommandTool().apply(
  File "/usr/lib/python3.9/site-packages/cfnbootstrap/command_tool.py", line 127, in apply
    raise ToolError(u"Command %s failed" % name)
cfnbootstrap.construction_errors.ToolError: Command 01_mount failed

Among other things I've tried:

Is there a security group or IAM role setting that must be used? Is there a time I must process this, on a first create or without an application LB? Do I need to do a special dance invoking the devops gods for their favour? Is there a change to owner I must make that is not in this doc? I cannot find it in any documentation that would point me in the right direction.

The goal is to have public, private and modules in the EFS when this is all working, but at the moment it is just the public files. Any help would be appreciated. Thanks

David-Slack commented 1 year ago

More info. Creating a new EFS and/or mounting will fail on builds from a pipeline or builds from the upload. However, once a package is in the Application Versions we can deploy them from the Actions and they will deploy without incident.

I need to check if the EFS is working once the environment is in the OK state and data is adding correctly.

Even if this workaround is working this is no good for CI/CD and the mount is still failing and needs looking at.

dm-marimosa commented 8 months ago

Had the same issue as @David-Slack this week, just adding what enabled me to progress in case it helps anyone else.

In the docs here: https://github.com/aws-samples/eb-php-drupal The docs use the command eb create drupal-beanstalk --sample --database. This created the EB instance without a VPC for me. If I alternatively used eb create drupal-beanstalk --sample --database --vpc and provided my VPC details in the prompts that followed, this seemed to enabled the EFS creation / mounting used in the scripts in this repo.

I also consulted the following docs: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/php-hadrupal-tutorial.html#php-hadrupal-tutorial-install

I was able to get to the last part of the drupal install after this, but running into a different issue now.

David-Slack commented 8 months ago

We have Drupal 10 as a headless CMS with Next.js / React as the frontend here https://www.huytonweb.com and all canary deployment from Github. The FE uses Git Flow branching for QA and dev but the BE is triggered from master branch merge. I will be moving from AWS very soon as the cost for IPv4 is too expensive and ALL tutorials/settings/wizards use IPv4 not IPv6.

To get Drupal 10 working in AWS with Elastic Beanstalk we need 3 files in .ebextensions (in Drupal root) dir:

  1. efs-create.config
  2. efs-mount.config
  3. https-redirect-alb

We need 1 file in the dir .platform/hooks/postdeploy (in Drupal root):

  1. 01_drupal_files.sh

This will get the system working with changing mods on prod, changing images, files, etc. in public or private Drupal setup, we have chosen public because we need to access images from the FE.

The files are:

efs-create.config - Change your subnets and VPCIds

###################################################################################################
#### Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
####
#### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
#### except in compliance with the License. A copy of the License is located at
####
####     http://aws.amazon.com/apache2.0/
####
#### or in the "license" file accompanying this file. This file is distributed on an "AS IS"
#### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#### License for the specific language governing permissions and limitations under the License.
###################################################################################################

###################################################################################################
#### This configuration file creates an Amazon EFS file system with mount targets in two subnets,
#### and a security group that allows traffic from the default AWS Elastic Beanstalk instance
#### security group. Each mount target corresponds to a single Availability Zone (AZ). Depending on
#### the region, the number of available AZs will vary. You can add mount target resources and the
#### corresponding subnet option for use in more than two AZs.
####
#### EFS requires a VPC. You can use the default VPC or create a custom VPC to use. If you
#### use a custom VPC, configure it to allow DNS resolution and DNS host names. For more
#### information, see this topic in the Elastic Beanstalk Developer Guide:
####    http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/vpc.html
####
#### Specify your VPC ID and subnet IDs in the "option_settings" section below. In a custom VPC,
#### use the VPC ID and subnet IDs that you chose for the Amazon EC2 instances running your
#### application. When you create a new environment, you can specify VPC settings in a
#### configuration file with the options in the aws:ec2:vpc namespace. See
#### vpc-custom-loadbalanced.config in the environment_configuration folder for an example.
####
#### To use this configuration file in your default VPC, you must have a mount target for each
#### default subnet to ensure that all instances can connect to the file system. Use the VPC
#### management console (https://console.aws.amazon.com/vpc) to determine the number of available
#### AZs and the default subnet for each. Add a subnet option and mount target resource for
#### each additional AZ.
####
#### EFS supports two performance modes for file systems, "generalPurpose" and "maxIO". Change the
#### "PerformanceMode" value under "FileSystem" to "maxIO" for increased throughput and IOPS
#### at the expense of slightly increased latency.
####
#### EFS supports encrypted file systems. To create an EFS encrypted file system, change the
#### "Encrypted" property value to "true". If you keep the "KMSKeyId" property commented out,
#### EFS uses a default KMS key. Alternatively, you can uncomment "KMSKeyId" (remove the initial "#")
#### and set its value to a valid ARN of a KMS key.
#### For information about creating and managing keys, see the AWS Key Management Service
#### Developer Guide:
####    http://docs.aws.amazon.com/kms/latest/developerguide
####
#### To avoid creating the file system more than once, add this configuration file in a deployment
#### without any other configuration changes. After the environment update completes and the file
#### system is ready, use storage-efs-mountfilesystem.config to mount the file system on each
#### instance. Any errors caused by other configuration files added in the same deployment will
#### cause the deployment to fail and the file system to be terminated.
####
#### Back up the contents of your file system to avoid data loss when your environment is
#### terminated. The file system will also be terminated if this configuration file is removed or
#### if you change the performance mode setting.
###################################################################################################

option_settings:
  aws:elasticbeanstalk:customoption:
    VPCId: "vpc-????"
## Subnet Options
    SubnetA: "subnet-????"
    SubnetB: "subnet-????"
    SubnetC: "subnet-????"

Resources:
  FileSystem:
    Type: AWS::EFS::FileSystem
    Properties:
      FileSystemTags:
      - Key: Name
        Value: "EB-EFS-FileSystem"
      PerformanceMode: "generalPurpose"
      Encrypted: "false"
#      KmsKeyId: "KMS-key-ARN"

## 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 ####
##############################################

  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}

efs-mount.config

###################################################################################################
#### Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
####
#### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
#### except in compliance with the License. A copy of the License is located at
####
####     http://aws.amazon.com/apache2.0/
####
#### or in the "license" file accompanying this file. This file is distributed on an "AS IS"
#### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#### License for the specific language governing permissions and limitations under the License.
###################################################################################################

###################################################################################################
#### This configuration file mounts an Amazon EFS file system to a directory named /efs. To mount
#### the file system to a different path, modify the MOUNT_DIRECTORY value in the "option_settings"
#### section.
####
#### The FILE_SYSTEM_ID setting references a resource named "FileSystem", which is created by the
#### storage-efs-createfilesystem.config configuration file. To use this file to mount a
#### file system that you created outside of AWS Elastic Beanstalk, replace the Ref with the
#### resource ID (e.g., fs-e7605f4e):
####
####      FILE_SYSTEM_ID: fs-e7605f4e
####
#### If your environment and file system are in a custom VPC, you must configure the VPC to allow
#### DNS resolution and DNS host names. See this topic in the VPC User Guide for more information:
####    http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-dns.html
###################################################################################################

option_settings:
  aws:elasticbeanstalk:application:environment:
    FILE_SYSTEM_ID: '`{"Ref" : "FileSystem"}`'
    # FILE_SYSTEM_ID: fs-0ef7fc2371c9207a5 # Encrypted seems to fail
    MOUNT_DIRECTORY: '/drupalfiles'

##############################################
#### Do not modify values below this line ####
##############################################

container_commands:
  1Make:
    command: "mkdir -p /drupalfiles/private"
  2chown:
    command: "chown -R webapp:webapp /drupalfiles"
  3chown:
    command: "chmod -R 755 /drupalfiles"
  4chmod:
    command: "chmod +x .platform/hooks/postdeploy/01_drupal_files.sh"

packages:
  yum:
    amazon-efs-utils: []

commands:
  01_mount:
    command: "/tmp/mount-efs.sh"

files:
  "/tmp/mount-efs.sh":
      mode: "000755"
      content : |
        #!/bin/bash

        EFS_MOUNT_DIR=$(/opt/elasticbeanstalk/bin/get-config environment -k MOUNT_DIRECTORY)
        EFS_FILE_SYSTEM_ID=$(/opt/elasticbeanstalk/bin/get-config environment -k FILE_SYSTEM_ID)

        echo "Mounting EFS filesystem ${EFS_FILE_SYSTEM_ID} 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 efs -o tls ${EFS_FILE_SYSTEM_ID}:/ ${EFS_MOUNT_DIR}"
            mount -t efs -o tls ${EFS_FILE_SYSTEM_ID}:/ ${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.'

https-redirect-alb

###################################################################################################
#### Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
####
#### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
#### except in compliance with the License. A copy of the License is located at
####
####     http://aws.amazon.com/apache2.0/
####
#### or in the "license" file accompanying this file. This file is distributed on an "AS IS"
#### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#### License for the specific language governing permissions and limitations under the License.
###################################################################################################

###################################################################################################
#### This configuration file modifies the default port 80 listener attached to an Application Load Balancer
#### to automatically redirect incoming connections on HTTP to HTTPS.
#### This will not work with an environment using the load balancer type Classic or Network.
#### A prerequisite is that the 443 listener has already been created.
#### Please use the below link for more information about creating an Application Load Balancer on
#### the Elastic Beanstalk console.
#### https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-alb.html#environments-cfg-alb-console
###################################################################################################

Resources:
 AWSEBV2LoadBalancerListener:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    LoadBalancerArn:
      Ref: AWSEBV2LoadBalancer
    Port: 80
    Protocol: HTTP
    DefaultActions:
      - Type: redirect
        RedirectConfig:
          Host: "#{host}"
          Path: "/#{path}"
          Port: "443"
          Protocol: "HTTPS"
          Query: "#{query}"
          StatusCode: "HTTP_301"
David-Slack commented 8 months ago

My notes are below, I have more with Drupal content, API, Cron, Sitemap, Robots.txt and others if anyone needs them. This took about a month of R&D and trial and error for 1 person and there is no easy way to do this. The tutorial from AWS fails on use so if you go down the route of AWS, Drupal and Elastic Beanstalk there is a lot of work, but it is interesting and adding Gitflow, Blue/Green deployment and separated FE and BE through headless gives a fast (100 in Google Lighthouse), well architected easy, safely updateable system.

AWS

  1. Purchase a domain in Route 53 for the project - Do not move on until this is complete.
  2. Create a mail server - Do not move on until this is complete. a. See https://aws.amazon.com/blogs/opensource/fully-automated-deployment-of-an-open-source-mail-server-on-aws/ b. Route 53 will need to do all the DNS so MiaB should not control the main domain and www sub domain or we will not have a website on AWS but on the mail server. See the page /admin#external_dns in MiaB c. Move out of SES Sandbox to production https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html d. Setup any email addresses and send the info to the client
  3. Create an Elastic Beanstalk (EB) application called ????-CMS (*???? Is the project name camel case) using https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/php-hadrupal-tutorial.html#php-hadrupal-tutorial-deploy. a. Keep it a single instance. b. Use the sample app - Do not move on until this is complete.
  4. Upload a zip of the basic Drupal app - Do not move on until this is complete. a. In settings.php update the trusted_host_patterns to add all domains, add $_SERVER['SERVER_ADDR'] to stop the health check failing. b. DO NOT include the file https-redirect-alb as we have no load balancer
  5. In the security group for the RDS database add an incoming rule with type Arora/MySQL and source the same sg- as the EB
  6. In Route 53 create a sub domain of the main domain called cms and alias it to the EB instance.
  7. In AWS Certificate Manager Request a certificate for the subdomain - Do not move on until this is complete a. Create records in Rout 53.
  8. In EB configuration edit instance and traffic scaling a. Auto scaling group to Load balanced b. Instances 1 and 2 c. Keep both as micro so delete small d. Under listeners Add listener i. Port 443 ii. Protocol HTTPS iii. Default Process to default so when HTTPS traffic is decrypted it is passed to port 80 instance iv. Choose the SSL cert requested previously v. SSL policy, usually ELBSecurityPolicy-TLS13-1-2-2021-06 e. Apply
  9. Create a pipeline from GitHub to the EB on the master branch update
  10. All traffic on port 80 should be redirected to 443 - SHOUD BE AUTOMATIC, but not a. In EC2 click load balancers
    b. Choose the load balancer for the EB instance and click it c. Under Listeners and rules at the bottom select HTTP:80 d. Under Manager Listener click Edit Listener e. Select Redirect URL f. Select URI parts g. Select HTTPS and type 443 as to port number h. Save Changes - This may take a minute to propagate
  11. To add a FE a. Go to the Amplify page b. Create a new app c. Follow the instructions

NB. Before rebuilding delete the incoming from RDS Security Group then add back once rebuilt https://repost.aws/knowledge-center/elastic-beanstalk-platform-hooks

Drupal Emails

  1. Create email address for the website e.g. admin@
  2. In AWS SES verify the email address
  3. In AWS IAM create a user for the CMS e.g. cms and give it the correct permissions a. ses:GetAccount b. ses:CreateEmailIdentity c. ses:DeleteEmailIdentity d. ses:GetEmailIdentity e. ses:ListEmailIdentities
  4. Create an access key for the user
  5. Install the 3 modules in Drupal a. Amazon SES b. Amazon Web Services c. Mail System
  6. Setup AWS at /admin/config/services/aws a. Add profile called the same name as the AWS IAM user for ease e.g. cms b. Add the access key from above c. Add the secret from above d. Add the region as eu-west-2
  7. Setup Amazon SES in Drupal at /admin/config/system/amazon_ses/settings with the email address of the site and that has been verified.
  8. Configure the mail system at /admin/config/system/mailsystem changing the formatter and sender to Amazon SES mailer.
  9. Submission email enabled at /admin/structure/webform/manage/contact/handlers/email_notification/edit set: a. To email: [site:mail] b. From email: [site:mail]

NB. The install for the AWS mod must be done in composer, not drupal modules as it does not install deps composer require 'drupal/aws:^2.0'

Contact page

Install the 3 mods: • WebformWebform RESTREST UI

NB. Enable Webform UI mod

  1. Go to the admin for /admin/config/services/rest
  2. Enable Webform Submit /webform_rest/submit: POST for POST, json and basic_auth
  3. Visit /admin/people/permissions and give anonymous users the Access POST on Webform Submit resource permission.
  4. Go to the Webform /admin/structure/webform and build the form if needed e.g. add phone number, but default should be fine.
  5. Go to the settings → Access for the form and remove access for all users to the form
  6. If we are using headless goto /admin/structure/webform/config/advanced a. remove ALL requirement settings b. User interface settings should have all disabled
  7. Give access to Administer webform submissions (viewable at /admin/structure/webform/submissions/manage) to content editor
  8. Create a shortcut to /admin/structure/webform/submissions/manage
  9. Add Contact to the main menu /admin/structure/menu
  10. Add Submissions to the admin menu /admin/structure/menu/manage/admin
  11. On the FE install reCAPTCHA a. npm install react-google-recaptcha (How can i implement ReCaptcha into a Nextjs contact form? ) b. Got to https://www.google.com/recaptcha/admin/create and setup c. Add the 2 env vars for all branches and .env.local, then an override for the master branch i. NEXT_PUBLIC_RECAPTCHA_SITE_KEY=YOUR_SITE_KEY ii. RECAPTCHA_SECRET_KEY=YOUR_SECRET_KEY

NB. Make sure the mod contact (site wide contact form) is uninstalled so there is no permissions issue with the menu link.