Updating/migrating to Envoy 1.17 - AWS App Mesh

Updating/migrating to Envoy 1.17

Important

End of support notice: On September 30, 2026, AWS will discontinue support for AWS App Mesh. After September 30, 2026, you will no longer be able to access the AWS App Mesh console or AWS App Mesh resources. For more information, visit this blog post Migrating from AWS App Mesh to Amazon ECS Service Connect.

Secret Discovery Service with SPIRE

If you're using SPIRE (SPIFFE Runtime Environment) with App Mesh to distribute trust certificates to your services, verify that you're using at least version 0.12.0 of the SPIRE agent (released December 2020). This is the first version that can support Envoy versions after 1.16.

Regular expression changes

Starting from Envoy 1.17, App Mesh configures Envoy to use the RE2 regular expression engine by default. This change is apparent to most users, but matches in Routes or Gateway Routes no longer allows look-ahead or back-references in regular expressions.

Positive and Negative look-ahead

Positive - A positive look-ahead is a parenthesized expression that starts with ?=:

(?=example)

These have the most utility when doing string replacement because they allow matching a string without consuming the characters as part of the match. Because App Mesh doesn't support regex string replacement, we recommend that you replace these with regular matches.

(example)

Negative - A negative look-ahead is a parenthesized expression that starts with ?!.

ex(?!amp)le

The parenthesized expressions are used to assert that part of the expression doesn't match a given input. In most cases, you can replace these with a zero quantifier.

ex(amp){0}le

If the expression itself is a character class, you can negate the whole class and mark it optional using ?.

prefix(?![0-9])suffix => prefix[^0-9]?suffix

Depending on your use-case, you might also be able to change your routes to handle this.

{ "routeSpec": { "priority": 0, "httpRoute": { "match": { "headers": [ { "name": "x-my-example-header", "match": { "regex": "^prefix(?!suffix)" } } ] } } } } { "routeSpec": { "priority": 1, "httpRoute": { "match": { "headers": [ { "name": "x-my-example-header", "match": { "regex": "^prefix" } } ] } } } }

The first route match looks for a header that starts with “prefix” but not followed by “suffix.” The second route acts to match all other headers that begin with “prefix,” including those that end in “suffix.” Instead, these can also be reversed as a way to remove the negative look-ahead.

{ "routeSpec": { "priority": 0, "httpRoute": { "match": { "headers": [ { "name": "x-my-example-header", "match": { "regex": "^prefix.*?suffix" } } ] } } } } { "routeSpec": { "priority": 1, "httpRoute": { "match": { "headers": [ { "name": "x-my-example-header", "match": { "regex": "^prefix" } } ] } } } }

This example reverses the routes to provide higher priority to headers that end in “suffix,” and all other headers that start with “prefix” are matched in the lower-priority route.

Back references

A back-reference is a way to write shorter expressions by repeating to a previous parenthesized group. They have this form.

(group1)(group2)\1

A backslash \ followed by a number acts as a placeholder for the n-th parenthesized group in the expression. In this example, \1 is used as an alternative way to write (group1) a second time.

(group1)(group2)(group1)

These can be removed by simply replacing the back-reference with the group being referenced as in the example.