Mirror production traffic to a test origin with Functions
Build a function on a firewall that sends a copy of every matched request to a test origin, then read the mirrored responses in Real-Time Events.
In this tutorial, you will build a function that copies production requests to a test origin. The copy lets new software answer real requests before it serves users. You will create the function, instantiate it on a firewall, and trigger it with a Rules Engine rule. Then you will read the mirrored responses in Real-Time Events.
Prerequisites
- An Azion account. To create one, refer to How to create an account on Azion.
- The Edit Functions permission on the account. It also requires the permission View Functions.
- The Edit Firewall permission on the account. It also requires the permission View Firewall. Refer to Teams Permissions.
- An application that receives production traffic, on a domain you control. To configure the domain, refer to Add a custom domain to a workload.
- A firewall associated with that domain. To create one, refer to Set a firewall’s main settings.
- A test origin that answers over HTTPS.
1. Create the traffic mirroring function
A function runs on a firewall when it exports a firewall handler. To create the function:
Access Azion Console > Products Menu > Libraries > Functions.
Enter a name for the function. For example: traffic-mirroring.
In the Code tab, paste the following code:
Replace example.com with the domain of your test origin.
The function is saved and available to instantiate on a firewall.
ctx.waitUntil() extends the execution past the point where the handler returns. The copy therefore leaves the request path, and the original request reaches the production origin with no added latency. The handler never calls ctx.deny(), so no request is blocked. AbortSignal.timeout() ends a copy after 5 seconds, and a slower test origin needs a higher value.
2. Instantiate the function on the firewall
A function instance binds the function to one firewall, and a firewall runs a function only with the Functions module turned on. To create the instance:
In Azion Console, go to Products Menu > Firewall > your firewall.
Enter a name for the instance. For example: traffic-mirroring instance.
Select the traffic-mirroring function. Only functions whose Initiator Type is set to Firewall appear in the list.
The instance appears in the Functions Instances tab. It does not run until a Rules Engine rule selects it.
3. Add the rule that runs the function
A Rules Engine rule sets the criteria that trigger the instance. To mirror the requests whose URI starts with /api:
In the same firewall, go to the Rules Engine tab.
Enter a name for the rule. For example: Mirror traffic to the test origin.
In the Criteria section, select the Request URI variable.
Enter /api as the argument.
The rule runs the instance on every request whose URI starts with /api. Changes can take a few minutes to propagate. Wait before you send a request that matches the criteria.
4. Verify the mirrored requests in Real-Time Events
Send a request that matches the rule criteria:
The firewall runs the instance on that request, and the function sends a copy to the test origin. To read what the test origin answered:
Access Azion Console > Real-Time Events.
A copy that succeeds logs the status of the test origin and its response time:
A response above 399 logs the request and the response as JSON, so the failure carries its own context. A copy that exceeds the timeout logs Test origin timeout.
Read the entries against four measures:
- Response time: how the latency of the test origin compares with production.
- Error rate: how many entries carry a 4xx or 5xx status.
- Timeout frequency: how often a copy exceeds the timeout.
- Request coverage: whether the test origin answers every method the rule matches, including
POST,PUT, andDELETE.
When the test origin answers production traffic inside your latency and error budget, it is ready to serve production.
5. (Optional) Set the test origin from an environment variable
Environment variables hold the test origin and the timeout outside the code, so one function serves several tests. To read both values from the environment:
Create TEST_ORIGIN and TEST_TIMEOUT on the function, as described in Environment variables.
In the Code tab, replace the code with the following:
Azion.env.get() returns the value of a key at run time. When TEST_TIMEOUT carries no value, the function falls back to 10000 ms.
The function reads the test origin at run time, so the next test origin needs no code edit.