Skip to content

Commit af89a5e

Browse files
authored
PHPLIB-1163 Create tutorial for using MongoDB with Bref (#1273) (#1282)
1 parent 25182bc commit af89a5e

File tree

7 files changed

+235
-0
lines changed

7 files changed

+235
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ psalm.xml
1919
.phpbench/
2020
phpbench.json
2121

22+
# bref
23+
.serverless/
24+
2225
mongocryptd.pid
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "mongodb/bref-tutorial",
3+
"type": "project",
4+
"license": "MIT",
5+
"repositories": [
6+
{
7+
"type": "path",
8+
"url": "../../..",
9+
"options": {
10+
"symlink": false
11+
}
12+
}
13+
],
14+
"require": {
15+
"bref/bref": "^2.1",
16+
"bref/extra-php-extensions": "^1.4",
17+
"mongodb/mongodb": "@dev"
18+
}
19+
}

docs/examples/aws-lambda/index.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use MongoDB\Client;
4+
5+
require_once __DIR__ . '/vendor/autoload.php';
6+
7+
$uri = getenv('MONGODB_URI');
8+
9+
try {
10+
$client = new Client($uri);
11+
$planets = $client
12+
->selectCollection('sample_guides', 'planets')
13+
->find([], ['sort' => ['orderFromSun' => 1]]);
14+
} catch (Throwable $exception) {
15+
exit($exception->getMessage());
16+
}
17+
18+
?>
19+
<!DOCTYPE html>
20+
<html lang="en">
21+
<head>
22+
<title>MongoDB Planets</title>
23+
</head>
24+
<body>
25+
<ul>
26+
<?php foreach ($planets as $planet) : ?>
27+
<li><?= $planet->name ?></li>
28+
<?php endforeach ?>
29+
</ul>
30+
</body>
31+
</html>
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
service: app
2+
3+
provider:
4+
name: aws
5+
region: us-east-1
6+
environment:
7+
MONGODB_URI: ${env:MONGODB_URI}
8+
9+
plugins:
10+
- ./vendor/bref/bref
11+
- ./vendor/bref/extra-php-extensions
12+
13+
functions:
14+
api:
15+
handler: index.php
16+
description: ''
17+
runtime: php-83-fpm
18+
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
19+
events:
20+
- httpApi: '*'
21+
layers:
22+
- ${bref-extra:mongodb-php-83}

docs/tutorial.txt

+1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ Tutorials
1818
/tutorial/indexes
1919
/tutorial/tailable-cursor
2020
/tutorial/example-data
21+
/tutorial/aws-lambda
2122
/tutorial/modeling-bson-data
2223
/tutorial/stable-api

docs/tutorial/aws-lambda.txt

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
==============================
2+
Deploy to AWS Lambda with Bref
3+
==============================
4+
5+
.. contents:: On this page
6+
:local:
7+
:backlinks: none
8+
:depth: 2
9+
:class: singlecol
10+
11+
Overview
12+
--------
13+
14+
`Bref <https://bref.sh>`__ lets you deploy serverless PHP applications on AWS Lambda.
15+
In this tutorial, you will deploy a simple PHP application with the MongoDB PHP extension,
16+
and connect to an Atlas cluster using AWS IAM authentication.
17+
18+
Prerequisites
19+
--------------
20+
21+
To deploy to AWS Lambda by using Bref, you must have the following components set up:
22+
23+
- AWS account with access keys
24+
- Serverless Framework
25+
26+
To learn how to set these up, follow the `Setup tutorial <https://bref.sh/docs/setup>`__
27+
in the Bref official documentation.
28+
29+
Install the MongoDB extension
30+
-----------------------------
31+
32+
Bref uses Lambda layers to provide the PHP runtime. The ``bref`` layer is compiled
33+
with PHP and a few extensions. Other extensions, like ``mongodb``, are available
34+
in additional layers.
35+
36+
Start by creating a new directory for your project and install the required MongoDB
37+
and Bref dependencies.
38+
39+
.. code-block:: none
40+
41+
$ mkdir bref-mongodb-app && cd bref-mongodb-app
42+
$ composer init
43+
$ composer require bref/bref bref/extra-php-extensions mongodb/mongodb
44+
45+
Then initialize the serverless configuration using the ``bref`` command.
46+
47+
.. code-block:: none
48+
49+
$ vendor/bin/bref init
50+
51+
52+
After this series of commands, you should have this files:
53+
54+
- ``composer.json`` for PHP dependencies installed in the ``vendor`` directory
55+
- ``index.php`` a sample webpage
56+
- ``serverless.yml`` for the configuration of the deployment
57+
58+
To validate your setup, try deploying this default application. This outputs
59+
a URL that renders a webpage with the Bref logo:
60+
61+
.. code-block:: none
62+
63+
$ serverless deploy
64+
65+
66+
Now that you have initialized the project, you will add the ``mongodb`` extension.
67+
Locate the "Serverless config" name in the list of extensions provided by
68+
`bref/extra-php-extension <https://github.com/brefphp/extra-php-extensions>`__.
69+
Add it to the ``layers`` of the function in ``serverless.yaml``, this file
70+
will look like this:
71+
72+
.. code-block:: yaml
73+
74+
plugins:
75+
- ./vendor/bref/bref
76+
- ./vendor/bref/extra-php-extensions
77+
78+
functions:
79+
api:
80+
handler: index.php
81+
runtime: php-83-fpm
82+
layers:
83+
- ${bref-extra:mongodb-php-83}
84+
85+
86+
87+
Let's use the MongoDB driver with a web page that list planets from the Atlas
88+
`sample dataset <https://www.mongodb.com/docs/atlas/sample-data/>`__.
89+
Replace the contents of ``index.php`` with the following:
90+
91+
.. literalinclude:: /examples/aws-lambda/index.php
92+
:language: php
93+
94+
95+
Redeploy the application with the new ``index.php``:
96+
97+
.. code-block:: none
98+
99+
$ serverless deploy
100+
101+
102+
The application will display an error message because the ``MONGODB_URI``
103+
environment variable has not yet been set. We'll look at how to set this
104+
variable in the next section.
105+
106+
AWS Credentials
107+
---------------
108+
109+
Atlas supports passwordless authentication with AWS credentials. In any Lambda function,
110+
AWS sets environment variables that contains the access token and secret token with
111+
the role assigned to deployed function.
112+
113+
1. Open the Lambda function in the AWS console
114+
2. In :guilabel:`Configuration > Permission`, copy the :guilabel:`Role name`
115+
3. Add this role to your Atlas cluster with the built-in Role: "Read and write any database"
116+
117+
To learn how to set up unified AWS access, see `Set Up Unified AWS Access
118+
<https://www.mongodb.com/docs/atlas/security/set-up-unified-aws-access/>`__
119+
in the MongoDB Atlas documentation.
120+
121+
Now that the permissions have been configured, the Lambda function is allowed to access
122+
your Atlas cluster. You can configure your application with the Atlas endpoint.
123+
124+
Access to Atlas clusters is also restricted by IP address. Since the range of IP that comes
125+
from AWS is very wide, you can `allow access from everywhere
126+
<https://www.mongodb.com/docs/atlas/security/ip-access-list/>`__.
127+
128+
.. note::
129+
130+
Using VPC Peering is recommended in order to isolate your Atlas cluster from Internet.
131+
This requires the Lambda function to be deployed in this AWS VPC.
132+
133+
Find the connection URI in the Atlas UI :guilabel:`Atlas > Deployment > Database > Connect`.
134+
Select :guilabel:`3. AWS IAM`.
135+
Remove the ``<AWS access key>:<AWS secret key>`` part from the URI, the credentials
136+
will be read from environment variables.
137+
138+
Update the ``serverless.yml`` file to pass the environment variable ``MONGODB_URI``.
139+
140+
.. code-block:: yaml
141+
142+
provider:
143+
environment:
144+
MONGODB_URI: "mongodb+srv://cluster0.example.mongodb.net/?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority"
145+
146+
Finally, deploy with the new configuration. After deployment completes, you can
147+
access the function URL and see the list of planets from your Atlas cluster.
148+
149+
.. code-block:: none
150+
151+
$ serverless deploy

phpcs.xml.dist

+8
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@
7575

7676
<!-- Disable forbidden annotation sniff as excluding @api from the list doesn't work -->
7777
<exclude name="SlevomatCodingStandard.Commenting.ForbiddenAnnotations.AnnotationForbidden" />
78+
79+
<!-- Example file using HTML templating -->
80+
<exclude name="Generic.Files.InlineHTML.Found">
81+
<exclude-pattern>docs/examples/*/index.php</exclude-pattern>
82+
</exclude>
83+
<exclude name="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing.IncorrectLinesCountAfterControlStructure">
84+
<exclude-pattern>docs/examples/*/index.php</exclude-pattern>
85+
</exclude>
7886
</rule>
7987

8088

0 commit comments

Comments
 (0)