Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Mesh API Revision - Developer Preview #92

Closed
bcelenza opened this issue Feb 22, 2019 · 4 comments
Closed

App Mesh API Revision - Developer Preview #92

bcelenza opened this issue Feb 22, 2019 · 4 comments
Assignees

Comments

@bcelenza
Copy link
Contributor

bcelenza commented Feb 22, 2019

What we're changing
On March 7, 2019, the AWS App Mesh team will release a new, backward incompatible version of our APIs in the AWS SDKs. The primary change is the introduction of a new resource type, VirtualService, which replaces the use of ServiceNames in the current APIs. These changes are primarily focused on addressing potential confusion around ServiceNames in VirtualNodes and VirtualRouters (see #77).

A VirtualService in AWS App Mesh is an abstraction of the real service implementation behind it. Dependent services will call your VirtualService by its name (formerly the ServiceName), and you are free to implement how your VirtualService is provided to those dependencies through VirtualNodes and VirtualRouters.

A full description of changes is available in the FAQ below.

What we're asking
We're inviting developers to try out these new APIs and provide feedback before we officially release them as part of the AWS SDK. We would especially love to hear your feedback on whether you feel this is an improvement over the existing APIs from the standpoint of issue #77.

How can you give feedback?
You can leave feedback on this issue. Or, you can email your feedback to aws-appmesh-feedback@amazon.com.

How can you test this?
You can try the new APIs by downloading the trial JSON CLI file and add it to your existing AWS CLI via:

$ aws configure add-model \
    --service-name appmesh-trial \
    --service-model https://s3-us-west-2.amazonaws.com/aws-appmesh-cli-trials/app-mesh-2019-01-25.trial.json

Once you've added this model, you can begin using the new APIs on your existing mesh.

As a brief example, if you've setup the colorapp example from our aws-app-mesh-examples repository, you can use the new VirtualService API to determine where the ServiceName tcpecho.default.svc.cluster.local points to in your mesh:

$ aws appmesh-trial describe-virtual-service \
    --mesh-name colorapp \
    --virtual-service-name tcpecho.default.svc.cluster.local
 {
    "virtualService": {
        "status": {
            "status": "ACTIVE"
        },
        "metadata": {
            "createdAt": 1543434909.84,
            "version": 1,
            "arn": "arn:aws:appmesh:us-west-2:123456789012:mesh/colorapp/virtualService/tcpecho.default.svc.cluster.local",
            "lastUpdatedAt": 1543434909.84,
            "uid": "3a222219-fd1f-410b-93f8-852338307046"
        },
        "meshName": "colorapp",
        "virtualServiceName": "tcpecho.default.svc.cluster.local",
        "spec": {
            "provider": {
                "virtualNode": {
                    "virtualNodeName": "tcpecho-vn"
                }
            }
        }
    }
}

In the above example we can see that the VirtualService (formerly ServiceName) points to the VirtualNode named tcpecho-vn by showing it as the VirtualService provider. This means that requests sent to tcpecho.default.svc.cluster.local in the mesh will be routed to the tcpecho-vn. The provider can also be a VirtualRouter, as would be the case for the colorteller.default.svc.cluster.local ServiceName.

We would love to hear your feedback on whether you feel these changes clarify the use of ServiceNames in App Mesh. Let us know in the comments below!

Walkthrough

Using the existing colorapp example as a guide, let's walk through what setting up the mesh would look like in the new APIs. To simplify things, we'll ignore the tcpecho service in the existing example and focus just on colorgateway, colorteller, and how we connect them through the use of a VirtualRouter and VirtualService.

To start, we'll create the VirtualNodes for colorgateway and colorteller (white).

$ aws appmesh-trial create-mesh --mesh-name colorapp

$ aws appmesh-trial create-virtual-node \
    --mesh-name colorapp \
    --cli-input-json file://colorgateway-virtualnode.json
    
// colorgateway-virtualnode.json:
{
    "spec": {
        "listeners": [
            {
                "portMapping": {
                    "port": 9080,
                    "protocol": "http"
                }
            }
        ],
        "serviceDiscovery": {
            "dns": {
                "hostname": "colorgateway.default.svc.cluster.local"
            }
        },
        "backends": [
            {
                // Note: Although the VirtualService does not yet exist,
                // you can still specify it as a backend, just as you could
                // in the original APIs. When the VirtualService is created later,
                // App Mesh will make the necessary connections in your mesh.
                // ¯\_(ツ)_/¯
                "virtualService": {
                    "virtualServiceName": "colorteller.default.svc.cluster.local"
                }
            }
        ]
    },
    "virtualNodeName": "colorgateway-vn"
}

$ aws appmesh-trial create-virtual-node \
    --mesh-name colorapp \
    --cli-input-json file://colorteller-virtualnode.json

// colorteller-virtualnode.json:
{
    "spec": {
        "listeners": [
            {
                "portMapping": {
                    "port": 9080,
                    "protocol": "http"
                },
                "healthCheck": {
                    "protocol": "http",
                    "path": "/ping",
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutMillis": 2000,
                    "intervalMillis": 5000
                }
            }
        ],
        "serviceDiscovery": {
            "dns": {
                "hostname": "colorteller.default.svc.cluster.local"
            }
        }
    },
    "virtualNodeName": "colorteller-vn"
}

Now we'll setup the VirtualRouter and an initial Route for the colorteller service.

$ aws appmesh-trial create-virtual-router \
    --mesh-name colorapp \
    --cli-input-json file://colorteller-virtualrouter.json
    
// colorteller-virtualrouter.json:
{
    "spec": {},
    "virtualRouterName": "colorteller-vr"
}

$ aws appmesh-trial create-route \
    --mesh-name colorapp \
    --virtual-router-name colorteller-vr \
    --cli-input-json file://colorteller-route.json
    
// colorteller-route.json:
{
    "routeName": "colorteller-route",
    "spec": {
        "httpRoute": {
            "action": {
                "weightedTargets": [
                    {
                        "virtualNode": "colorteller-vn",
                        "weight": 1
                    }
                ]
            },
            "match": {
                "prefix": "/"
            }
        }
    },
    "virtualRouterName": "colorteller-vr"
}

With the VirtualNodes, VirtualRouter, and Route setup, the final step is to create the VirtualService for the colorteller service and point it to the VirtualRouter by specifying it as a provider.

$ aws appmesh-trial create-virtual-service \
    --mesh-name colorapp \
    --cli-input-json file://colorteller-virtualservice.json
    
// colorteller-virtualservice.json:
{
    "spec": {
        "provider": {
            "virtualRouter": {
                "virtualRouterName": "colorteller-vr"
            }
        }
    },
    "virtualServiceName": "colorteller.default.svc.cluster.local"
}

Once the VirtualService has been created, requests made to colorteller.default.svc.cluster.local from the colorgateway VirtualNode will now be routed by the colorteller VirtualRouter to the colorteller VirtualNode.

Frequently Asked Questions

Why are we introducing this change?

The existing App Mesh APIs use the concept of a ServiceName to bind specific resources (VirtualNodes, VirtualRouters) together into a traversable service graph. A ServiceName is a fully qualified domain name (FQDN) that a client references in network calls to other services. This is used to route calls to a specific resource within Envoy Proxy, which may be discoverable by a different FQDN.

Today, there are several scenarios in the current APIs where a change to one resource's ServiceName setting may adversely affect that resource, or a different resource, with no indication of a problem to the customer. Additionally, it was discovered during the Public Preview period that the use of ServiceNames in our APIs is difficult to reason about for many customers (see #49, #71).

These changes seek to resolve the potential confusion around ServiceNames by treating the ServiceName as a first-class resource in AppMesh, which we're calling a VirtualService.

What specifically is being changed?

VirtualService

This new resource type is being introduced to formalize the existing concept of a ServiceName and provide clarity on how the entity is used within App Mesh.

This new resource type is used to point a ServiceName (e.g. “service-a.mesh.local”) to a specific networking resource (VirtualRouter, VirtualNode). Today this is done implicitly through fields on VirtualNodes and VirtualRouters. A VirtualService's name (formerly a ServiceName) points to a specific VirtualNode or VirtualRouter by way of the provider field in its spec.

This new resource type also allows customers to discover what ServiceNames exist in the mesh (i.e. aws appmesh-trial list-virtual-services), and where a particular ServiceName is pointing. Finally, it will allow a single actor to own the existing ServiceName and control how it is implemented through resource-based authorization in AWS Identity Access Management.

VirtualNode

  • The spec.backends field is being changed from a list of Strings to a list of structured objects to allow for additional upcoming features in AWS App Mesh. For example, egress policies like retries, circuit breakers, and timeouts will be available here.
// Current:
{"spec": {
    "backends": [
        "colorteller.default.svc.cluster.local"
    ]
}}

// Future:
{"spec": {
    "backends": [
        {
            "virtualService": {
                "virtualServiceName": "colorteller.default.svc.cluster.local"
            }   
        }
    ]
}}
  • The spec.serviceDiscovery.dns.serviceName field is being renamed to spec.serviceDiscovery.dns.hostname and will no longer be used as a ServiceName. The original field was used as both a ServiceName and for DNS discovery. In the new API, this field will only be used for DNS discovery. Instead of specifying an applicable ServiceName here, you can now create your VirtualService by the same name and set the VirtualNode as its provider.

VirtualRouter

  • The spec.serviceNames field is being removed. Instead of specifying applicable ServiceNames on the VirtualRouter, you can now create your VirtualService by the same name and set the VirtualRouter as its provider.

Will existing meshes still work?

Yes. Existing meshes will continue to work after the introduction of the new APIs.

Can I use the new APIs to see my existing meshes?

Yes. The new APIs were designed to work with the existing data in AWS App Mesh, and we encourage you to use the new APIs to get better clarity on how your existing mesh is configured.

Can I still use the existing APIs?

Yes. The new APIs are compatible with the existing APIs and data, so you are free to use either API during the trial period. Once the trial period is over, VirtualService will replace ServiceName.

@ewbankkit
Copy link

A couple of questions:

I see that Amazon has created Virtual Services for currently configured backends:

$ aws --region us-west-2 appmesh describe-virtual-node --mesh-name "PoC-App-Mesh" --virtual-node-name "colorgateway-vn"
{
    "virtualNode": {
        "status": {
            "status": "ACTIVE"
        },
        "meshName": "PoC-App-Mesh",
        "virtualNodeName": "colorgateway-vn",
        "spec": {
            "serviceDiscovery": {
                "dns": {
                    "serviceName": "colorgateway.mesh.svc.cluster.local"
                }
            },
            "listeners": [
                {
                    "portMapping": {
                        "protocol": "http",
                        "port": 9080
                    }
                }
            ],
            "backends": [
                "colorteller.mesh.svc.cluster.local",
                "tcpecho.mesh.svc.cluster.local"
            ]
        },
        "metadata": {
            ...
        }
    }
}

$ aws --region us-west-2 appmesh-trial describe-virtual-node --mesh-name "PoC-App-Mesh" --virtual-node-name "colorgateway-vn"
{
    "virtualNode": {
        "status": {
            "status": "ACTIVE"
        },
        "meshName": "PoC-App-Mesh",
        "virtualNodeName": "colorgateway-vn",
        "spec": {
            "serviceDiscovery": {
                "dns": {
                    "hostname": "colorgateway.mesh.svc.cluster.local"
                }
            },
            "listeners": [
                {
                    "portMapping": {
                        "protocol": "http",
                        "port": 9080
                    }
                }
            ],
            "backends": [
                {
                    "virtualService": {
                        "virtualServiceName": "colorteller.mesh.svc.cluster.local"
                    }
                },
                {
                    "virtualService": {
                        "virtualServiceName": "tcpecho.mesh.svc.cluster.local"
                    }
                }
            ]
        },
        "metadata": {
            ...
        }
    }
}

$ aws --region us-west-2 appmesh-trial describe-virtual-service --mesh-name "PoC-App-Mesh" --virtual-service-name "colorgateway.mesh.svc.cluster.local"
{
    "virtualService": {
        "status": {
            "status": "ACTIVE"
        },
        "meshName": "PoC-App-Mesh",
        "virtualServiceName": "colorgateway.mesh.svc.cluster.local",
        "spec": {},
        "metadata": {
            ...
        }
    }
}

Can we assume that there will be one new virtual service for each configured backend value and that virtual service will be named with that backend value (colorgateway.mesh.svc.cluster.local in the example above)?

Will the SDKs released on 3/7 (most of interest is the gloang SDK) just contain the new v20190125 App Mesh API, so that if I still want to use the old API version I have to use an older SDK?

@bcelenza
Copy link
Contributor Author

@ewbankkit For all backends created on the current APIs, a VirtualService will exist on the new APIs, as this is to preserve backwards compatibility with the resources themselves. However, this is not the case for backends created with the new APIs -- they will not automatically create VirtualService resources. So you can define a backend in a VirtualNode and then later create the VirtualService by that name.

Our intent is to release the SDKs on 3/7, which will include golang. Your are correct that the SDKs will only contain the 2019-01-25 version, so you'll need an older SDK if you want to stay on 2018-10-01.

@bcelenza
Copy link
Contributor Author

bcelenza commented Mar 1, 2019

Given this is already a backward incompatible change, we've decided to make one additional fix in the VirtualRouter resource to prevent blackhole routes from occurring in meshes. This change is a much smaller impact than the changes proposed here, but we'll likely roll them out at the same time to minimize overall customer impact and cognitive churn.

See #93 for the bug report, and #94 for the proposed fix. Once the proposed changes have been pushed to production, we will update the preview CLI JSON here.

@bcelenza
Copy link
Contributor Author

bcelenza commented Mar 7, 2019

These changes are now available in the following SDK versions:

CLI: 1.16.120
Java: 1.11.514
Java (V2): 2.5.5
CPP: 1.7.65
Go: 1.17.13
PHP: 3.89.0
Python: 1.9.110
JavaScript: 2.417.0
Ruby: 2.11.236
.NET: 3.3.471.0

Please let us know in a new issue if you have any questions or feedback for these new APIs.

@bcelenza bcelenza closed this as completed Mar 7, 2019
Y0Username pushed a commit to Y0Username/aws-app-mesh-examples that referenced this issue Mar 12, 2019
Y0Username pushed a commit to Y0Username/aws-app-mesh-examples that referenced this issue Mar 12, 2019
Y0Username pushed a commit to Y0Username/aws-app-mesh-examples that referenced this issue Mar 12, 2019
Y0Username pushed a commit to Y0Username/aws-app-mesh-examples that referenced this issue Mar 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants