From af89a5e1f89d4ad626475dfdef5f18e29a0e6c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 19 Apr 2024 15:04:07 +0200 Subject: [PATCH] PHPLIB-1163 Create tutorial for using MongoDB with Bref (#1273) (#1282) --- .gitignore | 3 + docs/examples/aws-lambda/composer.json | 19 +++ docs/examples/aws-lambda/index.php | 31 +++++ docs/examples/aws-lambda/serverless.yml | 22 ++++ docs/tutorial.txt | 1 + docs/tutorial/aws-lambda.txt | 151 ++++++++++++++++++++++++ phpcs.xml.dist | 8 ++ 7 files changed, 235 insertions(+) create mode 100644 docs/examples/aws-lambda/composer.json create mode 100644 docs/examples/aws-lambda/index.php create mode 100644 docs/examples/aws-lambda/serverless.yml create mode 100644 docs/tutorial/aws-lambda.txt diff --git a/.gitignore b/.gitignore index a973b72dd..9a0a717e5 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,7 @@ psalm.xml .phpbench/ phpbench.json +# bref +.serverless/ + mongocryptd.pid diff --git a/docs/examples/aws-lambda/composer.json b/docs/examples/aws-lambda/composer.json new file mode 100644 index 000000000..5d1c6071e --- /dev/null +++ b/docs/examples/aws-lambda/composer.json @@ -0,0 +1,19 @@ +{ + "name": "mongodb/bref-tutorial", + "type": "project", + "license": "MIT", + "repositories": [ + { + "type": "path", + "url": "../../..", + "options": { + "symlink": false + } + } + ], + "require": { + "bref/bref": "^2.1", + "bref/extra-php-extensions": "^1.4", + "mongodb/mongodb": "@dev" + } +} diff --git a/docs/examples/aws-lambda/index.php b/docs/examples/aws-lambda/index.php new file mode 100644 index 000000000..caad319bf --- /dev/null +++ b/docs/examples/aws-lambda/index.php @@ -0,0 +1,31 @@ +selectCollection('sample_guides', 'planets') + ->find([], ['sort' => ['orderFromSun' => 1]]); +} catch (Throwable $exception) { + exit($exception->getMessage()); +} + +?> + + + + MongoDB Planets + + + + + diff --git a/docs/examples/aws-lambda/serverless.yml b/docs/examples/aws-lambda/serverless.yml new file mode 100644 index 000000000..7773d1ddf --- /dev/null +++ b/docs/examples/aws-lambda/serverless.yml @@ -0,0 +1,22 @@ +service: app + +provider: + name: aws + region: us-east-1 + environment: + MONGODB_URI: ${env:MONGODB_URI} + +plugins: + - ./vendor/bref/bref + - ./vendor/bref/extra-php-extensions + +functions: + api: + handler: index.php + description: '' + runtime: php-83-fpm + timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds) + events: + - httpApi: '*' + layers: + - ${bref-extra:mongodb-php-83} diff --git a/docs/tutorial.txt b/docs/tutorial.txt index 31595bdc4..f50c19c88 100644 --- a/docs/tutorial.txt +++ b/docs/tutorial.txt @@ -18,5 +18,6 @@ Tutorials /tutorial/indexes /tutorial/tailable-cursor /tutorial/example-data + /tutorial/aws-lambda /tutorial/modeling-bson-data /tutorial/stable-api diff --git a/docs/tutorial/aws-lambda.txt b/docs/tutorial/aws-lambda.txt new file mode 100644 index 000000000..efce81fc1 --- /dev/null +++ b/docs/tutorial/aws-lambda.txt @@ -0,0 +1,151 @@ +============================== +Deploy to AWS Lambda with Bref +============================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +`Bref `__ lets you deploy serverless PHP applications on AWS Lambda. +In this tutorial, you will deploy a simple PHP application with the MongoDB PHP extension, +and connect to an Atlas cluster using AWS IAM authentication. + +Prerequisites +-------------- + +To deploy to AWS Lambda by using Bref, you must have the following components set up: + +- AWS account with access keys +- Serverless Framework + +To learn how to set these up, follow the `Setup tutorial `__ +in the Bref official documentation. + +Install the MongoDB extension +----------------------------- + +Bref uses Lambda layers to provide the PHP runtime. The ``bref`` layer is compiled +with PHP and a few extensions. Other extensions, like ``mongodb``, are available +in additional layers. + +Start by creating a new directory for your project and install the required MongoDB +and Bref dependencies. + +.. code-block:: none + + $ mkdir bref-mongodb-app && cd bref-mongodb-app + $ composer init + $ composer require bref/bref bref/extra-php-extensions mongodb/mongodb + +Then initialize the serverless configuration using the ``bref`` command. + +.. code-block:: none + + $ vendor/bin/bref init + + +After this series of commands, you should have this files: + +- ``composer.json`` for PHP dependencies installed in the ``vendor`` directory +- ``index.php`` a sample webpage +- ``serverless.yml`` for the configuration of the deployment + +To validate your setup, try deploying this default application. This outputs +a URL that renders a webpage with the Bref logo: + +.. code-block:: none + + $ serverless deploy + + +Now that you have initialized the project, you will add the ``mongodb`` extension. +Locate the "Serverless config" name in the list of extensions provided by +`bref/extra-php-extension `__. +Add it to the ``layers`` of the function in ``serverless.yaml``, this file +will look like this: + +.. code-block:: yaml + + plugins: + - ./vendor/bref/bref + - ./vendor/bref/extra-php-extensions + + functions: + api: + handler: index.php + runtime: php-83-fpm + layers: + - ${bref-extra:mongodb-php-83} + + + +Let's use the MongoDB driver with a web page that list planets from the Atlas +`sample dataset `__. +Replace the contents of ``index.php`` with the following: + +.. literalinclude:: /examples/aws-lambda/index.php + :language: php + + +Redeploy the application with the new ``index.php``: + +.. code-block:: none + + $ serverless deploy + + +The application will display an error message because the ``MONGODB_URI`` +environment variable has not yet been set. We'll look at how to set this +variable in the next section. + +AWS Credentials +--------------- + +Atlas supports passwordless authentication with AWS credentials. In any Lambda function, +AWS sets environment variables that contains the access token and secret token with +the role assigned to deployed function. + +1. Open the Lambda function in the AWS console +2. In :guilabel:`Configuration > Permission`, copy the :guilabel:`Role name` +3. Add this role to your Atlas cluster with the built-in Role: "Read and write any database" + +To learn how to set up unified AWS access, see `Set Up Unified AWS Access +`__ +in the MongoDB Atlas documentation. + +Now that the permissions have been configured, the Lambda function is allowed to access +your Atlas cluster. You can configure your application with the Atlas endpoint. + +Access to Atlas clusters is also restricted by IP address. Since the range of IP that comes +from AWS is very wide, you can `allow access from everywhere +`__. + +.. note:: + + Using VPC Peering is recommended in order to isolate your Atlas cluster from Internet. + This requires the Lambda function to be deployed in this AWS VPC. + +Find the connection URI in the Atlas UI :guilabel:`Atlas > Deployment > Database > Connect`. +Select :guilabel:`3. AWS IAM`. +Remove the ``:`` part from the URI, the credentials +will be read from environment variables. + +Update the ``serverless.yml`` file to pass the environment variable ``MONGODB_URI``. + +.. code-block:: yaml + + provider: + environment: + MONGODB_URI: "mongodb+srv://cluster0.example.mongodb.net/?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority" + +Finally, deploy with the new configuration. After deployment completes, you can +access the function URL and see the list of planets from your Atlas cluster. + +.. code-block:: none + + $ serverless deploy diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 9cee3b66a..8d6a708ce 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -75,6 +75,14 @@ + + + + docs/examples/*/index.php + + + docs/examples/*/index.php +