You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Notation provides a simplified model for cloud-based and serverless architectures. Whereas AWS requires users to set up and manage things like IAM roles, security groups and integrations, Notation figures this out for users.
As such there needs to be a mapping from the Notation resource model to the cloud platform resource model.
Let’s take a simple API. In Notation the code looks like this:
This represents an orchestration graph that, hierarchically, looks like:
stateDiagram-v2
API --> API_Route_1
API --> API_Route_2
API_Route_1 --> Function
API_Route_2 --> Function
Loading
To have something that is deployable though, we want the nodes arranged according to the order in which they are deployed. The desired graph is less comprehensible, but accurately models the dependencies between services:
stateDiagram-v2
API_Route_1 --> API
API_Route_2 --> API
API_Route_1 --> Function
API_Route_2 --> Function
Loading
Conveniently, this is exactly the way dependencies are structured within the programming model. This can be demonstrated by pushing each resource onto an adjacency list when it is invoked.
Note: theoretically, the API resource and function resource can be in alternate positions if, in the code, the function gets dynamically imported after the API is instantiated. This ordering is also valid. As long as dependencies are formed by JavaScript references, any valid JavaScript code will produce valid topological ordering.
Translation
To make this translate to a cloud platform (we'll use AWS in this example), some additional services are required: an API Gateway lambda integration, an API Gateway stage, and an IAM role for the lambda.
Let’s take the example of two API endpoints that call the same serverless function. Again, for comprehensibility, we'll look at this as a hierarchical chart:
stateDiagram-v2
API --> API_Stage
API --> API_Route_1
API --> Integration_Lambda_A
API --> Permission_Lambda_A
Integration_Lambda_A --> API_Route_1
Integration_Lambda_A --> Lambda_A
Permission_Lambda_A --> Lambda_A
API --> API_Route_2
Integration_Lambda_A --> API_Route_2
Role_Attachment --> Role
Lambda_A --> Role_Attachment
Loading
At a basic level, each resource in the Notation model corresponds to an AWS resource:
API → API Gateway
API Route → API Gateway Route
Serverless Function → Lambda
However, as we see from the diagrams, the AWS model also requires several additional resources to be created and configured. Each AWS resource has both:
intrinsic or static dependencies (for example, an API Gateway resource always needs a deployment stage)
relational or dynamic dependencies (for example, a Lambda that is invoked by an API route, requires an API integration and an IAM execution role).
Furthermore, the connections between resources in the original graph are not necessarily preserved when mapped to the AWS model. For example, in the AWS model, the API route does not connect directly to the lambda, rather, the connection is formed via an API integration.
Approach
If Notation’s ambition was to only solve certain architectures (such as connecting API Gateway to Lambda), then it could do resource mapping using a template-based pattern.
However, the aim is to support multiple architectures, so a general purpose mapping solution is desired. Creating these kinds of mappings will be such a common task as the framework grows to support more services, there should be a good model to implement them.
It will also be beneficial for the generated AWS resource graph to preserve a reference to the source Notation resource graph, so that developers can see how the mapping works.
Solution
The generated graph represents the original Notation resource node as resource groups, and the resources within them are the AWS resource that will be provisioned. The connections between resources should represent their dependencies.
flowchart LR
subgraph API
API_Stage --> API_Gateway
end
subgraph API_Route_1
API_Gateway_Route_1 --> API_Gateway
end
subgraph API_Route_2
API_Gateway_Route_2 --> API_Gateway
end
subgraph Function
Integration_Lambda_A --> API_Gateway
Permission_Lambda_A --> API_Gateway
Integration_Lambda_A --> Lambda_A
Permission_Lambda_A --> Lambda_A
Role_Attachment --> Role
Lambda_A --> Role_Attachment
end
API_Gateway_Route_2 --> Integration_Lambda_A
API_Gateway_Route_1 --> Integration_Lambda_A
Loading
Grouping Rules
Although the API integration and lambda permission exist only because the lambda is connected to an API route, the resources are grouped within the function subgroup. There is primarily because there is one of each resource per lambda, irrespective of how many API routes connect to the lambda. This is also how the associations are represented in the AWS console.
Connections
There are a couple of approaches to forming connections, while traversing each node:
Looks for parent resource groups to determine if additional resources are required e.g. a Notation function resource group has an API route as a parent, therefore it should also create an integration and permission
Look for children resource groups, and, if required, creates additional resources in them e.g. a Notation API route resource group has a function child, so, if they have not already been created, it should also creates an integration and permission (or, by inversion of control, ask the function resource group to create them)
The second approach has the key advantage of not requiring a complete traversal of the Notation resource graph in order to assign a resource groups parents.
It is also relatively straight forward to implement:
At each stage, because of the natural topological ordering, the dependent resource groups and resources are in scope.
Future Challenges
Additional complexities might include:
External factors that determine the creation of additional resources (such as creating additional API stages for staging deployments)
Implicit dependencies, for example, an API stage needing to be deployed after the API routes are created, even though the stage is not explicitly connected to the routes
If the creation of a resource depends on the configuration of a resource multiple levels of the dependency chain
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Context
Notation provides a simplified model for cloud-based and serverless architectures. Whereas AWS requires users to set up and manage things like IAM roles, security groups and integrations, Notation figures this out for users.
As such there needs to be a mapping from the Notation resource model to the cloud platform resource model.
Let’s take a simple API. In Notation the code looks like this:
This represents an orchestration graph that, hierarchically, looks like:
To have something that is deployable though, we want the nodes arranged according to the order in which they are deployed. The desired graph is less comprehensible, but accurately models the dependencies between services:
Conveniently, this is exactly the way dependencies are structured within the programming model. This can be demonstrated by pushing each resource onto an adjacency list when it is invoked.
Note: theoretically, the API resource and function resource can be in alternate positions if, in the code, the function gets dynamically imported after the API is instantiated. This ordering is also valid. As long as dependencies are formed by JavaScript references, any valid JavaScript code will produce valid topological ordering.
Translation
To make this translate to a cloud platform (we'll use AWS in this example), some additional services are required: an API Gateway lambda integration, an API Gateway stage, and an IAM role for the lambda.
Let’s take the example of two API endpoints that call the same serverless function. Again, for comprehensibility, we'll look at this as a hierarchical chart:
stateDiagram-v2 API --> API_Stage API --> API_Route_1 API --> Integration_Lambda_A API --> Permission_Lambda_A Integration_Lambda_A --> API_Route_1 Integration_Lambda_A --> Lambda_A Permission_Lambda_A --> Lambda_A API --> API_Route_2 Integration_Lambda_A --> API_Route_2 Role_Attachment --> Role Lambda_A --> Role_AttachmentAt a basic level, each resource in the Notation model corresponds to an AWS resource:
However, as we see from the diagrams, the AWS model also requires several additional resources to be created and configured. Each AWS resource has both:
Furthermore, the connections between resources in the original graph are not necessarily preserved when mapped to the AWS model. For example, in the AWS model, the API route does not connect directly to the lambda, rather, the connection is formed via an API integration.
Approach
If Notation’s ambition was to only solve certain architectures (such as connecting API Gateway to Lambda), then it could do resource mapping using a template-based pattern.
However, the aim is to support multiple architectures, so a general purpose mapping solution is desired. Creating these kinds of mappings will be such a common task as the framework grows to support more services, there should be a good model to implement them.
It will also be beneficial for the generated AWS resource graph to preserve a reference to the source Notation resource graph, so that developers can see how the mapping works.
Solution
The generated graph represents the original Notation resource node as resource groups, and the resources within them are the AWS resource that will be provisioned. The connections between resources should represent their dependencies.
flowchart LR subgraph API API_Stage --> API_Gateway end subgraph API_Route_1 API_Gateway_Route_1 --> API_Gateway end subgraph API_Route_2 API_Gateway_Route_2 --> API_Gateway end subgraph Function Integration_Lambda_A --> API_Gateway Permission_Lambda_A --> API_Gateway Integration_Lambda_A --> Lambda_A Permission_Lambda_A --> Lambda_A Role_Attachment --> Role Lambda_A --> Role_Attachment end API_Gateway_Route_2 --> Integration_Lambda_A API_Gateway_Route_1 --> Integration_Lambda_AGrouping Rules
Although the API integration and lambda permission exist only because the lambda is connected to an API route, the resources are grouped within the function subgroup. There is primarily because there is one of each resource per lambda, irrespective of how many API routes connect to the lambda. This is also how the associations are represented in the AWS console.
Connections
There are a couple of approaches to forming connections, while traversing each node:
The second approach has the key advantage of not requiring a complete traversal of the Notation resource graph in order to assign a resource groups parents.
It is also relatively straight forward to implement:
At each stage, because of the natural topological ordering, the dependent resource groups and resources are in scope.
Future Challenges
Additional complexities might include:
All reactions