From 9557ce283c4ff6ee8b6e254953aa771aafb2dfdf Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 23 May 2023 22:46:55 +1200 Subject: [PATCH 01/31] Adding RFC for Issue 502, aws-vpclattice --- text/vpclattice_rfc_502.md | 348 +++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 text/vpclattice_rfc_502.md diff --git a/text/vpclattice_rfc_502.md b/text/vpclattice_rfc_502.md new file mode 100644 index 000000000..4097c8353 --- /dev/null +++ b/text/vpclattice_rfc_502.md @@ -0,0 +1,348 @@ +# L2 Constructs for AWS VpcLattice + +**Status:** (DRAFT) + +* **Original Author(s):** @mrpackethead, +, @taylaand, @nbaillie +* **Tracking Issue:** #502 +* **API Bar Raiser:** @TheRealAmazonKendra + +This RFC proposes a new L2 module for CDK to support AWS VPC Lattice. + +--- +## PUBLIC ISSUES +* (vpclattice): L2 for Amazon VPC Lattice #25452 + +## Prototype Code: +https://github.com/raindancers/latticeplay +https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha + +--- +## VpcLattice + +Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. + +The resources, that are required by lattice broadly fall into two catagories +* those are a associated with the creation of a Lattice Service network, its access and logging +* those that are associated with the the **services** that the applicaton network will deliver. + +## Quick Overview / Example. + +All vpcLattice applications networks require a service network. + +```typescript +import { ServiceNetwork } from '@aws-cdk/aws-vpclattice-alpha'; + +const myServiceNetwork: ServiceNetwork; +myServiceNetwork = new ServiceNetwork(this, 'myserviceNetwork, { + name: 'mylatticenetwork', +}); +``` +Optionally an authentication policy can be added to the service network, Typically access policies for the Service Network are +coarse such as allowing particular accounts to use the service network. Note: the `.addLaticeAuthPolicy()` method provides defaults for +resources, actions and effect + +```typescript +myServiceNetwork.addLatticeAuthPolicy( + [ + new iam.PolicyStatement({ + principal: new iam.AccountPrincipal('12345678900') + }), + ] +); + iam.policyDocument: iam.PolicyStatement[]): void; +``` +The service can be configured to log to S3, Stream to kinesis, or use Cloudwatch with the `.logToS3()`, `sendToCloudWatch()` or `streamtoKinesis()` methods. + +```typescript +const loggingbucket: S3.Bucket +myServiceNetwork.logToS3(loggingbucket) +``` + +The service Network can be Shared using RAM using the `.share()` method + +```typescript +myServiceNetwork.share({ + name: 'myserviceshare', + allowExternalPrincipals: false, + principals: new iam.AccountPrincipal('12345678900') +}) +``` +In order to access a service network a vpc must be associated with a vpc. +Optionally security groups can be applied. +For vpcs, in the same account as the Servicenetwork; +```typescript +const vpc: ec2.Vpc; +const securityGroup: ec2.SecurityGroup +myServiceNetwork.associateVPC(vpc, [securityGroups]) +}) +``` +Cross account +```typescript +const vpc: ec2.Vpc; +const securityGroup: ec2.SecurityGroup; +cosnt serviceNetwork = ServiceNetwork.importFromName('mylatticenetwork') +myServiceNetwork.associateVPC(vpc, [securityGroups]) +``` + +## 2. Create a service + +A lattice service is the 'front' for various applicaitons that might be 'served' by AWS resources such +as ec2 Instances, Applicaiton Load Balancers, Lambdas. Listeners are attached to the service, which have rules and targets. + +```typescript +import { Service, Protocol, FixedResponse } from '@aws-cdk/aws-vpclattice-alpha'; + + +const myService: Service = new Service(this, 'myservice', { + name: 'myservice', +}) +``` + +Add a listner to the service, with a certificate, a hostname and DNS +```typescript +const myCertificate: certificate_manager.Certificate +const serviceListener: lattice.Listener = myService.addListener( + defaultAction: FixedResponse.NOT_FOUND + protocol: Protocol.HTTPS, + name: 'MyServiceListener' +) +myService.addCertificate(myCertificate); +myService.addCustomDomain('example.org'); +myService.addDNSEntry('abcdef'); +``` + +Create targets which will provide the 'content' for your service, in this example +we target a lambda. Then use the target in a Rule that is attached to the Listener. + +```typescript +const functionOne: aws_lambda.Function + +const targetOne = new lattice.LatticeTargetGroup(this, 'TargetOne', { + name: 'targetgroupOne', + lambdaTargets: [ + functionOne + ], +}) + +serviceListener.addListenerRule({ + name: 'listentolambdaone', + action: [{ target: targetOne }], + priority: 100, + pathMatch: { + pathMatchType: lattice.PathMatchType.EXACT, + matchValue: '/serviceOne', + caseSensitive: false, + } +}) + +``` +3. Finally, add the Service to the the Service Network +```typescript +serviceNetwork.addService(myService) +``` + +## API Design +The following API design is proposed + +#### Listener +```typescript +export interface IListener extends core.IResource { + /** + * The Amazon Resource Name (ARN) of the service. + */ + readonly listenerArn: string; + /** + * The Id of the Service Network + */ + readonly listenerId: string; + + /** + * Add A Listener Rule to the Listener + */ + addListenerRule(props: AddRuleProps): void; +} +``` + +#### Service +```typescript +export interface IService extends core.IResource { + /** + * The Amazon Resource Name (ARN) of the service. + */ + readonly serviceArn: string; + /** + * The Id of the Service Network + */ + readonly serviceId: string; + + /** + * Add An Authentication Policy to the Service. + * @param policyStatement[]; + */ + addLatticeAuthPolicy(policyStatement: iam.PolicyStatement[]): iam.PolicyDocument; + /** + * Add A vpc listener to the Service. + * @param props + */ + addListener(props: vpclattice.ListenerProps): vpclattice.Listener; + /** + * Share the service to other accounts via RAM + * @param props + */ + share(props: ShareServiceProps): void; + + /** + * Create a DNS entry in R53 for the service. + */ + addDNSEntry(props: aws_vpclattice.CfnService.DnsEntryProperty): void; + + /** + * Add a certificate to the service + * @param certificate + */ + addCertificate(certificate: certificatemanager.Certificate): void; + + /** + * add a custom domain to the service + * @param domain + */ + addCustomDomain(domain: string): void; + + /** + * add a name for the service + * @default cloudformation will provide a name + */ + addName(name: string): void; + /** + * add Tags to the service + * @deafult + */ + +} +``` +#### ServiceNetwork +```typescript +/** + * Create a vpc lattice service network. + * Implemented by `ServiceNetwork`. + */ +export interface IServiceNetwork extends core.IResource { + + /** + * The Amazon Resource Name (ARN) of the service network. + */ + readonly serviceNetworkArn: string; + + /** + * The Id of the Service Network + */ + readonly serviceNetworkId: string; + /** + * Add LatticeAuthPolicy + */ + addLatticeAuthPolicy(policyDocument: iam.PolicyStatement[]): void; + /** + * Add Lattice Service Policy + */ + addService(service: vpclattice.Service): void; + /** + * Associate a VPC with the Service Network + */ + associateVPC(vpc: ec2.Vpc, securityGroups: ec2.SecurityGroup[]): void; + /** + * Log To S3 + */ + logToS3(bucket: s3.Bucket | s3.IBucket ): void; + /** + * Send Events to Cloud Watch + */ + sendToCloudWatch(log: logs.LogGroup | logs.ILogGroup ): void; + /** + * Stream to Kinesis + */ + streamToKinesis(stream: kinesis.Stream | kinesis.IStream ): void; + /** + * Share the ServiceNetwork + */ + share(props: ShareServiceNetworkProps): void; + +} +``` +#### TargetGroups +```typescript +/** + * Create a vpc lattice TargetGroup. + * Implemented by `TargetGroup`. + */ +export interface ITargetGroup extends core.IResource { + /** + * The id of the target group + */ + readonly targetGroupId: string + /** + * The Arn of the target group + */ + readonly targetGroupArn: string; +} +``` + + + + + + +## SCRUM - USER STORIES + +As a consumer of cdk constructs I would like a L2 CDK Construct for Aws Lattice that; +* Is intuitive, and consistent with the general approach of cdk, and the service documentation. +* Abstracts the underlying complexities of the lattice service so, it is easy to concentrate on the solution. +* Integration between this construct and other CDK constructs +* Apply secure, best practice configurations as default + +As a Service Owner I would like to: +* Publish my service for others to access +* Control Authentication and Authorisation for my services +* Control load distribution across my compute resources +* Hide the implementation detail of my services from consumers + +As a Service Consumer I would like to: +* Be able have my resources use services that are available to me in my VPCs +* Authenticate with services +* Restrict access for services to security groups that I decide + +As a Platform/Network Admin I would like to: +* Create Service Networks for Owners and Consumers to use + +*** + + + +## FAQ + +### What is the scope of this RFC? + +This RFC Provides Classes and Methods to implement The VPC Lattice Service. +This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). + +### Why should I use this construct? + +This CDK L2 Construct can be used to deploy resources from [Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/what-is-vpc-service-network.html). VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). + + +You can check common [Amazon VPC Lattice Reference Architectures](https://d1.awsstatic.com/architecture-diagrams/ArchitectureDiagrams/lattice-use-cases-ra.pdf) to understand the different use cases you can build with the AWS service. +Examples of use for these constructs, are at ..... + + +* [vpc-lattice-an-implementation-of-kubernetes](https://aws.amazon.com/blogs/containers/introducing-aws-gateway-api-controller-for-amazon-vpc-lattice-an-implementation-of-kubernetes-gateway-api/) + +### Is this a breaking change? + +* No this will not break exisiting CDK functionality. + + +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the `api-approved` label was applied to the RFC pull request): + + +`[ ]` Signed-off by API Bar Raiser @TheRealAmazonKendra + From cd8c8aafd5194629bb92f0fffa73444d450d9893 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 23 May 2023 22:50:08 +1200 Subject: [PATCH 02/31] Update README.md Added RFC 502 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2ac461ea7..c147faeb4 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ future state of the libraries and to discover projects for contribution. [456](https://github.com/aws/aws-cdk-rfcs/issues/456)|[L2 ElastiCache support](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0456-elasticache-l2.md)||👷 implementing [460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing [457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning +[502](https://github.com/aws/aws-cdk-rfcs/issues/502)|[L2 Constructs for vpcLattice](https://github.com/aws/aws-cdk-rfcs/issues/502)||💡 proposed [8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review [175](https://github.com/aws/aws-cdk-rfcs/issues/175)|[AppSync Mapping Template Object Model](https://github.com/aws/aws-cdk-rfcs/pull/177)|[@MrArnoldPalmer](https://github.com/MrArnoldPalmer)|✍️ review [317](https://github.com/aws/aws-cdk-rfcs/issues/317)|[CDK third-party dependencies management](https://github.com/aws/aws-cdk-rfcs/issues/317)||✍️ review From 0e7a14388de9cc2447e6452b94bbd2c92d4c3db5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 24 May 2023 08:24:36 +1200 Subject: [PATCH 03/31] Update vpclattice_rfc_502.md Add fromServiceNetworkAttributes for Service, --- text/vpclattice_rfc_502.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/text/vpclattice_rfc_502.md b/text/vpclattice_rfc_502.md index 4097c8353..7fb29c19e 100644 --- a/text/vpclattice_rfc_502.md +++ b/text/vpclattice_rfc_502.md @@ -28,7 +28,8 @@ The resources, that are required by lattice broadly fall into two catagories ## Quick Overview / Example. -All vpcLattice applications networks require a service network. +#### Create a Service Network, and allow access from a VPC + ```typescript import { ServiceNetwork } from '@aws-cdk/aws-vpclattice-alpha'; @@ -85,7 +86,7 @@ cosnt serviceNetwork = ServiceNetwork.importFromName('mylatticenetwork') myServiceNetwork.associateVPC(vpc, [securityGroups]) ``` -## 2. Create a service +#### Create a service from a Lambda and associate it with the Service A lattice service is the 'front' for various applicaitons that might be 'served' by AWS resources such as ec2 Instances, Applicaiton Load Balancers, Lambdas. Listeners are attached to the service, which have rules and targets. @@ -147,6 +148,10 @@ The following API design is proposed #### Listener ```typescript +/** + * Create a vpcLattice Listener. + * Implemented by `Listener`. + */ export interface IListener extends core.IResource { /** * The Amazon Resource Name (ARN) of the service. @@ -158,7 +163,7 @@ export interface IListener extends core.IResource { readonly listenerId: string; /** - * Add A Listener Rule to the Listener + * Add A Rule to the Listener */ addListenerRule(props: AddRuleProps): void; } @@ -166,6 +171,10 @@ export interface IListener extends core.IResource { #### Service ```typescript +/** + * Create a vpcLattice service. + * Implemented by `Service`. + */ export interface IService extends core.IResource { /** * The Amazon Resource Name (ARN) of the service. @@ -215,9 +224,10 @@ export interface IService extends core.IResource { */ addName(name: string): void; /** - * add Tags to the service + *grant a Principal access to a Services Path * @deafult */ + grantAccess(props: grantAccessProps): void; } ``` @@ -225,7 +235,7 @@ export interface IService extends core.IResource { ```typescript /** * Create a vpc lattice service network. - * Implemented by `ServiceNetwork`. + * Implemented by `ServiceNetwork` */ export interface IServiceNetwork extends core.IResource { @@ -266,6 +276,12 @@ export interface IServiceNetwork extends core.IResource { * Share the ServiceNetwork */ share(props: ShareServiceNetworkProps): void; + /** + * Create a service network from Attributes. + * This function only needs to be used when it is not possible to pass + * a ServiceNetwork between cdk apps or stacks. + */ + fromServiceNetworkAttributes(attrs: ServiceNetworkAttributes): void; } ``` From 7d56e7dbd60aee0b71082835ed116b55e0362b76 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 24 May 2023 08:25:27 +1200 Subject: [PATCH 04/31] Update vpclattice_rfc_502.md --- text/vpclattice_rfc_502.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/vpclattice_rfc_502.md b/text/vpclattice_rfc_502.md index 7fb29c19e..9ed5d408d 100644 --- a/text/vpclattice_rfc_502.md +++ b/text/vpclattice_rfc_502.md @@ -26,7 +26,7 @@ The resources, that are required by lattice broadly fall into two catagories * those are a associated with the creation of a Lattice Service network, its access and logging * those that are associated with the the **services** that the applicaton network will deliver. -## Quick Overview / Example. +## Example Implementation #### Create a Service Network, and allow access from a VPC From d7f69e2cf22e4b4f0973827bf50843b8357747f1 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 24 May 2023 08:27:19 +1200 Subject: [PATCH 05/31] Create 0502_aws-vpclattice.md Renamed File --- text/0502_aws-vpclattice.md | 363 ++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 text/0502_aws-vpclattice.md diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md new file mode 100644 index 000000000..0a0808942 --- /dev/null +++ b/text/0502_aws-vpclattice.md @@ -0,0 +1,363 @@ +# L2 Constructs for AWS VpcLattice + +**Status:** (DRAFT) + +* **Original Author(s):** @mrpackethead, +, @taylaand, @nbaillie +* **Tracking Issue:** #502 +* **API Bar Raiser:** @TheRealAmazonKendra + +This RFC proposes a new L2 module for CDK to support AWS VPC Lattice. + +--- +## PUBLIC ISSUES +* (vpclattice): L2 for Amazon VPC Lattice #25452 + +## Prototype Code: +https://github.com/raindancers/latticeplay +https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha + +--- +## VpcLattice + +Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. + +The resources, that are required by lattice broadly fall into two catagories +* those are a associated with the creation of a Lattice Service network, its access and logging +* those that are associated with the the **services** that the applicaton network will deliver. + +## Example Implementation + +#### Create a Service Network, and allow access from a VPC + + +```typescript +import { ServiceNetwork } from '@aws-cdk/aws-vpclattice-alpha'; + +const myServiceNetwork: ServiceNetwork; +myServiceNetwork = new ServiceNetwork(this, 'myserviceNetwork, { + name: 'mylatticenetwork', +}); +``` +Optionally an authentication policy can be added to the service network, Typically access policies for the Service Network are +coarse such as allowing particular accounts to use the service network. Note: the `.addLaticeAuthPolicy()` method provides defaults for +resources, actions and effect + +```typescript +myServiceNetwork.addLatticeAuthPolicy( + [ + new iam.PolicyStatement({ + principal: new iam.AccountPrincipal('12345678900') + }), + ] +); + iam.policyDocument: iam.PolicyStatement[]): void; +``` +The service can be configured to log to S3, Stream to kinesis, or use Cloudwatch with the `.logToS3()`, `sendToCloudWatch()` or `streamtoKinesis()` methods. + +```typescript +const loggingbucket: S3.Bucket +myServiceNetwork.logToS3(loggingbucket) +``` + +The service Network can be Shared using RAM using the `.share()` method + +```typescript +myServiceNetwork.share({ + name: 'myserviceshare', + allowExternalPrincipals: false, + principals: new iam.AccountPrincipal('12345678900') +}) +``` +In order to access a service network a vpc must be associated with a vpc. +Optionally security groups can be applied. +For vpcs, in the same account as the Servicenetwork; +```typescript +const vpc: ec2.Vpc; +const securityGroup: ec2.SecurityGroup +myServiceNetwork.associateVPC(vpc, [securityGroups]) +}) +``` +Cross account +```typescript +const vpc: ec2.Vpc; +const securityGroup: ec2.SecurityGroup; +cosnt serviceNetwork = ServiceNetwork.importFromName('mylatticenetwork') +myServiceNetwork.associateVPC(vpc, [securityGroups]) +``` + +#### Create a service from a Lambda and associate it with the Service + +A lattice service is the 'front' for various applicaitons that might be 'served' by AWS resources such +as ec2 Instances, Applicaiton Load Balancers, Lambdas. Listeners are attached to the service, which have rules and targets. + +```typescript +import { Service, Protocol, FixedResponse } from '@aws-cdk/aws-vpclattice-alpha'; + + +const myService: Service = new Service(this, 'myservice', { + name: 'myservice', +}) +``` + +Add a listner to the service, with a certificate, a hostname and DNS +```typescript +const myCertificate: certificate_manager.Certificate +const serviceListener: lattice.Listener = myService.addListener( + defaultAction: FixedResponse.NOT_FOUND + protocol: Protocol.HTTPS, + name: 'MyServiceListener' +) +myService.addCertificate(myCertificate); +myService.addCustomDomain('example.org'); +myService.addDNSEntry('abcdef'); +``` + +Create targets which will provide the 'content' for your service, in this example +we target a lambda. Then use the target in a Rule that is attached to the Listener. + +```typescript +const functionOne: aws_lambda.Function + +const targetOne = new lattice.LatticeTargetGroup(this, 'TargetOne', { + name: 'targetgroupOne', + lambdaTargets: [ + functionOne + ], +}) + +serviceListener.addListenerRule({ + name: 'listentolambdaone', + action: [{ target: targetOne }], + priority: 100, + pathMatch: { + pathMatchType: lattice.PathMatchType.EXACT, + matchValue: '/serviceOne', + caseSensitive: false, + } +}) + +``` +3. Finally, add the Service to the the Service Network +```typescript +serviceNetwork.addService(myService) +``` + +## API Design +The following API design is proposed + +#### Listener +```typescript +/** + * Create a vpcLattice Listener. + * Implemented by `Listener`. + */ +export interface IListener extends core.IResource { + /** + * The Amazon Resource Name (ARN) of the service. + */ + readonly listenerArn: string; + /** + * The Id of the Service Network + */ + readonly listenerId: string; + + /** + * Add A Rule to the Listener + */ + addListenerRule(props: AddRuleProps): void; +} +``` + +#### Service +```typescript +/** + * Create a vpcLattice service. + * Implemented by `Service`. + */ +export interface IService extends core.IResource { + /** + * The Amazon Resource Name (ARN) of the service. + */ + readonly serviceArn: string; + /** + * The Id of the Service Network + */ + readonly serviceId: string; + + /** + * Add An Authentication Policy to the Service. + * @param policyStatement[]; + */ + addLatticeAuthPolicy(policyStatement: iam.PolicyStatement[]): iam.PolicyDocument; + /** + * Add A vpc listener to the Service. + * @param props + */ + addListener(props: vpclattice.ListenerProps): vpclattice.Listener; + /** + * Share the service to other accounts via RAM + * @param props + */ + share(props: ShareServiceProps): void; + + /** + * Create a DNS entry in R53 for the service. + */ + addDNSEntry(props: aws_vpclattice.CfnService.DnsEntryProperty): void; + + /** + * Add a certificate to the service + * @param certificate + */ + addCertificate(certificate: certificatemanager.Certificate): void; + + /** + * add a custom domain to the service + * @param domain + */ + addCustomDomain(domain: string): void; + + /** + * add a name for the service + * @default cloudformation will provide a name + */ + addName(name: string): void; + /** + *grant a Principal access to a Services Path + * @deafult + */ + grantAccess(props: grantAccessProps): void; + +} +``` +#### ServiceNetwork +```typescript +/** + * Create a vpc lattice service network. + * Implemented by `ServiceNetwork` + */ +export interface IServiceNetwork extends core.IResource { + + /** + * The Amazon Resource Name (ARN) of the service network. + */ + readonly serviceNetworkArn: string; + + /** + * The Id of the Service Network + */ + readonly serviceNetworkId: string; + /** + * Add LatticeAuthPolicy + */ + addLatticeAuthPolicy(policyDocument: iam.PolicyStatement[]): void; + /** + * Add Lattice Service Policy + */ + addService(service: vpclattice.Service): void; + /** + * Associate a VPC with the Service Network + */ + associateVPC(vpc: ec2.Vpc, securityGroups: ec2.SecurityGroup[]): void; + /** + * Log To S3 + */ + logToS3(bucket: s3.Bucket | s3.IBucket ): void; + /** + * Send Events to Cloud Watch + */ + sendToCloudWatch(log: logs.LogGroup | logs.ILogGroup ): void; + /** + * Stream to Kinesis + */ + streamToKinesis(stream: kinesis.Stream | kinesis.IStream ): void; + /** + * Share the ServiceNetwork + */ + share(props: ShareServiceNetworkProps): void; + /** + * Create a service network from Attributes. + * This function only needs to be used when it is not possible to pass + * a ServiceNetwork between cdk apps or stacks. + */ + fromServiceNetworkAttributes(attrs: ServiceNetworkAttributes): void; + +} +``` +#### TargetGroups +```typescript +/** + * Create a vpc lattice TargetGroup. + * Implemented by `TargetGroup`. + */ +export interface ITargetGroup extends core.IResource { + /** + * The id of the target group + */ + readonly targetGroupId: string + /** + * The Arn of the target group + */ + readonly targetGroupArn: string; +} +``` + + + + + + +## SCRUM - USER STORIES + +As a consumer of cdk constructs I would like a L2 CDK Construct for Aws Lattice that; +* Is intuitive, and consistent with the general approach of cdk, and the service documentation. +* Abstracts the underlying complexities of the lattice service so, it is easy to concentrate on the solution. +* Integration between this construct and other CDK constructs +* Apply secure, best practice configurations as default + +As a Service Owner I would like to: +* Publish my service for others to access +* Control Authentication and Authorisation for my services +* Control load distribution across my compute resources +* Hide the implementation detail of my services from consumers + +As a Service Consumer I would like to: +* Be able have my resources use services that are available to me in my VPCs +* Authenticate with services +* Restrict access for services to security groups that I decide + +As a Platform/Network Admin I would like to: +* Create Service Networks for Owners and Consumers to use + +*** + + + +## FAQ + +### What is the scope of this RFC? + +This RFC Provides Classes and Methods to implement The VPC Lattice Service. +This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). + +### Why should I use this construct? + +This CDK L2 Construct can be used to deploy resources from [Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/what-is-vpc-service-network.html). VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). + + +You can check common [Amazon VPC Lattice Reference Architectures](https://d1.awsstatic.com/architecture-diagrams/ArchitectureDiagrams/lattice-use-cases-ra.pdf) to understand the different use cases you can build with the AWS service. +Examples of use for these constructs, are at ..... + + +* [vpc-lattice-an-implementation-of-kubernetes](https://aws.amazon.com/blogs/containers/introducing-aws-gateway-api-controller-for-amazon-vpc-lattice-an-implementation-of-kubernetes-gateway-api/) + +### Is this a breaking change? + +* No this will not break exisiting CDK functionality. + + +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the `api-approved` label was applied to the RFC pull request): + + +`[ ]` Signed-off by API Bar Raiser @TheRealAmazonKendra From e7ac49d80ce339eaebed199a41baff804b3e19fd Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 24 May 2023 08:29:51 +1200 Subject: [PATCH 06/31] Delete vpclattice_rfc_502.md --- text/vpclattice_rfc_502.md | 364 ------------------------------------- 1 file changed, 364 deletions(-) delete mode 100644 text/vpclattice_rfc_502.md diff --git a/text/vpclattice_rfc_502.md b/text/vpclattice_rfc_502.md deleted file mode 100644 index 9ed5d408d..000000000 --- a/text/vpclattice_rfc_502.md +++ /dev/null @@ -1,364 +0,0 @@ -# L2 Constructs for AWS VpcLattice - -**Status:** (DRAFT) - -* **Original Author(s):** @mrpackethead, -, @taylaand, @nbaillie -* **Tracking Issue:** #502 -* **API Bar Raiser:** @TheRealAmazonKendra - -This RFC proposes a new L2 module for CDK to support AWS VPC Lattice. - ---- -## PUBLIC ISSUES -* (vpclattice): L2 for Amazon VPC Lattice #25452 - -## Prototype Code: -https://github.com/raindancers/latticeplay -https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha - ---- -## VpcLattice - -Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. - -The resources, that are required by lattice broadly fall into two catagories -* those are a associated with the creation of a Lattice Service network, its access and logging -* those that are associated with the the **services** that the applicaton network will deliver. - -## Example Implementation - -#### Create a Service Network, and allow access from a VPC - - -```typescript -import { ServiceNetwork } from '@aws-cdk/aws-vpclattice-alpha'; - -const myServiceNetwork: ServiceNetwork; -myServiceNetwork = new ServiceNetwork(this, 'myserviceNetwork, { - name: 'mylatticenetwork', -}); -``` -Optionally an authentication policy can be added to the service network, Typically access policies for the Service Network are -coarse such as allowing particular accounts to use the service network. Note: the `.addLaticeAuthPolicy()` method provides defaults for -resources, actions and effect - -```typescript -myServiceNetwork.addLatticeAuthPolicy( - [ - new iam.PolicyStatement({ - principal: new iam.AccountPrincipal('12345678900') - }), - ] -); - iam.policyDocument: iam.PolicyStatement[]): void; -``` -The service can be configured to log to S3, Stream to kinesis, or use Cloudwatch with the `.logToS3()`, `sendToCloudWatch()` or `streamtoKinesis()` methods. - -```typescript -const loggingbucket: S3.Bucket -myServiceNetwork.logToS3(loggingbucket) -``` - -The service Network can be Shared using RAM using the `.share()` method - -```typescript -myServiceNetwork.share({ - name: 'myserviceshare', - allowExternalPrincipals: false, - principals: new iam.AccountPrincipal('12345678900') -}) -``` -In order to access a service network a vpc must be associated with a vpc. -Optionally security groups can be applied. -For vpcs, in the same account as the Servicenetwork; -```typescript -const vpc: ec2.Vpc; -const securityGroup: ec2.SecurityGroup -myServiceNetwork.associateVPC(vpc, [securityGroups]) -}) -``` -Cross account -```typescript -const vpc: ec2.Vpc; -const securityGroup: ec2.SecurityGroup; -cosnt serviceNetwork = ServiceNetwork.importFromName('mylatticenetwork') -myServiceNetwork.associateVPC(vpc, [securityGroups]) -``` - -#### Create a service from a Lambda and associate it with the Service - -A lattice service is the 'front' for various applicaitons that might be 'served' by AWS resources such -as ec2 Instances, Applicaiton Load Balancers, Lambdas. Listeners are attached to the service, which have rules and targets. - -```typescript -import { Service, Protocol, FixedResponse } from '@aws-cdk/aws-vpclattice-alpha'; - - -const myService: Service = new Service(this, 'myservice', { - name: 'myservice', -}) -``` - -Add a listner to the service, with a certificate, a hostname and DNS -```typescript -const myCertificate: certificate_manager.Certificate -const serviceListener: lattice.Listener = myService.addListener( - defaultAction: FixedResponse.NOT_FOUND - protocol: Protocol.HTTPS, - name: 'MyServiceListener' -) -myService.addCertificate(myCertificate); -myService.addCustomDomain('example.org'); -myService.addDNSEntry('abcdef'); -``` - -Create targets which will provide the 'content' for your service, in this example -we target a lambda. Then use the target in a Rule that is attached to the Listener. - -```typescript -const functionOne: aws_lambda.Function - -const targetOne = new lattice.LatticeTargetGroup(this, 'TargetOne', { - name: 'targetgroupOne', - lambdaTargets: [ - functionOne - ], -}) - -serviceListener.addListenerRule({ - name: 'listentolambdaone', - action: [{ target: targetOne }], - priority: 100, - pathMatch: { - pathMatchType: lattice.PathMatchType.EXACT, - matchValue: '/serviceOne', - caseSensitive: false, - } -}) - -``` -3. Finally, add the Service to the the Service Network -```typescript -serviceNetwork.addService(myService) -``` - -## API Design -The following API design is proposed - -#### Listener -```typescript -/** - * Create a vpcLattice Listener. - * Implemented by `Listener`. - */ -export interface IListener extends core.IResource { - /** - * The Amazon Resource Name (ARN) of the service. - */ - readonly listenerArn: string; - /** - * The Id of the Service Network - */ - readonly listenerId: string; - - /** - * Add A Rule to the Listener - */ - addListenerRule(props: AddRuleProps): void; -} -``` - -#### Service -```typescript -/** - * Create a vpcLattice service. - * Implemented by `Service`. - */ -export interface IService extends core.IResource { - /** - * The Amazon Resource Name (ARN) of the service. - */ - readonly serviceArn: string; - /** - * The Id of the Service Network - */ - readonly serviceId: string; - - /** - * Add An Authentication Policy to the Service. - * @param policyStatement[]; - */ - addLatticeAuthPolicy(policyStatement: iam.PolicyStatement[]): iam.PolicyDocument; - /** - * Add A vpc listener to the Service. - * @param props - */ - addListener(props: vpclattice.ListenerProps): vpclattice.Listener; - /** - * Share the service to other accounts via RAM - * @param props - */ - share(props: ShareServiceProps): void; - - /** - * Create a DNS entry in R53 for the service. - */ - addDNSEntry(props: aws_vpclattice.CfnService.DnsEntryProperty): void; - - /** - * Add a certificate to the service - * @param certificate - */ - addCertificate(certificate: certificatemanager.Certificate): void; - - /** - * add a custom domain to the service - * @param domain - */ - addCustomDomain(domain: string): void; - - /** - * add a name for the service - * @default cloudformation will provide a name - */ - addName(name: string): void; - /** - *grant a Principal access to a Services Path - * @deafult - */ - grantAccess(props: grantAccessProps): void; - -} -``` -#### ServiceNetwork -```typescript -/** - * Create a vpc lattice service network. - * Implemented by `ServiceNetwork` - */ -export interface IServiceNetwork extends core.IResource { - - /** - * The Amazon Resource Name (ARN) of the service network. - */ - readonly serviceNetworkArn: string; - - /** - * The Id of the Service Network - */ - readonly serviceNetworkId: string; - /** - * Add LatticeAuthPolicy - */ - addLatticeAuthPolicy(policyDocument: iam.PolicyStatement[]): void; - /** - * Add Lattice Service Policy - */ - addService(service: vpclattice.Service): void; - /** - * Associate a VPC with the Service Network - */ - associateVPC(vpc: ec2.Vpc, securityGroups: ec2.SecurityGroup[]): void; - /** - * Log To S3 - */ - logToS3(bucket: s3.Bucket | s3.IBucket ): void; - /** - * Send Events to Cloud Watch - */ - sendToCloudWatch(log: logs.LogGroup | logs.ILogGroup ): void; - /** - * Stream to Kinesis - */ - streamToKinesis(stream: kinesis.Stream | kinesis.IStream ): void; - /** - * Share the ServiceNetwork - */ - share(props: ShareServiceNetworkProps): void; - /** - * Create a service network from Attributes. - * This function only needs to be used when it is not possible to pass - * a ServiceNetwork between cdk apps or stacks. - */ - fromServiceNetworkAttributes(attrs: ServiceNetworkAttributes): void; - -} -``` -#### TargetGroups -```typescript -/** - * Create a vpc lattice TargetGroup. - * Implemented by `TargetGroup`. - */ -export interface ITargetGroup extends core.IResource { - /** - * The id of the target group - */ - readonly targetGroupId: string - /** - * The Arn of the target group - */ - readonly targetGroupArn: string; -} -``` - - - - - - -## SCRUM - USER STORIES - -As a consumer of cdk constructs I would like a L2 CDK Construct for Aws Lattice that; -* Is intuitive, and consistent with the general approach of cdk, and the service documentation. -* Abstracts the underlying complexities of the lattice service so, it is easy to concentrate on the solution. -* Integration between this construct and other CDK constructs -* Apply secure, best practice configurations as default - -As a Service Owner I would like to: -* Publish my service for others to access -* Control Authentication and Authorisation for my services -* Control load distribution across my compute resources -* Hide the implementation detail of my services from consumers - -As a Service Consumer I would like to: -* Be able have my resources use services that are available to me in my VPCs -* Authenticate with services -* Restrict access for services to security groups that I decide - -As a Platform/Network Admin I would like to: -* Create Service Networks for Owners and Consumers to use - -*** - - - -## FAQ - -### What is the scope of this RFC? - -This RFC Provides Classes and Methods to implement The VPC Lattice Service. -This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). - -### Why should I use this construct? - -This CDK L2 Construct can be used to deploy resources from [Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/what-is-vpc-service-network.html). VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). - - -You can check common [Amazon VPC Lattice Reference Architectures](https://d1.awsstatic.com/architecture-diagrams/ArchitectureDiagrams/lattice-use-cases-ra.pdf) to understand the different use cases you can build with the AWS service. -Examples of use for these constructs, are at ..... - - -* [vpc-lattice-an-implementation-of-kubernetes](https://aws.amazon.com/blogs/containers/introducing-aws-gateway-api-controller-for-amazon-vpc-lattice-an-implementation-of-kubernetes-gateway-api/) - -### Is this a breaking change? - -* No this will not break exisiting CDK functionality. - - -Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the `api-approved` label was applied to the RFC pull request): - - -`[ ]` Signed-off by API Bar Raiser @TheRealAmazonKendra - From 32ef56310289b4e10556caa85049f428d177d606 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 5 Jun 2023 16:03:07 +1200 Subject: [PATCH 07/31] Update 0502_aws-vpclattice.md Added API Design Information --- text/0502_aws-vpclattice.md | 579 ++++++++++++++++++++++-------------- 1 file changed, 361 insertions(+), 218 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 0a0808942..e09db1d21 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -1,178 +1,281 @@ -# L2 Constructs for AWS VpcLattice +# vpcLattice L2 Construct -**Status:** (DRAFT) +- [Project Information](#project-information) +- [Example Impleentation](#example-implementation) +- [API Design](#proposed-api-design-for-vpclattice) +- [FAQ](#faq) +- [Acceptance](#acceptance) -* **Original Author(s):** @mrpackethead, -, @taylaand, @nbaillie -* **Tracking Issue:** #502 -* **API Bar Raiser:** @TheRealAmazonKendra -This RFC proposes a new L2 module for CDK to support AWS VPC Lattice. +--- +## Project Information ---- -## PUBLIC ISSUES +**Status** (DRAFT) + +**Original Author(s):** @mrpackethead, , @taylaand, @nbaillie + +**Tracking Issue:** #502 + +**API Bar Raiser:** @TheRealAmazonKendra + +**Public Issues ( aws-cdk)** * (vpclattice): L2 for Amazon VPC Lattice #25452 -## Prototype Code: -https://github.com/raindancers/latticeplay -https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha ---- -## VpcLattice +**Prototype Code** +- https://github.com/raindancers/latticeplay +- https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha -Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. -The resources, that are required by lattice broadly fall into two catagories -* those are a associated with the creation of a Lattice Service network, its access and logging -* those that are associated with the the **services** that the applicaton network will deliver. +**VpcLattice** + +Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. + +--- ## Example Implementation -#### Create a Service Network, and allow access from a VPC +A Service is created and assocaited with a ServiceNetwork +A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. +Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests.. Lambda1 will be in VPC1, and Lambda2 in VPC2 + ```typescript -import { ServiceNetwork } from '@aws-cdk/aws-vpclattice-alpha'; +const serviceCert: certificatemanager.Certificate; +const lambda1: lambda.Function; +const lambda2: lambda.Function; -const myServiceNetwork: ServiceNetwork; -myServiceNetwork = new ServiceNetwork(this, 'myserviceNetwork, { - name: 'mylatticenetwork', + +// Create a Lattice Service, with a custom certificate and domain name, +// this will default to using IAM Authentication +const myLatticeService = new vpclattice.Service(this, 'myLatticeService', { + certificate: serviceCert, + customDomain: 'exampleorg.cloud' + dnsEntry: 'latticerfc' }); -``` -Optionally an authentication policy can be added to the service network, Typically access policies for the Service Network are -coarse such as allowing particular accounts to use the service network. Note: the `.addLaticeAuthPolicy()` method provides defaults for -resources, actions and effect -```typescript -myServiceNetwork.addLatticeAuthPolicy( - [ - new iam.PolicyStatement({ - principal: new iam.AccountPrincipal('12345678900') - }), +// add a listener to the service, using the defaults ( HTTPS, port 443 +// a default action of returning 404 NOT FOUND, and a cloudformation provided name +const myListener = myLatticeService.addListener(); + + +// add a rule to the service called 'rule1', with an forwarding action to a +// target group that contains lambda1. +// the rule will be triggered if there is a path match of `/path1` +// allow Lambda2 to access this path ( this adds a statment in the authPolicy for +// the service ) + +myListener.addListenerRule( + name: 'rule1' + action: [ + { + targetGroup: new vpclattice.TargetGroup( + name: 'lambda1target', + lambdaTargets: [ lambda1 ] + ) + } ] + pathMatch: { + path: '/path1' + } + allowedPrincipals: [lambda2.role] +) + +// add an additonal auth policy to the service as reqiured; +myLatticeService.addPolicyStatement( + new iam.PolicyStatement({}), ); - iam.policyDocument: iam.PolicyStatement[]): void; -``` -The service can be configured to log to S3, Stream to kinesis, or use Cloudwatch with the `.logToS3()`, `sendToCloudWatch()` or `streamtoKinesis()` methods. -```typescript -const loggingbucket: S3.Bucket -myServiceNetwork.logToS3(loggingbucket) -``` +// after the creation of Rules, or the additons of additonal PolicyStatements, apply the authPolicy to the Service. +myLatticeService.applyAuthPolicyToService(); -The service Network can be Shared using RAM using the `.share()` method -```typescript -myServiceNetwork.share({ - name: 'myserviceshare', - allowExternalPrincipals: false, - principals: new iam.AccountPrincipal('12345678900') -}) -``` -In order to access a service network a vpc must be associated with a vpc. -Optionally security groups can be applied. -For vpcs, in the same account as the Servicenetwork; -```typescript -const vpc: ec2.Vpc; -const securityGroup: ec2.SecurityGroup -myServiceNetwork.associateVPC(vpc, [securityGroups]) +// Create a service Network, and add the services as required. +// client must be in a VPC that is associated with the service network. + +const latticeLogs: s3.Bucket = new s3.Bucket() +const vpc1: ec2.Vpc = ec2.Vpc(); +const vpc2: ec2.Vpc = ec2.Vpc(); + +new vpclattice.ServiceNetwork(this, 'myLatticeServiceNetwork', { + name: 'alpha-service-network', + services: [ + myLatticeService + ], + s3LogDestination: [ latticelogs ], + vpcs: [ + vpc1, + vpc2, + ], + accounts: [ + '1111111111111', + '2222222222222' + ], }) ``` -Cross account -```typescript -const vpc: ec2.Vpc; -const securityGroup: ec2.SecurityGroup; -cosnt serviceNetwork = ServiceNetwork.importFromName('mylatticenetwork') -myServiceNetwork.associateVPC(vpc, [securityGroups]) -``` +--- -#### Create a service from a Lambda and associate it with the Service +## Proposed API Design for vpclattice -A lattice service is the 'front' for various applicaitons that might be 'served' by AWS resources such -as ec2 Instances, Applicaiton Load Balancers, Lambdas. Listeners are attached to the service, which have rules and targets. +- [ServiceNetwork](#servicenetwork) +- [Service](#serviceService) +- [Listener](#listener) +- [TargetGroups](#targetgroups) -```typescript -import { Service, Protocol, FixedResponse } from '@aws-cdk/aws-vpclattice-alpha'; -const myService: Service = new Service(this, 'myservice', { - name: 'myservice', -}) -``` +### ServiceNetwork +A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. -Add a listner to the service, with a certificate, a hostname and DNS -```typescript -const myCertificate: certificate_manager.Certificate -const serviceListener: lattice.Listener = myService.addListener( - defaultAction: FixedResponse.NOT_FOUND - protocol: Protocol.HTTPS, - name: 'MyServiceListener' -) -myService.addCertificate(myCertificate); -myService.addCustomDomain('example.org'); -myService.addDNSEntry('abcdef'); -``` -Create targets which will provide the 'content' for your service, in this example -we target a lambda. Then use the target in a Rule that is attached to the Listener. +![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) -```typescript -const functionOne: aws_lambda.Function +The construct `ServiceNetwork` provides for this. -const targetOne = new lattice.LatticeTargetGroup(this, 'TargetOne', { - name: 'targetgroupOne', - lambdaTargets: [ - functionOne - ], -}) -serviceListener.addListenerRule({ - name: 'listentolambdaone', - action: [{ target: targetOne }], - priority: 100, - pathMatch: { - pathMatchType: lattice.PathMatchType.EXACT, - matchValue: '/serviceOne', - caseSensitive: false, - } -}) - -``` -3. Finally, add the Service to the the Service Network -```typescript -serviceNetwork.addService(myService) -``` +The construct will implement `IServiceNetwork`. -## API Design -The following API design is proposed -#### Listener ```typescript /** - * Create a vpcLattice Listener. - * Implemented by `Listener`. + * Create a vpc lattice service network. + * Implemented by `ServiceNetwork`. */ -export interface IListener extends core.IResource { +e/** + * Create a vpc lattice service network. + * Implemented by `ServiceNetwork`. + */ +export interface IServiceNetwork extends core.IResource { + /** - * The Amazon Resource Name (ARN) of the service. + * The Amazon Resource Name (ARN) of the service network. */ - readonly listenerArn: string; + readonly serviceNetworkArn: string; + /** - * The Id of the Service Network - */ - readonly listenerId: string; + * The Id of the Service Network + */ + readonly serviceNetworkId: string; + /** + * Grant Princopals access to the Service Network + */ + grantAccessToServiceNetwork(principal: iam.IPrincipal[]): void; + /** + * Add Lattice Service Policy + */ + addService(service: Service): void; + /** + * Associate a VPC with the Service Network + */ + associateVPC(props: AssociateVPCProps): void; + /** + * Log To S3 + */ + logToS3(bucket: s3.Bucket | s3.IBucket ): void; + /** + * Send Events to Cloud Watch + */ + sendToCloudWatch(log: logs.LogGroup | logs.ILogGroup ): void; + /** + * Stream to Kinesis + */ + streamToKinesis(stream: kinesis.Stream | kinesis.IStream ): void; + /** + * Share the ServiceNetwork + */ + share(props: ShareServiceNetworkProps): void; + /** + * Create and Add an auth policy to the Service Network + */ + applyAuthPolicyToServiceNetwork(): void; +} + +} +``` +All of the class functions, apart from addAuthPolicy, are convience functions that mirror the properties. + +`ServiceNetwork` will take `ServiceNetworkProps` as props +```typescript +/** + * The properties for the ServiceNetwork. + */ +export interface ServiceNetworkProps { + + /** The name of the Service Network. If not provided Cloudformation will provide + * a name + * @default cloudformation generated name + */ + readonly name?: string + + /** The type of authentication to use with the Service Network. + * @default 'AWS_IAM' + */ + readonly authType?: AuthType | undefined; /** - * Add A Rule to the Listener + * S3 buckets for access logs + * @default no s3 logging */ - addListenerRule(props: AddRuleProps): void; + + readonly s3LogDestination: s3.IBucket[] | undefined; + /** + * Cloudwatch Logs + * @default no logging to cloudwatch + */ + readonly cloudwatchLogs?: logs.ILogGroup[] | undefined; + + /** + * kinesis streams + * @default no streaming to Kinesis + */ + readonly kinesisStreams?: kinesis.IStream[]; + + /** + * Lattice Services that are assocaited with this Service Network + * @default no services are associated with the service network + */ + readonly services?: Service[] | undefined; + + /** + * Vpcs that are associated with this Service Network + * @default no vpcs are associated + */ + readonly vpcs?: ec2.IVpc[] | undefined; + + /** + * Account principals that are permitted to use this service + * @default none + */ + readonly accounts?: iam.AccountPrincipal[] | undefined; + + /** + * arnToShareWith, use this for specifying Orgs and OU's + * @default false + */ + readonly arnToShareServiceWith?: string[] | undefined; + + /** + * Allow external principals + * @default false + */ + + readonly allowExternalPrincipals?: boolean | undefined; } + ``` -#### Service +### Service + +A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. + + +![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) + + ```typescript -/** - * Create a vpcLattice service. +** + * Create a vpcLattice service network. * Implemented by `Service`. */ export interface IService extends core.IResource { @@ -185,16 +288,11 @@ export interface IService extends core.IResource { */ readonly serviceId: string; - /** - * Add An Authentication Policy to the Service. - * @param policyStatement[]; - */ - addLatticeAuthPolicy(policyStatement: iam.PolicyStatement[]): iam.PolicyDocument; /** * Add A vpc listener to the Service. * @param props */ - addListener(props: vpclattice.ListenerProps): vpclattice.Listener; + addListener(props: AddListenerProps ): IListener; /** * Share the service to other accounts via RAM * @param props @@ -224,70 +322,88 @@ export interface IService extends core.IResource { */ addName(name: string): void; /** - *grant a Principal access to a Services Path - * @deafult + * grant access to the service + * */ - grantAccess(props: grantAccessProps): void; - + grantAccess(principals: iam.IPrincipal[]): void; + /** + * Apply the authAuthPolicy to the Service + */ + applyAuthPolicyToService(): iam.PolicyDocument; + /** + * Add A policyStatement to the Auth Policy + */ + addPolicyStatement(statement: iam.PolicyStatement): void; } ``` -#### ServiceNetwork -```typescript -/** - * Create a vpc lattice service network. - * Implemented by `ServiceNetwork` - */ -export interface IServiceNetwork extends core.IResource { +### Listener +A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the service routes requests to its registered targets. +It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used. + + +``` typescript +export interface IListener extends core.IResource { /** - * The Amazon Resource Name (ARN) of the service network. + * The Amazon Resource Name (ARN) of the service. */ - readonly serviceNetworkArn: string; - + readonly listenerArn: string; /** - * The Id of the Service Network - */ - readonly serviceNetworkId: string; + * The Id of the Service Network + */ + readonly listenerId: string; + /** - * Add LatticeAuthPolicy + * Add A Listener Rule to the Listener */ - addLatticeAuthPolicy(policyDocument: iam.PolicyStatement[]): void; + addListenerRule(props: AddRuleProps): void; + +} +``` + + +```typescript +/** + * Propertys to Create a Lattice Listener + */ +export interface ListenerProps { /** - * Add Lattice Service Policy - */ - addService(service: vpclattice.Service): void; + * * A default action that will be taken if no rules match. + * @default 404 NOT Found + */ + readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; /** - * Associate a VPC with the Service Network - */ - associateVPC(vpc: ec2.Vpc, securityGroups: ec2.SecurityGroup[]): void; + * protocol that the listener will listen on + */ + readonly protocol: Protocol /** - * Log To S3 - */ - logToS3(bucket: s3.Bucket | s3.IBucket ): void; + * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol + * @default 80 or 443 depending on the Protocol + + */ + readonly port?: number | undefined /** - * Send Events to Cloud Watch - */ - sendToCloudWatch(log: logs.LogGroup | logs.ILogGroup ): void; + * The Name of the service. + * @default CloudFormation provided name. + */ + readonly name?: string; /** - * Stream to Kinesis + * The service */ - streamToKinesis(stream: kinesis.Stream | kinesis.IStream ): void; + readonly serviceId: string; /** - * Share the ServiceNetwork + * the authpolicy for the service this listener is associated with + * @default none. */ - share(props: ShareServiceNetworkProps): void; - /** - * Create a service network from Attributes. - * This function only needs to be used when it is not possible to pass - * a ServiceNetwork between cdk apps or stacks. - */ - fromServiceNetworkAttributes(attrs: ServiceNetworkAttributes): void; - + readonly serviceAuthPolicy?: iam.PolicyDocument | undefined } ``` -#### TargetGroups + +### TargetGroups + +A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers, or Kubernetes Pods. + ```typescript -/** * Create a vpc lattice TargetGroup. * Implemented by `TargetGroup`. */ @@ -300,64 +416,91 @@ export interface ITargetGroup extends core.IResource { * The Arn of the target group */ readonly targetGroupArn: string; + } ``` +```typescript +/** + * Properties for a Target Group, Only supply one of instancetargets, lambdaTargets, albTargets, ipTargets + */ +export interface TargetGroupProps { + /** + * The name of the target group + */ + readonly name: string, + /** + * A list of ec2 instance targets. + * @default - No targets + */ + readonly instancetargets?: ec2.Instance[], + /** + * A list of ip targets + * @default - No targets + */ + readonly ipTargets?: string[], + /** + * A list of lambda targets + * @default - No targets + */ + readonly lambdaTargets?: aws_lambda.Function[], + /** + * A list of alb targets + * @default - No targets + */ + readonly albTargets?: elbv2.ApplicationListener[] + /** + * The Target Group configuration. Must be provided for alb, instance and Ip targets, but + * must not be provided for lambda targets + * @default - No configuration + */ + /** + * The Target Group configuration. Must be provided for alb, instance and Ip targets, but + * must not be provided for lambda targets + * @default - No configuration + */ + readonly config?: vpclattice.TargetGroupConfig | undefined, +} +``` +--- +### FAQ -## SCRUM - USER STORIES - -As a consumer of cdk constructs I would like a L2 CDK Construct for Aws Lattice that; -* Is intuitive, and consistent with the general approach of cdk, and the service documentation. -* Abstracts the underlying complexities of the lattice service so, it is easy to concentrate on the solution. -* Integration between this construct and other CDK constructs -* Apply secure, best practice configurations as default - -As a Service Owner I would like to: -* Publish my service for others to access -* Control Authentication and Authorisation for my services -* Control load distribution across my compute resources -* Hide the implementation detail of my services from consumers - -As a Service Consumer I would like to: -* Be able have my resources use services that are available to me in my VPCs -* Authenticate with services -* Restrict access for services to security groups that I decide - -As a Platform/Network Admin I would like to: -* Create Service Networks for Owners and Consumers to use - -*** - - - -## FAQ - -### What is the scope of this RFC? - -This RFC Provides Classes and Methods to implement The VPC Lattice Service. -This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). - -### Why should I use this construct? - -This CDK L2 Construct can be used to deploy resources from [Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/what-is-vpc-service-network.html). VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). +**What are we launching today?** +Amazon VPC Lattice AWS CDK L2 Construct +**Why should I use this construct?** +This CDK L2 Construct can be used to deploy resources from Amazon VPC Lattice. VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). -You can check common [Amazon VPC Lattice Reference Architectures](https://d1.awsstatic.com/architecture-diagrams/ArchitectureDiagrams/lattice-use-cases-ra.pdf) to understand the different use cases you can build with the AWS service. -Examples of use for these constructs, are at ..... +This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). You have the freedom to create the combination of resources you need, so in multi-AWS Account environments you can make use of the module as many times as needed (different providers) to create your application network architecture. +You can check common Amazon VPC Lattice Reference Architectures to understand the different use cases you can build with the AWS service. -* [vpc-lattice-an-implementation-of-kubernetes](https://aws.amazon.com/blogs/containers/introducing-aws-gateway-api-controller-for-amazon-vpc-lattice-an-implementation-of-kubernetes-gateway-api/) +- It simplifies the deployment of common patterns for AWS VPC Lattice +- It has been tested and implemented as part of a number of wider architectures +- It is extensible to support other patterns as they emerge +- It simplifies AWS VPC Lattice adoption and administration +- Allows you to integrate infrastructure deployment with your application code +- Reduces time to deploy and test AWS VPC Lattice +- Provides separation of concerns with a common interface for user personas -### Is this a breaking change? +**Why are we doing this?** +- To provide a CDK native interface for AWS VPC Lattice +- Provide a way to deploy AWS VPC Lattice deterministically -* No this will not break exisiting CDK functionality. +**Is this a breaking change** +No. +**What are the drawbacks of this solution** +- It is an opinionated pattern, however there are escapes to help customisation where needed. +- It is a new AWS Service and its common usecases and features may change and evolve -Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the `api-approved` label was applied to the RFC pull request): +--- +### Acceptance +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): -`[ ]` Signed-off by API Bar Raiser @TheRealAmazonKendra +`[ ] Signed-off by API Bar Raiser @TheRealAmazonKendra` From 0236dd8ff2b2abb41a6ff6f54430cbe1c4f3753e Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 5 Jun 2023 16:04:11 +1200 Subject: [PATCH 08/31] Update 0502_aws-vpclattice.md comma --- text/0502_aws-vpclattice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index e09db1d21..5b2799a5f 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -51,7 +51,7 @@ const lambda2: lambda.Function; // this will default to using IAM Authentication const myLatticeService = new vpclattice.Service(this, 'myLatticeService', { certificate: serviceCert, - customDomain: 'exampleorg.cloud' + customDomain: 'exampleorg.cloud', dnsEntry: 'latticerfc' }); From c1bfdfc3bc23ae78d74f7ace558848e095ece793 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 9 Jun 2023 10:47:44 +1200 Subject: [PATCH 09/31] Update 0502_aws-vpclattice.md Updates to address the commetns. --- text/0502_aws-vpclattice.md | 507 ++++++++++++++++++++++++------------ 1 file changed, 338 insertions(+), 169 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 5b2799a5f..438b97577 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -35,84 +35,98 @@ Amazon VPC Lattice is an application networking service that consistently connec ## Example Implementation -A Service is created and assocaited with a ServiceNetwork +- A Service is created +- A Listener is added to the serviceand associated with a ServiceNetwork +- A Rule is assocated with the listener which uses a Lambda function as a target +- A Service Network is created +- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests.. Lambda1 will be in VPC1, and Lambda2 in VPC2 ```typescript -const serviceCert: certificatemanager.Certificate; -const lambda1: lambda.Function; -const lambda2: lambda.Function; - - -// Create a Lattice Service, with a custom certificate and domain name, -// this will default to using IAM Authentication -const myLatticeService = new vpclattice.Service(this, 'myLatticeService', { - certificate: serviceCert, - customDomain: 'exampleorg.cloud', - dnsEntry: 'latticerfc' -}); - -// add a listener to the service, using the defaults ( HTTPS, port 443 -// a default action of returning 404 NOT FOUND, and a cloudformation provided name -const myListener = myLatticeService.addListener(); - - -// add a rule to the service called 'rule1', with an forwarding action to a -// target group that contains lambda1. -// the rule will be triggered if there is a path match of `/path1` -// allow Lambda2 to access this path ( this adds a statment in the authPolicy for -// the service ) - -myListener.addListenerRule( - name: 'rule1' - action: [ - { - targetGroup: new vpclattice.TargetGroup( - name: 'lambda1target', - lambdaTargets: [ lambda1 ] - ) - } - ] - pathMatch: { - path: '/path1' +import * as core from 'aws-cdk-lib'; + +import { + aws_iam as iam, +} + from 'aws-cdk-lib'; +import { Construct } from 'constructs'; + +import { SupportResources } from './support'; +import { + ServiceNetwork, + Service, + TargetGroup, + Target, +} + from '../../lib/index'; + +export class LatticeTestStack extends core.Stack { + + constructor(scope: Construct, id: string, props?: core.StackProps) { + super(scope, id, props); + + const support = new SupportResources(this, 'supportresources'); + + // Create a Lattice Service + // this will default to using IAM Authentication + const myLatticeService = new Service(this, 'myLatticeService', { + shares: [{ + name: 'LatticeShare', + allowExternalPrincipals: false, + principals: [ + '123456654321', + ], + }], + }); + // add a listener to the service, using the defaults + // - HTTPS + // - Port 443 + // - default action of providing 404 NOT Found, + // - cloudformation name + const myListener = myLatticeService.addListener({}); + + myListener.addListenerRule({ + name: 'thing', + priority: 100, + action: [ + { + targetGroup: new TargetGroup(this, 'lambdatargets', { + name: 'lambda1', + target: Target.lambda([ + support.checkHelloWorld, + ]), + }), + }, + ], + pathMatch: { + path: '/helloWorld', + }, + allowedPrincipals: [support.checkHelloWorld.role as iam.Role], + }); + + myLatticeService.applyAuthPolicy(); + + /** + * Create a ServiceNetwork. + * OPINIONATED DEFAULT: The default behavior is to create a + * service network that requries an IAM policy, and authenticated access + * ( requestors must send signed requests ) + */ + + const serviceNetwork = new ServiceNetwork(this, 'LatticeServiceNetwork', { + services: [myLatticeService], + vpcs: [ + support.vpc1, + support.vpc2, + ], + }); + + serviceNetwork.applyAuthPolicyToServiceNetwork(); } - allowedPrincipals: [lambda2.role] -) - -// add an additonal auth policy to the service as reqiured; -myLatticeService.addPolicyStatement( - new iam.PolicyStatement({}), -); - -// after the creation of Rules, or the additons of additonal PolicyStatements, apply the authPolicy to the Service. -myLatticeService.applyAuthPolicyToService(); - - -// Create a service Network, and add the services as required. -// client must be in a VPC that is associated with the service network. - -const latticeLogs: s3.Bucket = new s3.Bucket() -const vpc1: ec2.Vpc = ec2.Vpc(); -const vpc2: ec2.Vpc = ec2.Vpc(); - -new vpclattice.ServiceNetwork(this, 'myLatticeServiceNetwork', { - name: 'alpha-service-network', - services: [ - myLatticeService - ], - s3LogDestination: [ latticelogs ], - vpcs: [ - vpc1, - vpc2, - ], - accounts: [ - '1111111111111', - '2222222222222' - ], -}) +} ``` --- @@ -121,7 +135,10 @@ new vpclattice.ServiceNetwork(this, 'myLatticeServiceNetwork', { - [ServiceNetwork](#servicenetwork) - [Service](#serviceService) - [Listener](#listener) -- [TargetGroups](#targetgroups) +- [TargetGroups](#targetgroups) +- [Targets](#targets) +- [Logging](#logging) + @@ -142,10 +159,6 @@ The construct will implement `IServiceNetwork`. * Create a vpc lattice service network. * Implemented by `ServiceNetwork`. */ -e/** - * Create a vpc lattice service network. - * Implemented by `ServiceNetwork`. - */ export interface IServiceNetwork extends core.IResource { /** @@ -157,43 +170,36 @@ export interface IServiceNetwork extends core.IResource { * The Id of the Service Network */ readonly serviceNetworkId: string; - /** - * Grant Princopals access to the Service Network - */ - grantAccessToServiceNetwork(principal: iam.IPrincipal[]): void; /** * Add Lattice Service Policy */ - addService(service: Service): void; + addService(service: IService): void; /** * Associate a VPC with the Service Network */ associateVPC(props: AssociateVPCProps): void; /** - * Log To S3 + * Add a logging Destination. */ - logToS3(bucket: s3.Bucket | s3.IBucket ): void; + addloggingDestination(destination: LoggingDestination): void; /** - * Send Events to Cloud Watch - */ - sendToCloudWatch(log: logs.LogGroup | logs.ILogGroup ): void; - /** - * Stream to Kinesis - */ - streamToKinesis(stream: kinesis.Stream | kinesis.IStream ): void; - /** - * Share the ServiceNetwork + * Share the ServiceNetwork, Consider if it is more appropriate to do this at the service. */ share(props: ShareServiceNetworkProps): void; + /** - * Create and Add an auth policy to the Service Network + * Add a statement to the auth policy. This should be high level coarse policy, consider only adding + * statements here that have DENY effects + * @param statement the policy statement to add. */ + addStatementToAuthPolicy(statement: iam.PolicyStatement): void; + /** + * Apply auth policy to the Service Network + */ applyAuthPolicyToServiceNetwork(): void; } - -} ``` -All of the class functions, apart from addAuthPolicy, are convience functions that mirror the properties. + `ServiceNetwork` will take `ServiceNetworkProps` as props ```typescript @@ -208,59 +214,40 @@ export interface ServiceNetworkProps { */ readonly name?: string - /** The type of authentication to use with the Service Network. + /** + * The type of authentication to use with the Service Network * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; /** - * S3 buckets for access logs - * @default no s3 logging - */ - - readonly s3LogDestination: s3.IBucket[] | undefined; - /** - * Cloudwatch Logs - * @default no logging to cloudwatch - */ - readonly cloudwatchLogs?: logs.ILogGroup[] | undefined; - - /** - * kinesis streams - * @default no streaming to Kinesis + * Logging destinations + * @default: no logging */ - readonly kinesisStreams?: kinesis.IStream[]; + readonly loggingDestinations?: LoggingDestination[]; /** * Lattice Services that are assocaited with this Service Network * @default no services are associated with the service network */ - readonly services?: Service[] | undefined; + readonly services?: IService[] | undefined; /** * Vpcs that are associated with this Service Network * @default no vpcs are associated */ readonly vpcs?: ec2.IVpc[] | undefined; - - /** - * Account principals that are permitted to use this service - * @default none - */ - readonly accounts?: iam.AccountPrincipal[] | undefined; - /** - * arnToShareWith, use this for specifying Orgs and OU's + * Allow external principals * @default false */ - readonly arnToShareServiceWith?: string[] | undefined; + readonly allowExternalPrincipals?: boolean | undefined; /** - * Allow external principals + * Allow unauthenticated access * @default false */ - - readonly allowExternalPrincipals?: boolean | undefined; + readonly allowUnauthenticatedAccess?: boolean | undefined; } ``` @@ -278,6 +265,10 @@ A service within VPC Lattice is an independently deployable unit of software tha * Create a vpcLattice service network. * Implemented by `Service`. */ +/** + * Create a vpcLattice service network. + * Implemented by `Service`. + */ export interface IService extends core.IResource { /** * The Amazon Resource Name (ARN) of the service. @@ -292,7 +283,7 @@ export interface IService extends core.IResource { * Add A vpc listener to the Service. * @param props */ - addListener(props: AddListenerProps ): IListener; + addListener(props: AddListenerProps): Listener; /** * Share the service to other accounts via RAM * @param props @@ -300,42 +291,82 @@ export interface IService extends core.IResource { share(props: ShareServiceProps): void; /** - * Create a DNS entry in R53 for the service. - */ - addDNSEntry(props: aws_vpclattice.CfnService.DnsEntryProperty): void; + * Grant Access to other principals + */ + grantAccess(principals: iam.IPrincipal[]): void; /** - * Add a certificate to the service - * @param certificate + * Apply the authAuthPolicy to the Service */ - addCertificate(certificate: certificatemanager.Certificate): void; - + applyAuthPolicy(): iam.PolicyDocument; /** - * add a custom domain to the service - * @param domain + * Add A policyStatement to the Auth Policy */ - addCustomDomain(domain: string): void; + addPolicyStatement(statement: iam.PolicyStatement): void; +} +``` + +`Service` will take `ServiceProps` as props +```typescript +/** + * Properties for a Lattice Service + */ +export interface LatticeServiceProps { /** - * add a name for the service + * Name for the service * @default cloudformation will provide a name */ - addName(name: string): void; + readonly name?: string | undefined; + /** - * grant access to the service - * + * The authType of the Service + * @default 'AWS_IAM' */ - grantAccess(principals: iam.IPrincipal[]): void; + readonly authType?: string | undefined; + /** - * Apply the authAuthPolicy to the Service + * Listeners that will be attached to the service + * @default no listeners + */ + readonly listeners?: IListener[] | undefined; + + /** + * A certificate that may be used by the service + * @default no custom certificate is used */ - applyAuthPolicyToService(): iam.PolicyDocument; + readonly certificate?: certificatemanager.Certificate | undefined; /** - * Add A policyStatement to the Auth Policy + * A customDomain used by the service + * @default no customdomain is used */ - addPolicyStatement(statement: iam.PolicyStatement): void; + readonly customDomain?: string | undefined; + /** + * A custom hosname + * @default no hostname is used + */ + readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; + + /** + * Share Service + *@default no sharing of the service + */ + readonly shares?: ShareServiceProps[] | undefined; + + /** + * Allow external principals + * @default false + */ + readonly allowExternalPrincipals?: boolean | undefined; + + /** + * Allow unauthenticated access + * @default false + */ + readonly allowUnauthenticatedAccess?: boolean | undefined; } ``` + ### Listener A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the service routes requests to its registered targets. @@ -343,6 +374,10 @@ It is not expected that a direct call to Listener will be made, instead the `.ad ``` typescript +/** + * Create a vpcLattice Listener. + * Implemented by `Listener`. + */ export interface IListener extends core.IResource { /** * The Amazon Resource Name (ARN) of the service. @@ -361,6 +396,7 @@ export interface IListener extends core.IResource { } ``` +`Listener` will take `ListenerProps` ```typescript /** @@ -388,7 +424,7 @@ export interface ListenerProps { */ readonly name?: string; /** - * The service + * The Id of the service that this listener is associated with. */ readonly serviceId: string; /** @@ -401,7 +437,7 @@ export interface ListenerProps { ### TargetGroups -A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers, or Kubernetes Pods. +A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers ```typescript * Create a vpc lattice TargetGroup. @@ -416,11 +452,9 @@ export interface ITargetGroup extends core.IResource { * The Arn of the target group */ readonly targetGroupArn: string; - } ``` - - +`TargetGroup` will take `TargetGroupProps` ```typescript /** @@ -432,36 +466,171 @@ export interface TargetGroupProps { */ readonly name: string, /** - * A list of ec2 instance targets. - * @default - No targets + * Targets + */ + readonly target: Target, +} +``` + +### Target + +Target is an abstract class with static function to return propertys for a TargetGroup + +```typescript +/** + * Targets for target Groups + */ +export abstract class Target { + + /** + * Lambda Target + * @param lambda + */ + public static lambda(lambda: aws_lambda.Function[]): Target { + + let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; + lambda.forEach((target) => { + targets.push({ id: target.functionArn }); + }); + + return { + type: TargetType.LAMBDA, + targets: targets, + }; + }; + + /** + * IpAddress as Targets + * @param ipAddress + * @param config + */ + public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { + + let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; + + ipAddress.forEach((target) => { + targets.push({ id: target }); + }); + + return { + type: TargetType.LAMBDA, + targets: targets, + config: config, + }; + + }; + + /** + * EC2 Instances as Targets + * @param ec2instance + * @param config + */ + public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { + + let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; + + ec2instance.forEach((target) => { + targets.push({ id: target.instanceId }); + }); + + return { + type: TargetType.LAMBDA, + targets: targets, + config: config, + }; + + }; + + /** + * Application Load Balancer as Targets + * @param alb + * @param config */ - readonly instancetargets?: ec2.Instance[], + public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { + + let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; + + alb.forEach((target) => { + targets.push({ id: target.listenerArn }); + }); + + return { + type: TargetType.LAMBDA, + targets: targets, + config: config, + }; + + } /** - * A list of ip targets - * @default - No targets + * The type of target */ - readonly ipTargets?: string[], + public abstract readonly type: TargetType; /** - * A list of lambda targets - * @default - No targets + * References to the targets, ids or Arns */ - readonly lambdaTargets?: aws_lambda.Function[], + public abstract readonly targets: aws_vpclattice.CfnTargetGroup.TargetProperty[]; /** - * A list of alb targets - * @default - No targets + * Configuration for the TargetGroup, if it is not a lambda */ - readonly albTargets?: elbv2.ApplicationListener[] + public abstract readonly config?: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty | undefined; + + constructor() {}; + +} +``` + +### LoggingDestination + +LoggingDestination is a abstract class to return properties for a LoggingSubscription + +```typescript +/** + * Logging options + */ +export abstract class LoggingDestination { + /** - * The Target Group configuration. Must be provided for alb, instance and Ip targets, but - * must not be provided for lambda targets - * @default - No configuration + * Construct a logging destination for a S3 Bucket + * @param bucket an s3 bucket */ + public static s3(bucket: s3.IBucket): LoggingDestination { + return { + name: bucket.bucketName, + arn: bucket.bucketArn, + }; + } /** - * The Target Group configuration. Must be provided for alb, instance and Ip targets, but - * must not be provided for lambda targets - * @default - No configuration + * Send to CLoudwatch + * @param logGroup */ - readonly config?: vpclattice.TargetGroupConfig | undefined, + public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination { + return { + name: logGroup.logGroupName, + arn: logGroup.logGroupArn, + }; + } + + /** + * Stream to Kinesis + * @param stream + */ + public static kinesis(stream: kinesis.IStream): LoggingDestination { + return { + name: stream.streamName, + arn: stream.streamArn, + }; + } + + /** + * A name of the destination + */ + public abstract readonly name: string; + /** + * An Arn of the destination + */ + public abstract readonly arn: string; + + protected constructor() {}; } ``` From be849c2ef075caf998a334cab8be41c8eb04376b Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 21 Jun 2023 13:36:36 +1200 Subject: [PATCH 10/31] Update 0502_aws-vpclattice.md Updated. --- text/0502_aws-vpclattice.md | 175 ++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 66 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 438b97577..3de77eaca 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -23,13 +23,15 @@ **Prototype Code** -- https://github.com/raindancers/latticeplay - https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha +- hhttps://github.com/raindancers/vpclattice-prealpha-demo **VpcLattice** Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. + +The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. --- @@ -72,41 +74,63 @@ export class LatticeTestStack extends core.Stack { // Create a Lattice Service // this will default to using IAM Authentication - const myLatticeService = new Service(this, 'myLatticeService', { - shares: [{ - name: 'LatticeShare', - allowExternalPrincipals: false, - principals: [ - '123456654321', - ], - }], - }); + const myLatticeService = new Service(this, 'myLatticeService', {}); // add a listener to the service, using the defaults // - HTTPS // - Port 443 // - default action of providing 404 NOT Found, // - cloudformation name - const myListener = myLatticeService.addListener({}); + const myListener = new vpclattice.Listener(this, 'Listener', { + service: myLatticeService, + }) + + + // add a listenerRule that will use the helloworld lambda as a Target + mylistener.addListenerRule({ + name: 'helloworld', + priority: 10, + action: [ + { + targetGroup: new vpclattice.TargetGroup(this, 'hellolambdatargets', { + name: 'hellowworld', + target: vpclattice.Target.lambda([ + support.helloWorld, + ]), + }), + }, + ], - myListener.addListenerRule({ - name: 'thing', - priority: 100, + httpMatch: { + pathMatches: { path: '/hello' }, + }, + // we will only allow access to this service from the ec2 instance + accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED + }); + + //add a listenerRule that will use the goodbyeworld lambda as a Target + mylistener.addListenerRule({ + name: 'goodbyeworld', + priority: 20, action: [ { - targetGroup: new TargetGroup(this, 'lambdatargets', { - name: 'lambda1', - target: Target.lambda([ - support.checkHelloWorld, + targetGroup: new vpclattice.TargetGroup(this, 'goodbyelambdatargets', { + name: 'goodbyeworld', + target: vpclattice.Target.lambda([ + support.goodbyeWorld, ]), }), }, ], - pathMatch: { - path: '/helloWorld', + + httpMatch: { + pathMatches: { path: '/goodbye' }, }, - allowedPrincipals: [support.checkHelloWorld.role as iam.Role], + // we will only allow access to this service from the ec2 instance + allowedPrincipals: [support.ec2instance.role], + accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, }); + myLatticeService.applyAuthPolicy(); /** @@ -120,7 +144,6 @@ export class LatticeTestStack extends core.Stack { services: [myLatticeService], vpcs: [ support.vpc1, - support.vpc2, ], }); @@ -141,7 +164,6 @@ export class LatticeTestStack extends core.Stack { - ### ServiceNetwork A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. @@ -150,10 +172,8 @@ A service network is a logical boundary for a collection of services. Services a The construct `ServiceNetwork` provides for this. - The construct will implement `IServiceNetwork`. - ```typescript /** * Create a vpc lattice service network. @@ -171,9 +191,9 @@ export interface IServiceNetwork extends core.IResource { */ readonly serviceNetworkId: string; /** - * Add Lattice Service Policy + * Add Lattice Service */ - addService(service: IService): void; + addService(props: AddServiceProps): void; /** * Associate a VPC with the Service Network */ @@ -181,7 +201,7 @@ export interface IServiceNetwork extends core.IResource { /** * Add a logging Destination. */ - addloggingDestination(destination: LoggingDestination): void; + addloggingDestination(props: AddloggingDestinationProps): void; /** * Share the ServiceNetwork, Consider if it is more appropriate to do this at the service. */ @@ -198,13 +218,15 @@ export interface IServiceNetwork extends core.IResource { */ applyAuthPolicyToServiceNetwork(): void; } -``` +``` + +The Construct will consume ServiceNetworkProps. -`ServiceNetwork` will take `ServiceNetworkProps` as props ```typescript /** - * The properties for the ServiceNetwork. + * Create a vpc lattice service network. + * Implemented by `ServiceNetwork`. */ export interface ServiceNetworkProps { @@ -241,15 +263,8 @@ export interface ServiceNetworkProps { * Allow external principals * @default false */ - readonly allowExternalPrincipals?: boolean | undefined; - - /** - * Allow unauthenticated access - * @default false - */ - readonly allowUnauthenticatedAccess?: boolean | undefined; + readonly accessmode?: ServiceNetworkAccessMode | undefined; } - ``` ### Service @@ -261,10 +276,6 @@ A service within VPC Lattice is an independently deployable unit of software tha ```typescript -** - * Create a vpcLattice service network. - * Implemented by `Service`. - */ /** * Create a vpcLattice service network. * Implemented by `Service`. @@ -278,17 +289,58 @@ export interface IService extends core.IResource { * The Id of the Service Network */ readonly serviceId: string; + /** + * Allow an Odd + */ + readonly orgId: string | undefined; + /** + * the policy document for the service; + */ + authPolicy: iam.PolicyDocument; /** * Add A vpc listener to the Service. * @param props */ - addListener(props: AddListenerProps): Listener; + shareToAccounts(props: ShareServiceProps): void; + + /** + * Grant Access to other principals + */ + grantAccess(principals: iam.IPrincipal[]): void; + + /** + * Apply the authAuthPolicy to the Service + */ + applyAuthPolicy(): iam.PolicyDocument; + /** + * Add A policyStatement to the Auth Policy + */ + addPolicyStatement(statement: iam.PolicyStatement): void; +} +export interface IService extends core.IResource { + /** + * The Amazon Resource Name (ARN) of the service. + */ + readonly serviceArn: string; + /** + * The Id of the Service Network + */ + readonly serviceId: string; + /** + * Allow an Odd + */ + readonly orgId: string | undefined; + /** + * the policy document for the service; + */ + authPolicy: iam.PolicyDocument; + /** - * Share the service to other accounts via RAM + * Add A vpc listener to the Service. * @param props */ - share(props: ShareServiceProps): void; + shareToAccounts(props: ShareServiceProps): void; /** * Grant Access to other principals @@ -304,6 +356,7 @@ export interface IService extends core.IResource { */ addPolicyStatement(statement: iam.PolicyStatement): void; } + ``` `Service` will take `ServiceProps` as props @@ -352,19 +405,8 @@ export interface LatticeServiceProps { *@default no sharing of the service */ readonly shares?: ShareServiceProps[] | undefined; - - /** - * Allow external principals - * @default false - */ - readonly allowExternalPrincipals?: boolean | undefined; - - /** - * Allow unauthenticated access - * @default false - */ - readonly allowUnauthenticatedAccess?: boolean | undefined; } + ``` ### Listener @@ -399,6 +441,9 @@ export interface IListener extends core.IResource { `Listener` will take `ListenerProps` ```typescript +/** + * Propertys to Create a Lattice Listener + */ /** * Propertys to Create a Lattice Listener */ @@ -410,8 +455,9 @@ export interface ListenerProps { readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; /** * protocol that the listener will listen on + * @default HTTPS */ - readonly protocol: Protocol + readonly protocol?: Protocol | undefined; /** * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol * @default 80 or 443 depending on the Protocol @@ -426,12 +472,7 @@ export interface ListenerProps { /** * The Id of the service that this listener is associated with. */ - readonly serviceId: string; - /** - * the authpolicy for the service this listener is associated with - * @default none. - */ - readonly serviceAuthPolicy?: iam.PolicyDocument | undefined + readonly service: IService; } ``` @@ -440,7 +481,8 @@ export interface ListenerProps { A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers ```typescript - * Create a vpc lattice TargetGroup. + + /** Create a vpc lattice TargetGroup. * Implemented by `TargetGroup`. */ export interface ITargetGroup extends core.IResource { @@ -454,6 +496,7 @@ export interface ITargetGroup extends core.IResource { readonly targetGroupArn: string; } ``` + `TargetGroup` will take `TargetGroupProps` ```typescript From e3adaf7cdd35b33085d386dd731b1b08d52fde75 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 14:19:45 +1200 Subject: [PATCH 11/31] Update 0502_aws-vpclattice.md --- text/0502_aws-vpclattice.md | 706 ++++++++++++++++++++++++++---------- 1 file changed, 507 insertions(+), 199 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 3de77eaca..b60e340ca 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -24,7 +24,10 @@ **Prototype Code** - https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha -- hhttps://github.com/raindancers/vpclattice-prealpha-demo +- https://github.com/raindancers/vpclattice-prealpha-demo + +** Constructs.dev ** +- https://constructs.dev/packages/aws-vpclattice-prealpha **VpcLattice** @@ -153,26 +156,84 @@ export class LatticeTestStack extends core.Stack { ``` --- -## Proposed API Design for vpclattice +## Proposed API Design for vpclattice: +[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) + + +### Constructs + +- ✓ [AssociateVpc](#associatevpc) +- ✓ [ServiceNetwork](#servicenetwork) +- ✓ [ServiceNetworkAssociation] (#servicenetworkassociation) +- ✓ [Service](#serviceService) +- ✓ [ServiceAssociation] +- ✓ [Listener](#listener) +- ✓ [TargetGroup](#targetgroup) + +### Classes + - [HealthCheck] + - [LoggingDestination] + - [Target] + +### Enums + - [AuthType] + - [FixedResponse] + - [HTTPMethods] + - [IpAddressType] + - [MatchOperator] + - [PathMatchType] + - [Protocol] + - [ProtocolVersion] + - [RuleAccessMode] + - [ServiceNetworkAccessMode] + - [TargetType] + + +--- +## Constructs + +### AssociateVpc + +Creates a CloudFormation `AWS::VpcLattice::ServiceNetworkVpcAssociation` -- [ServiceNetwork](#servicenetwork) -- [Service](#serviceService) -- [Listener](#listener) -- [TargetGroups](#targetgroups) -- [Targets](#targets) -- [Logging](#logging) +This construct associates a VPC, with a service network. It creates an endpoint interface in a VPC to enable the resources in the vpc +to be clients of the service network. + +The construct extends core.Resource, and will consume AssociateVpcProps. + +```typescript +/** + * Props to Associate a VPC with a Service Network + */ +export interface AssociateVpcProps { + /** + * security groups for the lattice endpoint + * @default a security group that will permit inbound 443 + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** + * The VPC to associate with + */ + readonly vpc: ec2.IVpc; + /** + * Service Network Identifier + */ + readonly serviceNetworkId: string; +} +``` ### ServiceNetwork -A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. +Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` + +A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. ![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) -The construct `ServiceNetwork` provides for this. -The construct will implement `IServiceNetwork`. +The construct will extend ServiceNetworkBase and implement IServiceNetwork. ```typescript /** @@ -185,11 +246,14 @@ export interface IServiceNetwork extends core.IResource { * The Amazon Resource Name (ARN) of the service network. */ readonly serviceNetworkArn: string; - /** * The Id of the Service Network */ readonly serviceNetworkId: string; + /** + * Is this an imported serviceNetwork + */ + readonly imported: boolean; /** * Add Lattice Service */ @@ -198,25 +262,6 @@ export interface IServiceNetwork extends core.IResource { * Associate a VPC with the Service Network */ associateVPC(props: AssociateVPCProps): void; - /** - * Add a logging Destination. - */ - addloggingDestination(props: AddloggingDestinationProps): void; - /** - * Share the ServiceNetwork, Consider if it is more appropriate to do this at the service. - */ - share(props: ShareServiceNetworkProps): void; - - /** - * Add a statement to the auth policy. This should be high level coarse policy, consider only adding - * statements here that have DENY effects - * @param statement the policy statement to add. - */ - addStatementToAuthPolicy(statement: iam.PolicyStatement): void; - /** - * Apply auth policy to the Service Network - */ - applyAuthPolicyToServiceNetwork(): void; } ``` @@ -224,20 +269,17 @@ The Construct will consume ServiceNetworkProps. ```typescript -/** - * Create a vpc lattice service network. - * Implemented by `ServiceNetwork`. - */ export interface ServiceNetworkProps { /** The name of the Service Network. If not provided Cloudformation will provide * a name * @default cloudformation generated name */ - readonly name?: string + readonly name?: string; /** - * The type of authentication to use with the Service Network + * The type of authentication to use with the Service Network. The only method avaialble is + * AWS_IAM, however in anticipation, it is expected that other types will be added. * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; @@ -260,101 +302,131 @@ export interface ServiceNetworkProps { */ readonly vpcs?: ec2.IVpc[] | undefined; /** - * Allow external principals - * @default false + * An access mode provides 'pre-canned' conditions for the policy + * @default no conditions */ readonly accessmode?: ServiceNetworkAccessMode | undefined; } + +``` +`ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. + +```typescript +public static fromId(scope: constructs.Construct, id: string, props: ImportedServiceNetworkProps ): IServiceNetwork { + return new ImportedServiceNetwork(scope, id, props); +} + +public static fromName(scope: constructs.Construct, id: string, serviceNetworkName: string ): IServiceNetwork { + return new ImportedServiceNetwork(scope, id, { serviceNetworkName: serviceNetworkName }); + } +``` + +`ServiceNetwork` will implement methods for a variety of tasks; + + +```typescript +// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application +addStatementToAuthPolicy(statement: iam.PolicyStatement) +``` + +```typescript +// applies the AuthPolicy that has been created, to the serviceNetwork. +applyAuthPolicyToServiceNetwork() +``` + +```typescript +// creates and associates a logging subscription to provide visisiblity for the lattice service +addloggingDestination(props: AddloggingDestinationProps) ``` +```typescript +// share the service network using RAM + public share(props: ShareServiceNetworkProps) +``` + +### ServiceNetworkAssociation + +Creates a Cloudformation `AWS::VpcLattice::ServiceNetworkServiceAssociation` +Associates a service with a service network. +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps +Consider using `.associateWithServiceNetwork` method on `Service` in preference. + + +```typescript +export interface ServiceNetworkAssociationProps { + /** + * lattice Service + */ + readonly serviceNetwork: IServiceNetwork; + /** + * Lattice ServiceId + */ + readonly serviceId: string; +} +``` + + + + ### Service +Creates a cloudformation `AWS::VpcLattice::Service` + A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. ![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) +`Service` extends `core.Resource` and implments `IService` + ```typescript -/** - * Create a vpcLattice service network. - * Implemented by `Service`. - */ export interface IService extends core.IResource { /** - * The Amazon Resource Name (ARN) of the service. - */ - readonly serviceArn: string; - /** - * The Id of the Service Network - */ + * The Id of the Service + */ readonly serviceId: string; /** - * Allow an Odd + * The Arn of the Service */ - readonly orgId: string | undefined; + readonly serviceArn: string; /** - * the policy document for the service; + * the discovered OrgId */ - authPolicy: iam.PolicyDocument; - + readonly orgId: string | undefined; /** - * Add A vpc listener to the Service. - * @param props + * Imported */ - shareToAccounts(props: ShareServiceProps): void; - + readonly imported: boolean; /** - * Grant Access to other principals + * The authType of the service. */ - grantAccess(principals: iam.IPrincipal[]): void; - + authType: AuthType | undefined; /** - * Apply the authAuthPolicy to the Service + * A certificate that may be used by the service */ - applyAuthPolicy(): iam.PolicyDocument; + certificate: certificatemanager.Certificate | undefined; /** - * Add A policyStatement to the Auth Policy + * A custom Domain used by the service */ - addPolicyStatement(statement: iam.PolicyStatement): void; -} -export interface IService extends core.IResource { + customDomain: string | undefined; /** - * The Amazon Resource Name (ARN) of the service. - */ - readonly serviceArn: string; + * A DNS Entry for the service + */ + dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** - * The Id of the Service Network + * A name for the service */ - readonly serviceId: string; + name: string | undefined; /** - * Allow an Odd - */ - readonly orgId: string | undefined; - /** - * the policy document for the service; + * The auth Policy for the service. */ authPolicy: iam.PolicyDocument; /** - * Add A vpc listener to the Service. - * @param props - */ - shareToAccounts(props: ShareServiceProps): void; - - /** - * Grant Access to other principals - */ - grantAccess(principals: iam.IPrincipal[]): void; - - /** - * Apply the authAuthPolicy to the Service - */ - applyAuthPolicy(): iam.PolicyDocument; - /** - * Add A policyStatement to the Auth Policy - */ - addPolicyStatement(statement: iam.PolicyStatement): void; + * associate the service with a servicenetwork. + */ + associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; } ``` @@ -364,7 +436,10 @@ export interface IService extends core.IResource { /** * Properties for a Lattice Service */ -export interface LatticeServiceProps { +/** + * Properties for a Lattice Service + */ +export interface ServiceProps { /** * Name for the service @@ -405,14 +480,103 @@ export interface LatticeServiceProps { *@default no sharing of the service */ readonly shares?: ShareServiceProps[] | undefined; + /** + * ServiceNetwork to associate with. + * @default will not assocaite with any serviceNetwork. + */ + readonly serviceNetwork?: IServiceNetwork | undefined; } +``` +`Service` will implement a static for importing the service. +```typescript +public static fromId(scope: constructs.Construct, id: string, serviceId: string): IService { + return new ImportedService(scope, id, serviceId); + } +``` +Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. + + + +`Service` will implement methods for the following +```typescript +/** + * .grantAccess on a lattice service, will permit the principals to + * access all resoruces of the service. Consider using finer permissions + * at the rule level. + * + * @param principals + */ +public grantAccess(principals: iam.IPrincipal[]) { } +``` + +```typescript + /** + * apply an authpolicy to the service + */ + public applyAuthPolicy(): iam.PolicyDocument { } ``` +```typescript + /** + * Add a PolicyStatement to the auth policy + */ + public addPolicyStatement(statement: iam.PolicyStatement): void { } +``` + +```typescript + /** + * Share the service to other accounts via RAM + */ + public shareToAccounts(props: ShareServiceProps): void { } +``` + +```typescript +/** + * Associate with a Service Network + */ + public associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void { } +``` + + +### ServiceAssociation + +Associates a ServiceNetwork to a Service + +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. + +```typescript +/** + * Props for Service Assocaition + */ +export interface ServiceNetworkAssociationProps { + /** + * lattice Service + */ + readonly serviceNetwork: IServiceNetwork; + /** + * Lattice ServiceId + */ + readonly serviceId: string; +} +``` + + + + + + + ### Listener + +Creates a cloudformation `AWS::VpcLattice::Listener` + A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the service routes requests to its registered targets. -It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used. +It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used on a service + + +`Listener` extends `core.resource` implements `IListener` ``` typescript @@ -438,12 +602,9 @@ export interface IListener extends core.IResource { } ``` -`Listener` will take `ListenerProps` +`Listener` will consome `ListenerProps` ```typescript -/** - * Propertys to Create a Lattice Listener - */ /** * Propertys to Create a Lattice Listener */ @@ -461,7 +622,6 @@ export interface ListenerProps { /** * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol * @default 80 or 443 depending on the Protocol - */ readonly port?: number | undefined /** @@ -476,10 +636,27 @@ export interface ListenerProps { } ``` -### TargetGroups +`Listener` will implement methods + +```typescript + /** + * add a rule to the listener, which will implement AWS::VpcLattice::Rule + * @param props AddRuleProps + */ + public addListenerRule(props: AddRuleProps): void { } +``` + + + +### TargetGroup + +Creates a cloudformation `AWS::VpcLattice::TargetGroup` A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers +`TargetGroup` extends core.Resource and implements ITargetGroup + + ```typescript /** Create a vpc lattice TargetGroup. @@ -515,9 +692,15 @@ export interface TargetGroupProps { } ``` +--- +## Classes + + + ### Target -Target is an abstract class with static function to return propertys for a TargetGroup +`Target` is an abstract class with static function to return propertys for use in a `TargetGroup` +Targets can be lambda, ipAddress, ec2instances, or applicaiton loadbalancers. ```typescript /** @@ -529,97 +712,29 @@ export abstract class Target { * Lambda Target * @param lambda */ - public static lambda(lambda: aws_lambda.Function[]): Target { - - let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; - lambda.forEach((target) => { - targets.push({ id: target.functionArn }); - }); - - return { - type: TargetType.LAMBDA, - targets: targets, - }; - }; + public static lambda(lambda: aws_lambda.Function[]): Target { }; /** * IpAddress as Targets * @param ipAddress * @param config */ - public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { - - let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; - - ipAddress.forEach((target) => { - targets.push({ id: target }); - }); - - return { - type: TargetType.LAMBDA, - targets: targets, - config: config, - }; - - }; + public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { }; /** * EC2 Instances as Targets * @param ec2instance * @param config */ - public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { - - let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; - - ec2instance.forEach((target) => { - targets.push({ id: target.instanceId }); - }); - - return { - type: TargetType.LAMBDA, - targets: targets, - config: config, - }; - - }; + public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { }; /** * Application Load Balancer as Targets * @param alb * @param config */ - public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { - - let targets: aws_vpclattice.CfnTargetGroup.TargetProperty[] = []; - - alb.forEach((target) => { - targets.push({ id: target.listenerArn }); - }); + public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { } - return { - type: TargetType.LAMBDA, - targets: targets, - config: config, - }; - - } - /** - * The type of target - */ - public abstract readonly type: TargetType; - /** - * References to the targets, ids or Arns - */ - public abstract readonly targets: aws_vpclattice.CfnTargetGroup.TargetProperty[]; - /** - * Configuration for the TargetGroup, if it is not a lambda - */ - public abstract readonly config?: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty | undefined; - - constructor() {}; - -} ``` ### LoggingDestination @@ -636,50 +751,243 @@ export abstract class LoggingDestination { * Construct a logging destination for a S3 Bucket * @param bucket an s3 bucket */ - public static s3(bucket: s3.IBucket): LoggingDestination { - return { - name: bucket.bucketName, - arn: bucket.bucketArn, - }; - } + public static s3(bucket: s3.IBucket): LoggingDestination { } /** * Send to CLoudwatch * @param logGroup */ - public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination { - return { - name: logGroup.logGroupName, - arn: logGroup.logGroupArn, - }; - } + public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination { } /** * Stream to Kinesis * @param stream */ - public static kinesis(stream: kinesis.IStream): LoggingDestination { + public static kinesis(stream: kinesis.IStream): LoggingDestination { } + +} +``` + +### HeatlhCheck + +HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. + +```typescript +/** + * A Configuration of the TargetGroup Health Check. + */ +export interface TargetGroupHealthCheckProps { + /** + * Enable this Health Check + * @default true + */ + readonly enabled?: boolean | undefined; + /** + * Health Check Interval + * @default 30 seconds + */ + readonly healthCheckInterval?: core.Duration | undefined; + /** + * TimeOut Period + * @default 5 seconds + */ + readonly healthCheckTimeout?: core.Duration | undefined; + /** + * Number of Healthy Responses before Target is considered healthy + * @default 2 + */ + readonly healthyThresholdCount?: number | undefined; + /** + * Check based on Response from target + * @default 200 OK + */ + readonly matcher?: FixedResponse | undefined; + /** + * Path to use for Health Check + * @default '/' + */ + readonly path?: string | undefined; + /** + * Port to use for Health Check + * @default 443 + */ + readonly port?: number | undefined; + /** + * Protocol to use for Health Check + * @default HTTPS + */ + readonly protocol?: Protocol | undefined; + /** + * Protocol to use for Health Check + * @default HTTP2 + */ + readonly protocolVersion?: ProtocolVersion | undefined; + /** + * Number of unhealty events before Target is considered unhealthy + * @default 1 + */ + readonly unhealthyThresholdCount?: number | undefined; +} + +/** + * Create a Health Check for a target + */ +export abstract class HealthCheck { + + /** + * A Health Check configuration object for a target + * @param props + * @returns HealthCheck + */ + public static check(props: TargetGroupHealthCheckProps): HealthCheck { + + // validate the ranges for the health check + if (props.healthCheckInterval) { + if (props.healthCheckInterval.toSeconds() < 5 || props.healthCheckInterval.toSeconds() > 300) { + throw new Error('HealthCheckInterval must be between 5 and 300 seconds'); + } + }; + + if (props.healthCheckTimeout) { + if (props.healthCheckTimeout.toSeconds() < 1 || props.healthCheckTimeout.toSeconds() > 120) { + throw new Error('HealthCheckTimeout must be between 1 and 120seconds'); + } + }; + + if (props.healthyThresholdCount) { + if (props.healthyThresholdCount < 1 || props.healthyThresholdCount > 10) { + throw new Error('HealthyThresholdCount must be between 1 and 10'); + } + }; + + if (props.protocolVersion) { + if (props.protocolVersion === ProtocolVersion.GRPC) { + throw new Error('GRPC is not supported'); + } + }; + + if (props.unhealthyThresholdCount) { + if (props.unhealthyThresholdCount < 2 || props.unhealthyThresholdCount > 10) { + throw new Error('UnhealthyThresholdCount must be between 2 and 10'); + } + } + + var port: number; + if (props.port) { + port = props.port; + } else if ( props.protocol === Protocol.HTTP ) { + port = 80; + } else { + port = 443; + }; + + let matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined = undefined; + if (props.matcher) { + const codeAsString = props.matcher.toString(); + matcher = { httpCode: codeAsString }; + }; + return { - name: stream.streamName, - arn: stream.streamArn, + enabled: props.enabled ?? true, + healthCheckInterval: props.healthCheckInterval ?? core.Duration.seconds(30), + healthCheckTimeout: props.healthCheckTimeout ?? core.Duration.seconds(5), + path: props.path ?? '/', + protocol: props.protocol ?? 'HTTPS', + port: port, + protocolVersion: props.protocolVersion ?? 'HTTP1', + unhealthyThresholdCount: props.unhealthyThresholdCount ?? 2, + healthyThresholdCount: props.healthyThresholdCount ?? 5, + matcher: matcher, }; - } + }; /** - * A name of the destination - */ - public abstract readonly name: string; + * health check is enabled. + */ + public abstract readonly enabled: boolean; + /** + * healthCheck Interval + */ + public abstract readonly healthCheckInterval: core.Duration; /** - * An Arn of the destination + * HealthCheck Timeout */ - public abstract readonly arn: string; + public abstract readonly healthCheckTimeout: core.Duration; + /** + * Target Match reponse + */ + public abstract readonly matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined; + /** + * Path to check + */ + public abstract readonly path: string; + /** + * Port to check + */ + public abstract readonly port: number; + /** Protocol + * + */ + public abstract readonly protocol: string; + /** + * HTTP Protocol Version + */ + public abstract readonly protocolVersion: string; + /** + * Unhealthy Threshold Count + */ + public abstract readonly unhealthyThresholdCount: number; + /** + * Healthy Threshold Count + */ + public abstract readonly healthyThresholdCount: number; protected constructor() {}; -} + +}; ``` +--- +## Enums +The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. + +### AuthType +Lattice Services can use IAM for Authentication or NONE. + +### FixedResponse +Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need expanding + +### HTTPMethods +Valid HTTP Methods, these are used for constructing Rules. + +### IpAddressType +IPv4 and IPv6, used for creating rules + +### MatchOperators +Contains, Exact and Prefix used for creating rules + +### PathMatchType +Exact Prefix, used for creating path matches in rules. + +### Protocol +HTTP or HTTPS - used for creating rules. + +### PRotocolVersion +HTTP1, HTTP2 or GRPC - used for creating rules. + +### RuleAccessMode +Used for creating Authenticaiton Policy Access Modes. + +### ServiceNetworkAccessMode +Used for creating Authenticaiton Policy Access Modes. (Note a different set of options from RuleAccessMode) + +### TargetTypes +LAMBDA, IP, INSTANCE, ALB. Used for creating targets. + --- -### FAQ + + +## FAQ **What are we launching today?** Amazon VPC Lattice AWS CDK L2 Construct From 9a364f721c164da03e55a582106ab85b79314284 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 16:26:54 +1200 Subject: [PATCH 12/31] Update README.md --- README.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c147faeb4..1fbddf89a 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,15 @@ future state of the libraries and to discover projects for contribution. \#|Title|Owner|Status ---|-----|-----|------ [52](https://github.com/aws/aws-cdk-rfcs/issues/52)|[Support resource import](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0052-resource-importing-support.md)||👷 implementing -[77](https://github.com/aws/aws-cdk-rfcs/issues/77)|[CloudFormation Registry Support](https://github.com/aws/aws-cdk-rfcs/issues/77)||👷 implementing +[77](https://github.com/aws/aws-cdk-rfcs/issues/77)|[CloudFormation Registry Support](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0077-import-external-resources.md)||👷 implementing [340](https://github.com/aws/aws-cdk-rfcs/issues/340)|[Kinesis Data Firehose Delivery Stream L2](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0340-firehose-l2.md)|[@BenChaimberg](https://github.com/BenChaimberg)|👷 implementing [431](https://github.com/aws/aws-cdk-rfcs/issues/431)|[SageMaker Model Hosting L2 Constructs](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0431-sagemaker-l2-endpoint.md)||👷 implementing [456](https://github.com/aws/aws-cdk-rfcs/issues/456)|[L2 ElastiCache support](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0456-elasticache-l2.md)||👷 implementing [460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing +[474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)||👷 implementing [457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning -[502](https://github.com/aws/aws-cdk-rfcs/issues/502)|[L2 Constructs for vpcLattice](https://github.com/aws/aws-cdk-rfcs/issues/502)||💡 proposed +[507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved +[510](https://github.com/aws/aws-cdk-rfcs/issues/510)|[DyanmoDB Global Table L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0510-dynamodb-global-table.md)|[@vinayak-kukreja](https://github.com/vinayak-kukreja)|👍 approved [8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review [175](https://github.com/aws/aws-cdk-rfcs/issues/175)|[AppSync Mapping Template Object Model](https://github.com/aws/aws-cdk-rfcs/pull/177)|[@MrArnoldPalmer](https://github.com/MrArnoldPalmer)|✍️ review [317](https://github.com/aws/aws-cdk-rfcs/issues/317)|[CDK third-party dependencies management](https://github.com/aws/aws-cdk-rfcs/issues/317)||✍️ review @@ -125,13 +127,20 @@ future state of the libraries and to discover projects for contribution. [470](https://github.com/aws/aws-cdk-rfcs/issues/470)|[Amazon Aurora Serverless v2 support](https://github.com/aws/aws-cdk-rfcs/issues/470)||💡 proposed [471](https://github.com/aws/aws-cdk-rfcs/issues/471)|[Amazon Managed Grafana L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/471)||💡 proposed [473](https://github.com/aws/aws-cdk-rfcs/issues/473)|[EventBridge Pipes L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/473)|[@mrgrain](https://github.com/mrgrain)|💡 proposed -[474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/474)||💡 proposed [481](https://github.com/aws/aws-cdk-rfcs/issues/481)|[Add L2 constructs for Amazon Redshift Serverless](https://github.com/aws/aws-cdk-rfcs/issues/481)||💡 proposed [483](https://github.com/aws/aws-cdk-rfcs/issues/483)|[AppFlow L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/483)|[@iliapolo](https://github.com/iliapolo)|💡 proposed [487](https://github.com/aws/aws-cdk-rfcs/issues/487)|[New L2 Construct for Step Functions Map State in Distributed Mode](https://github.com/aws/aws-cdk-rfcs/issues/487)||💡 proposed [489](https://github.com/aws/aws-cdk-rfcs/issues/489)|[Add API to register and execute code before or after CDK App lifecycle events](https://github.com/aws/aws-cdk-rfcs/issues/489)||💡 proposed [491](https://github.com/aws/aws-cdk-rfcs/issues/491)|[CloudFront Origin Access Control L2](https://github.com/aws/aws-cdk-rfcs/issues/491)||💡 proposed [492](https://github.com/aws/aws-cdk-rfcs/issues/492)|[Amazon OpenSearch Serverless L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/492)||💡 proposed +[495](https://github.com/aws/aws-cdk-rfcs/issues/495)|[AWS IAM Identity Store L2 construct](https://github.com/aws/aws-cdk-rfcs/issues/495)||💡 proposed +[497](https://github.com/aws/aws-cdk-rfcs/issues/497)|[AWS Glue L2 CDK Construct](https://github.com/aws/aws-cdk-rfcs/issues/497)|[@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra)|💡 proposed +[499](https://github.com/aws/aws-cdk-rfcs/issues/499)|[AppConfig L2 Constructs](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0499-appconfig-constructs.md)||💡 proposed +[501](https://github.com/aws/aws-cdk-rfcs/issues/501)|[L2 Constructs for Lattice Service](https://github.com/aws/aws-cdk-rfcs/issues/501)||💡 proposed +[502](https://github.com/aws/aws-cdk-rfcs/issues/502)|[Amazon VPC Lattice L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/502)||💡 proposed +[509](https://github.com/aws/aws-cdk-rfcs/issues/509)|[Add Step Functions SageMaker CreateProcessingJob task construct](https://github.com/aws/aws-cdk-rfcs/issues/509)||💡 proposed +[512](https://github.com/aws/aws-cdk-rfcs/issues/512)|[Thumbprint L2 Construct for use with IAM OIDC Provider](https://github.com/aws/aws-cdk-rfcs/issues/512)||💡 proposed +[513](https://github.com/aws/aws-cdk-rfcs/issues/513)|[Application Specific Staging Resources](https://github.com/aws/aws-cdk-rfcs/issues/513)||💡 proposed [1](https://github.com/aws/aws-cdk-rfcs/issues/1)|[CDK Watch](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0001-cdk-update.md)||✅ done [6](https://github.com/aws/aws-cdk-rfcs/issues/6)|[Monolithic Packaging](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0006-monolothic-packaging.md)||✅ done [7](https://github.com/aws/aws-cdk-rfcs/issues/7)|[Lambda Bundles](https://github.com/aws/aws-cdk-rfcs/issues/7)||✅ done @@ -157,7 +166,7 @@ future state of the libraries and to discover projects for contribution. [282](https://github.com/aws/aws-cdk-rfcs/issues/282)|[CDK Pipelines security posture change approvals](https://github.com/aws/aws-cdk-rfcs/issues/282)||✅ done [287](https://github.com/aws/aws-cdk-rfcs/issues/287)|[Deprecated API Warnings](https://github.com/aws/aws-cdk-rfcs/blob/master/text/287-cli-deprecation-warnings.md)||✅ done [308](https://github.com/aws/aws-cdk-rfcs/issues/308)|[CLI notices](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0308-cli-advisories.md)||✅ done -[322](https://github.com/aws/aws-cdk-rfcs/issues/322)|[CDK Pipelines Updated API](https://github.com/aws/aws-cdk-rfcs/issues/322)||✅ done +[322](https://github.com/aws/aws-cdk-rfcs/issues/322)|[CDK Pipelines Updated API](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0322-cdk-pipelines-updated-api.md)||✅ done [324](https://github.com/aws/aws-cdk-rfcs/issues/324)|[Construct Hub](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0324-cdk-construct-hub.md)|[@RomainMuller](https://github.com/RomainMuller)|✅ done [328](https://github.com/aws/aws-cdk-rfcs/issues/328)|[polyglot assert library](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0328-polyglot-assert.md)|[@nija-at](https://github.com/nija-at)|✅ done [353](https://github.com/aws/aws-cdk-rfcs/issues/353)|[Constructs for all public CloudFormation resources and modules](https://github.com/aws/aws-cdk-rfcs/blob/master/text/353-cfn-registry-constructs.md)||✅ done @@ -169,7 +178,7 @@ future state of the libraries and to discover projects for contribution. [164](https://github.com/aws/aws-cdk-rfcs/issues/164)|[Construct Library Segments](https://github.com/aws/aws-cdk-rfcs/pull/169)|[@nija-at](https://github.com/nija-at)|👎 rejected [272](https://github.com/aws/aws-cdk-rfcs/issues/272)|[CI/CD to Cloudfront Deploy](https://github.com/aws/aws-cdk-rfcs/issues/272)||👎 rejected [436](https://github.com/aws/aws-cdk-rfcs/issues/436)|[Amazon GameLift L2 Constructs](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0436-gamelift-l2.md)||❓unknown -[485](https://github.com/aws/aws-cdk-rfcs/issues/485)|[AWS Batch L2](https://github.com/aws/aws-cdk-rfcs/issues/485)||❓unknown +[485](https://github.com/aws/aws-cdk-rfcs/issues/485)|[AWS Batch L2](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0485-aws-batch.md)||❓unknown ## What is an RFC? From aaff81c8a417c11c4dfc1b920de3e489e9279d3a Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 13 Jul 2023 13:25:18 +1200 Subject: [PATCH 13/31] Update 0502_aws-vpclattice.md - Responses to corys comments. - Removed references to L1 constructs ( dns, and default actions ) - added small section about networking - modified props in assocaiateVPC and fixed casing of some variables. --- text/0502_aws-vpclattice.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index b60e340ca..714dc3ae4 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -106,7 +106,6 @@ export class LatticeTestStack extends core.Stack { httpMatch: { pathMatches: { path: '/hello' }, }, - // we will only allow access to this service from the ec2 instance accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED }); @@ -154,6 +153,17 @@ export class LatticeTestStack extends core.Stack { } } ``` +--- +## Vpc Lattice Networking. + +When a vpc is associated with a vpclattice servicenetwork, the following occurs; + +- A service interface is placed in the vpc. Lattice uses link-local (169.254.x.x) address's for this. +- It associates a aws service domain (*.on.aws) with the vpc, which is how resources in the vpc are able to resolve the service interface. Generally you would then put a CNAME record at it. +- Optionally an array of securitygroups can be provided, which are applied on to the interface to filter what can connect + +https://d1.awsstatic.com/events/Summits/reinvent2022/NET215_NEW-LAUNCH!-Introducing-Amazon-VPC-Lattice-Simplifying-application-networking.pdf + --- ## Proposed API Design for vpclattice: @@ -401,7 +411,7 @@ export interface IService extends core.IResource { /** * The authType of the service. */ - authType: AuthType | undefined; + authType: string | undefined; /** * A certificate that may be used by the service */ @@ -410,10 +420,6 @@ export interface IService extends core.IResource { * A custom Domain used by the service */ customDomain: string | undefined; - /** - * A DNS Entry for the service - */ - dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** * A name for the service */ @@ -473,7 +479,7 @@ export interface ServiceProps { * A custom hosname * @default no hostname is used */ - readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; + readonly hostedZone?: r53.IHostedZone | undefined; /** * Share Service @@ -613,7 +619,7 @@ export interface ListenerProps { * * A default action that will be taken if no rules match. * @default 404 NOT Found */ - readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; + readonly defaultAction?: DefaultListenerAction | undefined; /** * protocol that the listener will listen on * @default HTTPS @@ -622,8 +628,9 @@ export interface ListenerProps { /** * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol * @default 80 or 443 depending on the Protocol + */ - readonly port?: number | undefined + readonly port?: number | undefined; /** * The Name of the service. * @default CloudFormation provided name. From 7a001f771e38f53f648f2b40b0ab4b225116c30e Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 13 Jul 2023 17:34:14 +1200 Subject: [PATCH 14/31] Update 0502_aws-vpclattice.md Removing applyAuth Methods. --- text/0502_aws-vpclattice.md | 96 +++++++++++++------------------------ 1 file changed, 34 insertions(+), 62 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 714dc3ae4..4e6805a75 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -78,18 +78,10 @@ export class LatticeTestStack extends core.Stack { // Create a Lattice Service // this will default to using IAM Authentication const myLatticeService = new Service(this, 'myLatticeService', {}); - // add a listener to the service, using the defaults - // - HTTPS - // - Port 443 - // - default action of providing 404 NOT Found, - // - cloudformation name - const myListener = new vpclattice.Listener(this, 'Listener', { - service: myLatticeService, - }) - + // add a listenerRule that will use the helloworld lambda as a Target - mylistener.addListenerRule({ + const helloworld: RuleProp = { name: 'helloworld', priority: 10, action: [ @@ -107,10 +99,10 @@ export class LatticeTestStack extends core.Stack { pathMatches: { path: '/hello' }, }, accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED - }); + }; //add a listenerRule that will use the goodbyeworld lambda as a Target - mylistener.addListenerRule({ + const goodbye: RuleProp = { name: 'goodbyeworld', priority: 20, action: [ @@ -130,10 +122,20 @@ export class LatticeTestStack extends core.Stack { // we will only allow access to this service from the ec2 instance allowedPrincipals: [support.ec2instance.role], accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, - }); + }; - - myLatticeService.applyAuthPolicy(); + // add a listener to the service, using the defaults + // - HTTPS + // - Port 443 + // - default action of providing 404 NOT Found, + // - cloudformation name + const myListener = new vpclattice.Listener(this, 'Listener', { + service: myLatticeService, + rules: [ + helloworld, + goodbyeworld, + ] + }) /** * Create a ServiceNetwork. @@ -148,8 +150,6 @@ export class LatticeTestStack extends core.Stack { support.vpc1, ], }); - - serviceNetwork.applyAuthPolicyToServiceNetwork(); } } ``` @@ -288,8 +288,7 @@ export interface ServiceNetworkProps { readonly name?: string; /** - * The type of authentication to use with the Service Network. The only method avaialble is - * AWS_IAM, however in anticipation, it is expected that other types will be added. + * The type of authentication to use with the Service Network * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; @@ -312,12 +311,15 @@ export interface ServiceNetworkProps { */ readonly vpcs?: ec2.IVpc[] | undefined; /** - * An access mode provides 'pre-canned' conditions for the policy - * @default no conditions + * Allow external principals + * @default false */ readonly accessmode?: ServiceNetworkAccessMode | undefined; + /** + * Additional Optional Auth statements: + */ + readonly authStatements?: iam.PolicyStatement[] | undefined; } - ``` `ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. @@ -331,18 +333,8 @@ public static fromName(scope: constructs.Construct, id: string, serviceNetworkNa } ``` -`ServiceNetwork` will implement methods for a variety of tasks; - +`ServiceNetwork` will implement public methods for a variety of tasks; -```typescript -// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application -addStatementToAuthPolicy(statement: iam.PolicyStatement) -``` - -```typescript -// applies the AuthPolicy that has been created, to the serviceNetwork. -applyAuthPolicyToServiceNetwork() -``` ```typescript // creates and associates a logging subscription to provide visisiblity for the lattice service @@ -375,9 +367,6 @@ export interface ServiceNetworkAssociationProps { } ``` - - - ### Service Creates a cloudformation `AWS::VpcLattice::Service` @@ -433,6 +422,10 @@ export interface IService extends core.IResource { * associate the service with a servicenetwork. */ associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; + /** + * apply an authpolicy to the servicenetwork + */ + applyAuthPolicy(): iam.PolicyDocument; } ``` @@ -516,20 +509,6 @@ Note: unlike ServiceNetwork there are minimal reason to implmenet a import by na public grantAccess(principals: iam.IPrincipal[]) { } ``` -```typescript - /** - * apply an authpolicy to the service - */ - public applyAuthPolicy(): iam.PolicyDocument { } -``` - -```typescript - /** - * Add a PolicyStatement to the auth policy - */ - public addPolicyStatement(statement: iam.PolicyStatement): void { } -``` - ```typescript /** * Share the service to other accounts via RAM @@ -608,7 +587,7 @@ export interface IListener extends core.IResource { } ``` -`Listener` will consome `ListenerProps` +`Listener` will consume `ListenerProps` ```typescript /** @@ -640,21 +619,14 @@ export interface ListenerProps { * The Id of the service that this listener is associated with. */ readonly service: IService; -} -``` - -`Listener` will implement methods - -```typescript - /** - * add a rule to the listener, which will implement AWS::VpcLattice::Rule - * @param props AddRuleProps + /** + * rules for the listener */ - public addListenerRule(props: AddRuleProps): void { } + readonly rules?: RuleProp[] | undefined; +} ``` - ### TargetGroup Creates a cloudformation `AWS::VpcLattice::TargetGroup` From c2d4e97ea3a36dcfcdd55aeeb703d1af1bac0c96 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sat, 15 Jul 2023 13:49:52 +1200 Subject: [PATCH 15/31] Update 0502_aws-vpclattice.md Migrated Targets to use Integration Pattern --- text/0502_aws-vpclattice.md | 38 +++---------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 4e6805a75..4b49545d9 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -675,46 +675,14 @@ export interface TargetGroupProps { ## Classes +### Targets + +Lattice Targets will be created in `aws-vpclattice-targets` a seperate module. They will implment `ITarget` -### Target `Target` is an abstract class with static function to return propertys for use in a `TargetGroup` Targets can be lambda, ipAddress, ec2instances, or applicaiton loadbalancers. -```typescript -/** - * Targets for target Groups - */ -export abstract class Target { - - /** - * Lambda Target - * @param lambda - */ - public static lambda(lambda: aws_lambda.Function[]): Target { }; - - /** - * IpAddress as Targets - * @param ipAddress - * @param config - */ - public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { }; - - /** - * EC2 Instances as Targets - * @param ec2instance - * @param config - */ - public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { }; - - /** - * Application Load Balancer as Targets - * @param alb - * @param config - */ - public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { } - -``` ### LoggingDestination From 86f04b2a9b9e57a4fb62ae085c98579cd0d1d5fb Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 19 Jul 2023 09:29:20 +1200 Subject: [PATCH 16/31] Linting issues in Markup document fixed. Linting was turned off for markup docs. Now fixed. --- text/0502_aws-vpclattice.md | 316 +++++++++++++++++++++--------------- 1 file changed, 187 insertions(+), 129 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 4b49545d9..bb81853ca 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -6,49 +6,55 @@ - [FAQ](#faq) - [Acceptance](#acceptance) +--- ---- ## Project Information -**Status** (DRAFT) +### Status + +(DRAFT) + +### Original Author(s) -**Original Author(s):** @mrpackethead, , @taylaand, @nbaillie +@mrpackethead, , @taylaand, @nbaillie -**Tracking Issue:** #502 +### Tracking Issue -**API Bar Raiser:** @TheRealAmazonKendra +502 -**Public Issues ( aws-cdk)** -* (vpclattice): L2 for Amazon VPC Lattice #25452 +### API Bar Raiser +@TheRealAmazonKendra -**Prototype Code** -- https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha -- https://github.com/raindancers/vpclattice-prealpha-demo +## Public Issues -** Constructs.dev ** -- https://constructs.dev/packages/aws-vpclattice-prealpha +( aws-cdk)(vpclattice): L2 for Amazon VPC Lattice #25452 +### Prototype Code -**VpcLattice** +- +- +- + +--- + +## VpcLattice Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. -The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. - +The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. + --- ## Example Implementation -- A Service is created +- A Service is created - A Listener is added to the serviceand associated with a ServiceNetwork - A Rule is assocated with the listener which uses a Lambda function as a target - A Service Network is created -- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. -A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. -Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests.. Lambda1 will be in VPC1, and Lambda2 in VPC2 - - +- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. +- A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. +- Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests. Lambda1 will be in VPC1, and Lambda2 in VPC2 ```typescript import * as core from 'aws-cdk-lib'; @@ -78,10 +84,18 @@ export class LatticeTestStack extends core.Stack { // Create a Lattice Service // this will default to using IAM Authentication const myLatticeService = new Service(this, 'myLatticeService', {}); - + // add a listener to the service, using the defaults + // - HTTPS + // - Port 443 + // - default action of providing 404 NOT Found, + // - cloudformation name + const myListener = new vpclattice.Listener(this, 'Listener', { + service: myLatticeService, + }) + // add a listenerRule that will use the helloworld lambda as a Target - const helloworld: RuleProp = { + mylistener.addListenerRule({ name: 'helloworld', priority: 10, action: [ @@ -98,11 +112,12 @@ export class LatticeTestStack extends core.Stack { httpMatch: { pathMatches: { path: '/hello' }, }, + // we will only allow access to this service from the ec2 instance accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED - }; + }); //add a listenerRule that will use the goodbyeworld lambda as a Target - const goodbye: RuleProp = { + mylistener.addListenerRule({ name: 'goodbyeworld', priority: 20, action: [ @@ -122,20 +137,10 @@ export class LatticeTestStack extends core.Stack { // we will only allow access to this service from the ec2 instance allowedPrincipals: [support.ec2instance.role], accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, - }; + }); - // add a listener to the service, using the defaults - // - HTTPS - // - Port 443 - // - default action of providing 404 NOT Found, - // - cloudformation name - const myListener = new vpclattice.Listener(this, 'Listener', { - service: myLatticeService, - rules: [ - helloworld, - goodbyeworld, - ] - }) + + myLatticeService.applyAuthPolicy(); /** * Create a ServiceNetwork. @@ -150,63 +155,57 @@ export class LatticeTestStack extends core.Stack { support.vpc1, ], }); + + serviceNetwork.applyAuthPolicyToServiceNetwork(); } } ``` ---- -## Vpc Lattice Networking. - -When a vpc is associated with a vpclattice servicenetwork, the following occurs; - -- A service interface is placed in the vpc. Lattice uses link-local (169.254.x.x) address's for this. -- It associates a aws service domain (*.on.aws) with the vpc, which is how resources in the vpc are able to resolve the service interface. Generally you would then put a CNAME record at it. -- Optionally an array of securitygroups can be provided, which are applied on to the interface to filter what can connect - -https://d1.awsstatic.com/events/Summits/reinvent2022/NET215_NEW-LAUNCH!-Introducing-Amazon-VPC-Lattice-Simplifying-application-networking.pdf --- -## Proposed API Design for vpclattice: -[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) +## Proposed API Design for vpclattice +[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) ### Constructs - ✓ [AssociateVpc](#associatevpc) - ✓ [ServiceNetwork](#servicenetwork) - ✓ [ServiceNetworkAssociation] (#servicenetworkassociation) -- ✓ [Service](#serviceService) +- ✓ [Service](service) - ✓ [ServiceAssociation] - ✓ [Listener](#listener) - ✓ [TargetGroup](#targetgroup) ### Classes - - [HealthCheck] - - [LoggingDestination] - - [Target] + +- [HealthCheck] +- [LoggingDestination] +- [Target] ### Enums - - [AuthType] - - [FixedResponse] - - [HTTPMethods] - - [IpAddressType] - - [MatchOperator] - - [PathMatchType] - - [Protocol] - - [ProtocolVersion] - - [RuleAccessMode] - - [ServiceNetworkAccessMode] - - [TargetType] +- [AuthType] +- [FixedResponse] +- [HTTPMethods] +- [IpAddressType] +- [MatchOperator] +- [PathMatchType] +- [Protocol] +- [ProtocolVersion] +- [RuleAccessMode] +- [ServiceNetworkAccessMode] +- [TargetType] --- -## Constructs + +## Constructs Details ### AssociateVpc Creates a CloudFormation `AWS::VpcLattice::ServiceNetworkVpcAssociation` -This construct associates a VPC, with a service network. It creates an endpoint interface in a VPC to enable the resources in the vpc +This construct associates a VPC, with a service network. It creates an endpoint interface in a VPC to enable the resources in the vpc to be clients of the service network. The construct extends core.Resource, and will consume AssociateVpcProps. @@ -232,8 +231,6 @@ export interface AssociateVpcProps { } ``` - - ### ServiceNetwork Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` @@ -242,7 +239,6 @@ A service network is a logical boundary for a collection of services. Services a ![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) - The construct will extend ServiceNetworkBase and implement IServiceNetwork. ```typescript @@ -277,7 +273,6 @@ export interface IServiceNetwork extends core.IResource { The Construct will consume ServiceNetworkProps. - ```typescript export interface ServiceNetworkProps { @@ -288,7 +283,8 @@ export interface ServiceNetworkProps { readonly name?: string; /** - * The type of authentication to use with the Service Network + * The type of authentication to use with the Service Network. The only method avaialble is + * AWS_IAM, however in anticipation, it is expected that other types will be added. * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; @@ -311,16 +307,14 @@ export interface ServiceNetworkProps { */ readonly vpcs?: ec2.IVpc[] | undefined; /** - * Allow external principals - * @default false + * An access mode provides 'pre-canned' conditions for the policy + * @default no conditions */ readonly accessmode?: ServiceNetworkAccessMode | undefined; - /** - * Additional Optional Auth statements: - */ - readonly authStatements?: iam.PolicyStatement[] | undefined; } + ``` + `ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. ```typescript @@ -333,8 +327,18 @@ public static fromName(scope: constructs.Construct, id: string, serviceNetworkNa } ``` -`ServiceNetwork` will implement public methods for a variety of tasks; +`ServiceNetwork` will implement methods for a variety of tasks; +```typescript + +// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application +addStatementToAuthPolicy(statement: iam.PolicyStatement) +``` + +```typescript +// applies the AuthPolicy that has been created, to the serviceNetwork. +applyAuthPolicyToServiceNetwork() +``` ```typescript // creates and associates a logging subscription to provide visisiblity for the lattice service @@ -353,8 +357,8 @@ Associates a service with a service network. `ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps Consider using `.associateWithServiceNetwork` method on `Service` in preference. - ```typescript + export interface ServiceNetworkAssociationProps { /** * lattice Service @@ -373,11 +377,9 @@ Creates a cloudformation `AWS::VpcLattice::Service` A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. - ![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) - -`Service` extends `core.Resource` and implments `IService` +`Service` extends `core.Resource` and implments `IService` ```typescript export interface IService extends core.IResource { @@ -400,7 +402,7 @@ export interface IService extends core.IResource { /** * The authType of the service. */ - authType: string | undefined; + authType: AuthType | undefined; /** * A certificate that may be used by the service */ @@ -409,6 +411,10 @@ export interface IService extends core.IResource { * A custom Domain used by the service */ customDomain: string | undefined; + /** + * A DNS Entry for the service + */ + dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** * A name for the service */ @@ -422,15 +428,12 @@ export interface IService extends core.IResource { * associate the service with a servicenetwork. */ associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; - /** - * apply an authpolicy to the servicenetwork - */ - applyAuthPolicy(): iam.PolicyDocument; } ``` `Service` will take `ServiceProps` as props + ```typescript /** * Properties for a Lattice Service @@ -472,7 +475,7 @@ export interface ServiceProps { * A custom hosname * @default no hostname is used */ - readonly hostedZone?: r53.IHostedZone | undefined; + readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** * Share Service @@ -488,17 +491,19 @@ export interface ServiceProps { ``` `Service` will implement a static for importing the service. + ```typescript public static fromId(scope: constructs.Construct, id: string, serviceId: string): IService { return new ImportedService(scope, id, serviceId); } -``` -Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. - +``` +Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. `Service` will implement methods for the following + ```typescript + /** * .grantAccess on a lattice service, will permit the principals to * access all resoruces of the service. Consider using finer permissions @@ -509,6 +514,20 @@ Note: unlike ServiceNetwork there are minimal reason to implmenet a import by na public grantAccess(principals: iam.IPrincipal[]) { } ``` +```typescript + /** + * apply an authpolicy to the service + */ + public applyAuthPolicy(): iam.PolicyDocument { } +``` + +```typescript + /** + * Add a PolicyStatement to the auth policy + */ + public addPolicyStatement(statement: iam.PolicyStatement): void { } +``` + ```typescript /** * Share the service to other accounts via RAM @@ -523,12 +542,11 @@ public grantAccess(principals: iam.IPrincipal[]) { } public associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void { } ``` - ### ServiceAssociation Associates a ServiceNetwork to a Service -`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. ```typescript /** @@ -546,12 +564,6 @@ export interface ServiceNetworkAssociationProps { } ``` - - - - - - ### Listener Creates a cloudformation `AWS::VpcLattice::Listener` @@ -560,9 +572,7 @@ A listener is a process that checks for connection requests, using the protocol It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used on a service - -`Listener` extends `core.resource` implements `IListener` - +`Listener` extends `core.resource` implements `IListener` ``` typescript /** @@ -587,7 +597,7 @@ export interface IListener extends core.IResource { } ``` -`Listener` will consume `ListenerProps` +`Listener` will consome `ListenerProps` ```typescript /** @@ -598,7 +608,7 @@ export interface ListenerProps { * * A default action that will be taken if no rules match. * @default 404 NOT Found */ - readonly defaultAction?: DefaultListenerAction | undefined; + readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; /** * protocol that the listener will listen on * @default HTTPS @@ -607,9 +617,8 @@ export interface ListenerProps { /** * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol * @default 80 or 443 depending on the Protocol - */ - readonly port?: number | undefined; + readonly port?: number | undefined /** * The Name of the service. * @default CloudFormation provided name. @@ -619,13 +628,18 @@ export interface ListenerProps { * The Id of the service that this listener is associated with. */ readonly service: IService; - /** - * rules for the listener - */ - readonly rules?: RuleProp[] | undefined; } ``` +`Listener` will implement methods + +```typescript + /** + * add a rule to the listener, which will implement AWS::VpcLattice::Rule + * @param props AddRuleProps + */ + public addListenerRule(props: AddRuleProps): void { } +``` ### TargetGroup @@ -635,7 +649,6 @@ A VPC Lattice target group is a collection of targets, or compute resources, tha `TargetGroup` extends core.Resource and implements ITargetGroup - ```typescript /** Create a vpc lattice TargetGroup. @@ -672,17 +685,48 @@ export interface TargetGroupProps { ``` --- -## Classes - - -### Targets -Lattice Targets will be created in `aws-vpclattice-targets` a seperate module. They will implment `ITarget` +## Classes Detail +### Target `Target` is an abstract class with static function to return propertys for use in a `TargetGroup` Targets can be lambda, ipAddress, ec2instances, or applicaiton loadbalancers. +```typescript +/** + * Targets for target Groups + */ +export abstract class Target { + + /** + * Lambda Target + * @param lambda + */ + public static lambda(lambda: aws_lambda.Function[]): Target { }; + + /** + * IpAddress as Targets + * @param ipAddress + * @param config + */ + public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { }; + + /** + * EC2 Instances as Targets + * @param ec2instance + * @param config + */ + public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { }; + + /** + * Application Load Balancer as Targets + * @param alb + * @param config + */ + public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { } + +``` ### LoggingDestination @@ -716,7 +760,7 @@ export abstract class LoggingDestination { ### HeatlhCheck -HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. +HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. ```typescript /** @@ -892,48 +936,59 @@ export abstract class HealthCheck { }; ``` + --- -## Enums -The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. + +## Enums Detail + +The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. ### AuthType -Lattice Services can use IAM for Authentication or NONE. + +Lattice Services can use IAM for Authentication or NONE. ### FixedResponse + Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need expanding ### HTTPMethods + Valid HTTP Methods, these are used for constructing Rules. ### IpAddressType + IPv4 and IPv6, used for creating rules ### MatchOperators + Contains, Exact and Prefix used for creating rules ### PathMatchType + Exact Prefix, used for creating path matches in rules. ### Protocol -HTTP or HTTPS - used for creating rules. -### PRotocolVersion -HTTP1, HTTP2 or GRPC - used for creating rules. +HTTP or HTTPS - used for creating rules. + +### ProtocolVersion + +HTTP1, HTTP2 or GRPC - used for creating rules. ### RuleAccessMode + Used for creating Authenticaiton Policy Access Modes. ### ServiceNetworkAccessMode + Used for creating Authenticaiton Policy Access Modes. (Note a different set of options from RuleAccessMode) ### TargetTypes -LAMBDA, IP, INSTANCE, ALB. Used for creating targets. +LAMBDA, IP, INSTANCE, ALB. Used for creating targets. --- - - ## FAQ **What are we launching today?** @@ -955,19 +1010,22 @@ You can check common Amazon VPC Lattice Reference Architectures to understand th - Provides separation of concerns with a common interface for user personas **Why are we doing this?** + - To provide a CDK native interface for AWS VPC Lattice - Provide a way to deploy AWS VPC Lattice deterministically **Is this a breaking change** No. -**What are the drawbacks of this solution** +What are the drawbacks of this solution? + - It is an opinionated pattern, however there are escapes to help customisation where needed. - It is a new AWS Service and its common usecases and features may change and evolve --- + ### Acceptance -Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): `[ ] Signed-off by API Bar Raiser @TheRealAmazonKendra` From 521352e678d35d95e03ba8980ffc451d553fb6cc Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 14:24:34 +1200 Subject: [PATCH 17/31] Create 0502-vpclattice.md Added RFC for VPC Lattice Issue 502 --- text/0502-vpclattice.md | 1026 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1026 insertions(+) create mode 100644 text/0502-vpclattice.md diff --git a/text/0502-vpclattice.md b/text/0502-vpclattice.md new file mode 100644 index 000000000..b60e340ca --- /dev/null +++ b/text/0502-vpclattice.md @@ -0,0 +1,1026 @@ +# vpcLattice L2 Construct + +- [Project Information](#project-information) +- [Example Impleentation](#example-implementation) +- [API Design](#proposed-api-design-for-vpclattice) +- [FAQ](#faq) +- [Acceptance](#acceptance) + + +--- +## Project Information + +**Status** (DRAFT) + +**Original Author(s):** @mrpackethead, , @taylaand, @nbaillie + +**Tracking Issue:** #502 + +**API Bar Raiser:** @TheRealAmazonKendra + +**Public Issues ( aws-cdk)** +* (vpclattice): L2 for Amazon VPC Lattice #25452 + + +**Prototype Code** +- https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha +- https://github.com/raindancers/vpclattice-prealpha-demo + +** Constructs.dev ** +- https://constructs.dev/packages/aws-vpclattice-prealpha + + +**VpcLattice** + +Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. + +The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. + +--- + +## Example Implementation + +- A Service is created +- A Listener is added to the serviceand associated with a ServiceNetwork +- A Rule is assocated with the listener which uses a Lambda function as a target +- A Service Network is created +- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. +A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. +Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests.. Lambda1 will be in VPC1, and Lambda2 in VPC2 + + + +```typescript +import * as core from 'aws-cdk-lib'; + +import { + aws_iam as iam, +} + from 'aws-cdk-lib'; +import { Construct } from 'constructs'; + +import { SupportResources } from './support'; +import { + ServiceNetwork, + Service, + TargetGroup, + Target, +} + from '../../lib/index'; + +export class LatticeTestStack extends core.Stack { + + constructor(scope: Construct, id: string, props?: core.StackProps) { + super(scope, id, props); + + const support = new SupportResources(this, 'supportresources'); + + // Create a Lattice Service + // this will default to using IAM Authentication + const myLatticeService = new Service(this, 'myLatticeService', {}); + // add a listener to the service, using the defaults + // - HTTPS + // - Port 443 + // - default action of providing 404 NOT Found, + // - cloudformation name + const myListener = new vpclattice.Listener(this, 'Listener', { + service: myLatticeService, + }) + + + // add a listenerRule that will use the helloworld lambda as a Target + mylistener.addListenerRule({ + name: 'helloworld', + priority: 10, + action: [ + { + targetGroup: new vpclattice.TargetGroup(this, 'hellolambdatargets', { + name: 'hellowworld', + target: vpclattice.Target.lambda([ + support.helloWorld, + ]), + }), + }, + ], + + httpMatch: { + pathMatches: { path: '/hello' }, + }, + // we will only allow access to this service from the ec2 instance + accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED + }); + + //add a listenerRule that will use the goodbyeworld lambda as a Target + mylistener.addListenerRule({ + name: 'goodbyeworld', + priority: 20, + action: [ + { + targetGroup: new vpclattice.TargetGroup(this, 'goodbyelambdatargets', { + name: 'goodbyeworld', + target: vpclattice.Target.lambda([ + support.goodbyeWorld, + ]), + }), + }, + ], + + httpMatch: { + pathMatches: { path: '/goodbye' }, + }, + // we will only allow access to this service from the ec2 instance + allowedPrincipals: [support.ec2instance.role], + accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, + }); + + + myLatticeService.applyAuthPolicy(); + + /** + * Create a ServiceNetwork. + * OPINIONATED DEFAULT: The default behavior is to create a + * service network that requries an IAM policy, and authenticated access + * ( requestors must send signed requests ) + */ + + const serviceNetwork = new ServiceNetwork(this, 'LatticeServiceNetwork', { + services: [myLatticeService], + vpcs: [ + support.vpc1, + ], + }); + + serviceNetwork.applyAuthPolicyToServiceNetwork(); + } +} +``` +--- + +## Proposed API Design for vpclattice: +[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) + + +### Constructs + +- ✓ [AssociateVpc](#associatevpc) +- ✓ [ServiceNetwork](#servicenetwork) +- ✓ [ServiceNetworkAssociation] (#servicenetworkassociation) +- ✓ [Service](#serviceService) +- ✓ [ServiceAssociation] +- ✓ [Listener](#listener) +- ✓ [TargetGroup](#targetgroup) + +### Classes + - [HealthCheck] + - [LoggingDestination] + - [Target] + +### Enums + - [AuthType] + - [FixedResponse] + - [HTTPMethods] + - [IpAddressType] + - [MatchOperator] + - [PathMatchType] + - [Protocol] + - [ProtocolVersion] + - [RuleAccessMode] + - [ServiceNetworkAccessMode] + - [TargetType] + + +--- +## Constructs + +### AssociateVpc + +Creates a CloudFormation `AWS::VpcLattice::ServiceNetworkVpcAssociation` + +This construct associates a VPC, with a service network. It creates an endpoint interface in a VPC to enable the resources in the vpc +to be clients of the service network. + +The construct extends core.Resource, and will consume AssociateVpcProps. + +```typescript +/** + * Props to Associate a VPC with a Service Network + */ +export interface AssociateVpcProps { + /** + * security groups for the lattice endpoint + * @default a security group that will permit inbound 443 + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** + * The VPC to associate with + */ + readonly vpc: ec2.IVpc; + /** + * Service Network Identifier + */ + readonly serviceNetworkId: string; +} +``` + + + +### ServiceNetwork + +Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` + +A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. + +![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) + + +The construct will extend ServiceNetworkBase and implement IServiceNetwork. + +```typescript +/** + * Create a vpc lattice service network. + * Implemented by `ServiceNetwork`. + */ +export interface IServiceNetwork extends core.IResource { + + /** + * The Amazon Resource Name (ARN) of the service network. + */ + readonly serviceNetworkArn: string; + /** + * The Id of the Service Network + */ + readonly serviceNetworkId: string; + /** + * Is this an imported serviceNetwork + */ + readonly imported: boolean; + /** + * Add Lattice Service + */ + addService(props: AddServiceProps): void; + /** + * Associate a VPC with the Service Network + */ + associateVPC(props: AssociateVPCProps): void; +} +``` + +The Construct will consume ServiceNetworkProps. + + +```typescript +export interface ServiceNetworkProps { + + /** The name of the Service Network. If not provided Cloudformation will provide + * a name + * @default cloudformation generated name + */ + readonly name?: string; + + /** + * The type of authentication to use with the Service Network. The only method avaialble is + * AWS_IAM, however in anticipation, it is expected that other types will be added. + * @default 'AWS_IAM' + */ + readonly authType?: AuthType | undefined; + + /** + * Logging destinations + * @default: no logging + */ + readonly loggingDestinations?: LoggingDestination[]; + + /** + * Lattice Services that are assocaited with this Service Network + * @default no services are associated with the service network + */ + readonly services?: IService[] | undefined; + + /** + * Vpcs that are associated with this Service Network + * @default no vpcs are associated + */ + readonly vpcs?: ec2.IVpc[] | undefined; + /** + * An access mode provides 'pre-canned' conditions for the policy + * @default no conditions + */ + readonly accessmode?: ServiceNetworkAccessMode | undefined; +} + +``` +`ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. + +```typescript +public static fromId(scope: constructs.Construct, id: string, props: ImportedServiceNetworkProps ): IServiceNetwork { + return new ImportedServiceNetwork(scope, id, props); +} + +public static fromName(scope: constructs.Construct, id: string, serviceNetworkName: string ): IServiceNetwork { + return new ImportedServiceNetwork(scope, id, { serviceNetworkName: serviceNetworkName }); + } +``` + +`ServiceNetwork` will implement methods for a variety of tasks; + + +```typescript +// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application +addStatementToAuthPolicy(statement: iam.PolicyStatement) +``` + +```typescript +// applies the AuthPolicy that has been created, to the serviceNetwork. +applyAuthPolicyToServiceNetwork() +``` + +```typescript +// creates and associates a logging subscription to provide visisiblity for the lattice service +addloggingDestination(props: AddloggingDestinationProps) +``` + +```typescript +// share the service network using RAM + public share(props: ShareServiceNetworkProps) +``` + +### ServiceNetworkAssociation + +Creates a Cloudformation `AWS::VpcLattice::ServiceNetworkServiceAssociation` +Associates a service with a service network. +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps +Consider using `.associateWithServiceNetwork` method on `Service` in preference. + + +```typescript +export interface ServiceNetworkAssociationProps { + /** + * lattice Service + */ + readonly serviceNetwork: IServiceNetwork; + /** + * Lattice ServiceId + */ + readonly serviceId: string; +} +``` + + + + +### Service + +Creates a cloudformation `AWS::VpcLattice::Service` + +A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. + + +![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) + + +`Service` extends `core.Resource` and implments `IService` + +```typescript +export interface IService extends core.IResource { + /** + * The Id of the Service + */ + readonly serviceId: string; + /** + * The Arn of the Service + */ + readonly serviceArn: string; + /** + * the discovered OrgId + */ + readonly orgId: string | undefined; + /** + * Imported + */ + readonly imported: boolean; + /** + * The authType of the service. + */ + authType: AuthType | undefined; + /** + * A certificate that may be used by the service + */ + certificate: certificatemanager.Certificate | undefined; + /** + * A custom Domain used by the service + */ + customDomain: string | undefined; + /** + * A DNS Entry for the service + */ + dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; + /** + * A name for the service + */ + name: string | undefined; + /** + * The auth Policy for the service. + */ + authPolicy: iam.PolicyDocument; + + /** + * associate the service with a servicenetwork. + */ + associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; +} + +``` + +`Service` will take `ServiceProps` as props +```typescript +/** + * Properties for a Lattice Service + */ +/** + * Properties for a Lattice Service + */ +export interface ServiceProps { + + /** + * Name for the service + * @default cloudformation will provide a name + */ + readonly name?: string | undefined; + + /** + * The authType of the Service + * @default 'AWS_IAM' + */ + readonly authType?: string | undefined; + + /** + * Listeners that will be attached to the service + * @default no listeners + */ + readonly listeners?: IListener[] | undefined; + + /** + * A certificate that may be used by the service + * @default no custom certificate is used + */ + readonly certificate?: certificatemanager.Certificate | undefined; + /** + * A customDomain used by the service + * @default no customdomain is used + */ + readonly customDomain?: string | undefined; + /** + * A custom hosname + * @default no hostname is used + */ + readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; + + /** + * Share Service + *@default no sharing of the service + */ + readonly shares?: ShareServiceProps[] | undefined; + /** + * ServiceNetwork to associate with. + * @default will not assocaite with any serviceNetwork. + */ + readonly serviceNetwork?: IServiceNetwork | undefined; +} +``` + +`Service` will implement a static for importing the service. +```typescript +public static fromId(scope: constructs.Construct, id: string, serviceId: string): IService { + return new ImportedService(scope, id, serviceId); + } +``` +Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. + + + +`Service` will implement methods for the following +```typescript +/** + * .grantAccess on a lattice service, will permit the principals to + * access all resoruces of the service. Consider using finer permissions + * at the rule level. + * + * @param principals + */ +public grantAccess(principals: iam.IPrincipal[]) { } +``` + +```typescript + /** + * apply an authpolicy to the service + */ + public applyAuthPolicy(): iam.PolicyDocument { } +``` + +```typescript + /** + * Add a PolicyStatement to the auth policy + */ + public addPolicyStatement(statement: iam.PolicyStatement): void { } +``` + +```typescript + /** + * Share the service to other accounts via RAM + */ + public shareToAccounts(props: ShareServiceProps): void { } +``` + +```typescript +/** + * Associate with a Service Network + */ + public associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void { } +``` + + +### ServiceAssociation + +Associates a ServiceNetwork to a Service + +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. + +```typescript +/** + * Props for Service Assocaition + */ +export interface ServiceNetworkAssociationProps { + /** + * lattice Service + */ + readonly serviceNetwork: IServiceNetwork; + /** + * Lattice ServiceId + */ + readonly serviceId: string; +} +``` + + + + + + + +### Listener + +Creates a cloudformation `AWS::VpcLattice::Listener` + +A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the service routes requests to its registered targets. + +It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used on a service + + +`Listener` extends `core.resource` implements `IListener` + + +``` typescript +/** + * Create a vpcLattice Listener. + * Implemented by `Listener`. + */ +export interface IListener extends core.IResource { + /** + * The Amazon Resource Name (ARN) of the service. + */ + readonly listenerArn: string; + /** + * The Id of the Service Network + */ + readonly listenerId: string; + + /** + * Add A Listener Rule to the Listener + */ + addListenerRule(props: AddRuleProps): void; + +} +``` + +`Listener` will consome `ListenerProps` + +```typescript +/** + * Propertys to Create a Lattice Listener + */ +export interface ListenerProps { + /** + * * A default action that will be taken if no rules match. + * @default 404 NOT Found + */ + readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; + /** + * protocol that the listener will listen on + * @default HTTPS + */ + readonly protocol?: Protocol | undefined; + /** + * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol + * @default 80 or 443 depending on the Protocol + */ + readonly port?: number | undefined + /** + * The Name of the service. + * @default CloudFormation provided name. + */ + readonly name?: string; + /** + * The Id of the service that this listener is associated with. + */ + readonly service: IService; +} +``` + +`Listener` will implement methods + +```typescript + /** + * add a rule to the listener, which will implement AWS::VpcLattice::Rule + * @param props AddRuleProps + */ + public addListenerRule(props: AddRuleProps): void { } +``` + + + +### TargetGroup + +Creates a cloudformation `AWS::VpcLattice::TargetGroup` + +A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers + +`TargetGroup` extends core.Resource and implements ITargetGroup + + +```typescript + + /** Create a vpc lattice TargetGroup. + * Implemented by `TargetGroup`. + */ +export interface ITargetGroup extends core.IResource { + /** + * The id of the target group + */ + readonly targetGroupId: string + /** + * The Arn of the target group + */ + readonly targetGroupArn: string; +} +``` + +`TargetGroup` will take `TargetGroupProps` + +```typescript +/** + * Properties for a Target Group, Only supply one of instancetargets, lambdaTargets, albTargets, ipTargets + */ +export interface TargetGroupProps { + /** + * The name of the target group + */ + readonly name: string, + /** + * Targets + */ + readonly target: Target, +} +``` + +--- +## Classes + + + +### Target + +`Target` is an abstract class with static function to return propertys for use in a `TargetGroup` +Targets can be lambda, ipAddress, ec2instances, or applicaiton loadbalancers. + +```typescript +/** + * Targets for target Groups + */ +export abstract class Target { + + /** + * Lambda Target + * @param lambda + */ + public static lambda(lambda: aws_lambda.Function[]): Target { }; + + /** + * IpAddress as Targets + * @param ipAddress + * @param config + */ + public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { }; + + /** + * EC2 Instances as Targets + * @param ec2instance + * @param config + */ + public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { }; + + /** + * Application Load Balancer as Targets + * @param alb + * @param config + */ + public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { } + +``` + +### LoggingDestination + +LoggingDestination is a abstract class to return properties for a LoggingSubscription + +```typescript +/** + * Logging options + */ +export abstract class LoggingDestination { + + /** + * Construct a logging destination for a S3 Bucket + * @param bucket an s3 bucket + */ + public static s3(bucket: s3.IBucket): LoggingDestination { } + /** + * Send to CLoudwatch + * @param logGroup + */ + public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination { } + + /** + * Stream to Kinesis + * @param stream + */ + public static kinesis(stream: kinesis.IStream): LoggingDestination { } + +} +``` + +### HeatlhCheck + +HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. + +```typescript +/** + * A Configuration of the TargetGroup Health Check. + */ +export interface TargetGroupHealthCheckProps { + /** + * Enable this Health Check + * @default true + */ + readonly enabled?: boolean | undefined; + /** + * Health Check Interval + * @default 30 seconds + */ + readonly healthCheckInterval?: core.Duration | undefined; + /** + * TimeOut Period + * @default 5 seconds + */ + readonly healthCheckTimeout?: core.Duration | undefined; + /** + * Number of Healthy Responses before Target is considered healthy + * @default 2 + */ + readonly healthyThresholdCount?: number | undefined; + /** + * Check based on Response from target + * @default 200 OK + */ + readonly matcher?: FixedResponse | undefined; + /** + * Path to use for Health Check + * @default '/' + */ + readonly path?: string | undefined; + /** + * Port to use for Health Check + * @default 443 + */ + readonly port?: number | undefined; + /** + * Protocol to use for Health Check + * @default HTTPS + */ + readonly protocol?: Protocol | undefined; + /** + * Protocol to use for Health Check + * @default HTTP2 + */ + readonly protocolVersion?: ProtocolVersion | undefined; + /** + * Number of unhealty events before Target is considered unhealthy + * @default 1 + */ + readonly unhealthyThresholdCount?: number | undefined; +} + +/** + * Create a Health Check for a target + */ +export abstract class HealthCheck { + + /** + * A Health Check configuration object for a target + * @param props + * @returns HealthCheck + */ + public static check(props: TargetGroupHealthCheckProps): HealthCheck { + + // validate the ranges for the health check + if (props.healthCheckInterval) { + if (props.healthCheckInterval.toSeconds() < 5 || props.healthCheckInterval.toSeconds() > 300) { + throw new Error('HealthCheckInterval must be between 5 and 300 seconds'); + } + }; + + if (props.healthCheckTimeout) { + if (props.healthCheckTimeout.toSeconds() < 1 || props.healthCheckTimeout.toSeconds() > 120) { + throw new Error('HealthCheckTimeout must be between 1 and 120seconds'); + } + }; + + if (props.healthyThresholdCount) { + if (props.healthyThresholdCount < 1 || props.healthyThresholdCount > 10) { + throw new Error('HealthyThresholdCount must be between 1 and 10'); + } + }; + + if (props.protocolVersion) { + if (props.protocolVersion === ProtocolVersion.GRPC) { + throw new Error('GRPC is not supported'); + } + }; + + if (props.unhealthyThresholdCount) { + if (props.unhealthyThresholdCount < 2 || props.unhealthyThresholdCount > 10) { + throw new Error('UnhealthyThresholdCount must be between 2 and 10'); + } + } + + var port: number; + if (props.port) { + port = props.port; + } else if ( props.protocol === Protocol.HTTP ) { + port = 80; + } else { + port = 443; + }; + + let matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined = undefined; + if (props.matcher) { + const codeAsString = props.matcher.toString(); + matcher = { httpCode: codeAsString }; + }; + + return { + enabled: props.enabled ?? true, + healthCheckInterval: props.healthCheckInterval ?? core.Duration.seconds(30), + healthCheckTimeout: props.healthCheckTimeout ?? core.Duration.seconds(5), + path: props.path ?? '/', + protocol: props.protocol ?? 'HTTPS', + port: port, + protocolVersion: props.protocolVersion ?? 'HTTP1', + unhealthyThresholdCount: props.unhealthyThresholdCount ?? 2, + healthyThresholdCount: props.healthyThresholdCount ?? 5, + matcher: matcher, + }; + }; + + /** + * health check is enabled. + */ + public abstract readonly enabled: boolean; + /** + * healthCheck Interval + */ + public abstract readonly healthCheckInterval: core.Duration; + /** + * HealthCheck Timeout + */ + public abstract readonly healthCheckTimeout: core.Duration; + /** + * Target Match reponse + */ + public abstract readonly matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined; + /** + * Path to check + */ + public abstract readonly path: string; + /** + * Port to check + */ + public abstract readonly port: number; + /** Protocol + * + */ + public abstract readonly protocol: string; + /** + * HTTP Protocol Version + */ + public abstract readonly protocolVersion: string; + /** + * Unhealthy Threshold Count + */ + public abstract readonly unhealthyThresholdCount: number; + /** + * Healthy Threshold Count + */ + public abstract readonly healthyThresholdCount: number; + + protected constructor() {}; + +}; +``` +--- +## Enums +The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. + +### AuthType +Lattice Services can use IAM for Authentication or NONE. + +### FixedResponse +Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need expanding + +### HTTPMethods +Valid HTTP Methods, these are used for constructing Rules. + +### IpAddressType +IPv4 and IPv6, used for creating rules + +### MatchOperators +Contains, Exact and Prefix used for creating rules + +### PathMatchType +Exact Prefix, used for creating path matches in rules. + +### Protocol +HTTP or HTTPS - used for creating rules. + +### PRotocolVersion +HTTP1, HTTP2 or GRPC - used for creating rules. + +### RuleAccessMode +Used for creating Authenticaiton Policy Access Modes. + +### ServiceNetworkAccessMode +Used for creating Authenticaiton Policy Access Modes. (Note a different set of options from RuleAccessMode) + +### TargetTypes +LAMBDA, IP, INSTANCE, ALB. Used for creating targets. + + +--- + + + +## FAQ + +**What are we launching today?** +Amazon VPC Lattice AWS CDK L2 Construct + +**Why should I use this construct?** +This CDK L2 Construct can be used to deploy resources from Amazon VPC Lattice. VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). + +This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). You have the freedom to create the combination of resources you need, so in multi-AWS Account environments you can make use of the module as many times as needed (different providers) to create your application network architecture. + +You can check common Amazon VPC Lattice Reference Architectures to understand the different use cases you can build with the AWS service. + +- It simplifies the deployment of common patterns for AWS VPC Lattice +- It has been tested and implemented as part of a number of wider architectures +- It is extensible to support other patterns as they emerge +- It simplifies AWS VPC Lattice adoption and administration +- Allows you to integrate infrastructure deployment with your application code +- Reduces time to deploy and test AWS VPC Lattice +- Provides separation of concerns with a common interface for user personas + +**Why are we doing this?** +- To provide a CDK native interface for AWS VPC Lattice +- Provide a way to deploy AWS VPC Lattice deterministically + +**Is this a breaking change** +No. + +**What are the drawbacks of this solution** +- It is an opinionated pattern, however there are escapes to help customisation where needed. +- It is a new AWS Service and its common usecases and features may change and evolve + +--- +### Acceptance +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): + + +`[ ] Signed-off by API Bar Raiser @TheRealAmazonKendra` From 5aad164d994da4a8e2c180a5a6ec8fc5c485f280 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 14:59:04 +1200 Subject: [PATCH 18/31] Updated Readme to include issue 502 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1fbddf89a..4b4ed0387 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ future state of the libraries and to discover projects for contribution. [460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing [474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)||👷 implementing [457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning +[502](https://https://github.com/aws/aws-cdk-rfcs/issues/507) | [L2 Constructs for VPCLattice]] | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review [507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved [510](https://github.com/aws/aws-cdk-rfcs/issues/510)|[DyanmoDB Global Table L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0510-dynamodb-global-table.md)|[@vinayak-kukreja](https://github.com/vinayak-kukreja)|👍 approved [8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review From b5da8847308a794c728d1e5f749745550455ce2b Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 14:59:36 +1200 Subject: [PATCH 19/31] Update README.md to fix extra bracket --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b4ed0387..619b1b3d9 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ future state of the libraries and to discover projects for contribution. [460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing [474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)||👷 implementing [457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning -[502](https://https://github.com/aws/aws-cdk-rfcs/issues/507) | [L2 Constructs for VPCLattice]] | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review +[502](https://https://github.com/aws/aws-cdk-rfcs/issues/507) | [L2 Constructs for VPCLattice] | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review [507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved [510](https://github.com/aws/aws-cdk-rfcs/issues/510)|[DyanmoDB Global Table L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0510-dynamodb-global-table.md)|[@vinayak-kukreja](https://github.com/vinayak-kukreja)|👍 approved [8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review From 71a2579d8258bd3adbfaff3cea579d630d753a4c Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 15:00:34 +1200 Subject: [PATCH 20/31] Update README.md Wrong Issue Number fixed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 619b1b3d9..e1e12872e 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ future state of the libraries and to discover projects for contribution. [460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing [474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)||👷 implementing [457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning -[502](https://https://github.com/aws/aws-cdk-rfcs/issues/507) | [L2 Constructs for VPCLattice] | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review +[502](https://https://github.com/aws/aws-cdk-rfcs/issues/502) | [L2 Constructs for VPCLattice] | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review [507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved [510](https://github.com/aws/aws-cdk-rfcs/issues/510)|[DyanmoDB Global Table L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0510-dynamodb-global-table.md)|[@vinayak-kukreja](https://github.com/vinayak-kukreja)|👍 approved [8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review From eefb79ebfca911ff2dac704d90440a248313b61f Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2023 15:03:08 +1200 Subject: [PATCH 21/31] Update README.md Fixed Link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e1e12872e..9f10676b7 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ future state of the libraries and to discover projects for contribution. [460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing [474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)||👷 implementing [457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning -[502](https://https://github.com/aws/aws-cdk-rfcs/issues/502) | [L2 Constructs for VPCLattice] | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review +[502](https://https://github.com/aws/aws-cdk-rfcs/issues/502) | [L2 Constructs for VPCLattice](https://github.com/aws/aws-cdk-rfcs/issues/502) | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review [507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved [510](https://github.com/aws/aws-cdk-rfcs/issues/510)|[DyanmoDB Global Table L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0510-dynamodb-global-table.md)|[@vinayak-kukreja](https://github.com/vinayak-kukreja)|👍 approved [8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review From bfbd9d040fea621d881c925274e583aca7c4f7a9 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 13 Jul 2023 17:26:47 +1200 Subject: [PATCH 22/31] Update 0502-vpclattice.md Removed applyAuth methods from Service and ServiceNetwork. Service and Service Networks will take the rules as propertys of the construct. --- text/0502-vpclattice.md | 121 +++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 71 deletions(-) diff --git a/text/0502-vpclattice.md b/text/0502-vpclattice.md index b60e340ca..4e6805a75 100644 --- a/text/0502-vpclattice.md +++ b/text/0502-vpclattice.md @@ -78,18 +78,10 @@ export class LatticeTestStack extends core.Stack { // Create a Lattice Service // this will default to using IAM Authentication const myLatticeService = new Service(this, 'myLatticeService', {}); - // add a listener to the service, using the defaults - // - HTTPS - // - Port 443 - // - default action of providing 404 NOT Found, - // - cloudformation name - const myListener = new vpclattice.Listener(this, 'Listener', { - service: myLatticeService, - }) - + // add a listenerRule that will use the helloworld lambda as a Target - mylistener.addListenerRule({ + const helloworld: RuleProp = { name: 'helloworld', priority: 10, action: [ @@ -106,12 +98,11 @@ export class LatticeTestStack extends core.Stack { httpMatch: { pathMatches: { path: '/hello' }, }, - // we will only allow access to this service from the ec2 instance accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED - }); + }; //add a listenerRule that will use the goodbyeworld lambda as a Target - mylistener.addListenerRule({ + const goodbye: RuleProp = { name: 'goodbyeworld', priority: 20, action: [ @@ -131,10 +122,20 @@ export class LatticeTestStack extends core.Stack { // we will only allow access to this service from the ec2 instance allowedPrincipals: [support.ec2instance.role], accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, - }); + }; - - myLatticeService.applyAuthPolicy(); + // add a listener to the service, using the defaults + // - HTTPS + // - Port 443 + // - default action of providing 404 NOT Found, + // - cloudformation name + const myListener = new vpclattice.Listener(this, 'Listener', { + service: myLatticeService, + rules: [ + helloworld, + goodbyeworld, + ] + }) /** * Create a ServiceNetwork. @@ -149,11 +150,20 @@ export class LatticeTestStack extends core.Stack { support.vpc1, ], }); - - serviceNetwork.applyAuthPolicyToServiceNetwork(); } } ``` +--- +## Vpc Lattice Networking. + +When a vpc is associated with a vpclattice servicenetwork, the following occurs; + +- A service interface is placed in the vpc. Lattice uses link-local (169.254.x.x) address's for this. +- It associates a aws service domain (*.on.aws) with the vpc, which is how resources in the vpc are able to resolve the service interface. Generally you would then put a CNAME record at it. +- Optionally an array of securitygroups can be provided, which are applied on to the interface to filter what can connect + +https://d1.awsstatic.com/events/Summits/reinvent2022/NET215_NEW-LAUNCH!-Introducing-Amazon-VPC-Lattice-Simplifying-application-networking.pdf + --- ## Proposed API Design for vpclattice: @@ -278,8 +288,7 @@ export interface ServiceNetworkProps { readonly name?: string; /** - * The type of authentication to use with the Service Network. The only method avaialble is - * AWS_IAM, however in anticipation, it is expected that other types will be added. + * The type of authentication to use with the Service Network * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; @@ -302,12 +311,15 @@ export interface ServiceNetworkProps { */ readonly vpcs?: ec2.IVpc[] | undefined; /** - * An access mode provides 'pre-canned' conditions for the policy - * @default no conditions + * Allow external principals + * @default false */ readonly accessmode?: ServiceNetworkAccessMode | undefined; + /** + * Additional Optional Auth statements: + */ + readonly authStatements?: iam.PolicyStatement[] | undefined; } - ``` `ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. @@ -321,19 +333,9 @@ public static fromName(scope: constructs.Construct, id: string, serviceNetworkNa } ``` -`ServiceNetwork` will implement methods for a variety of tasks; +`ServiceNetwork` will implement public methods for a variety of tasks; -```typescript -// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application -addStatementToAuthPolicy(statement: iam.PolicyStatement) -``` - -```typescript -// applies the AuthPolicy that has been created, to the serviceNetwork. -applyAuthPolicyToServiceNetwork() -``` - ```typescript // creates and associates a logging subscription to provide visisiblity for the lattice service addloggingDestination(props: AddloggingDestinationProps) @@ -365,9 +367,6 @@ export interface ServiceNetworkAssociationProps { } ``` - - - ### Service Creates a cloudformation `AWS::VpcLattice::Service` @@ -401,7 +400,7 @@ export interface IService extends core.IResource { /** * The authType of the service. */ - authType: AuthType | undefined; + authType: string | undefined; /** * A certificate that may be used by the service */ @@ -410,10 +409,6 @@ export interface IService extends core.IResource { * A custom Domain used by the service */ customDomain: string | undefined; - /** - * A DNS Entry for the service - */ - dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** * A name for the service */ @@ -427,6 +422,10 @@ export interface IService extends core.IResource { * associate the service with a servicenetwork. */ associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; + /** + * apply an authpolicy to the servicenetwork + */ + applyAuthPolicy(): iam.PolicyDocument; } ``` @@ -473,7 +472,7 @@ export interface ServiceProps { * A custom hosname * @default no hostname is used */ - readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; + readonly hostedZone?: r53.IHostedZone | undefined; /** * Share Service @@ -510,20 +509,6 @@ Note: unlike ServiceNetwork there are minimal reason to implmenet a import by na public grantAccess(principals: iam.IPrincipal[]) { } ``` -```typescript - /** - * apply an authpolicy to the service - */ - public applyAuthPolicy(): iam.PolicyDocument { } -``` - -```typescript - /** - * Add a PolicyStatement to the auth policy - */ - public addPolicyStatement(statement: iam.PolicyStatement): void { } -``` - ```typescript /** * Share the service to other accounts via RAM @@ -602,7 +587,7 @@ export interface IListener extends core.IResource { } ``` -`Listener` will consome `ListenerProps` +`Listener` will consume `ListenerProps` ```typescript /** @@ -613,7 +598,7 @@ export interface ListenerProps { * * A default action that will be taken if no rules match. * @default 404 NOT Found */ - readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; + readonly defaultAction?: DefaultListenerAction | undefined; /** * protocol that the listener will listen on * @default HTTPS @@ -622,8 +607,9 @@ export interface ListenerProps { /** * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol * @default 80 or 443 depending on the Protocol + */ - readonly port?: number | undefined + readonly port?: number | undefined; /** * The Name of the service. * @default CloudFormation provided name. @@ -633,21 +619,14 @@ export interface ListenerProps { * The Id of the service that this listener is associated with. */ readonly service: IService; -} -``` - -`Listener` will implement methods - -```typescript - /** - * add a rule to the listener, which will implement AWS::VpcLattice::Rule - * @param props AddRuleProps + /** + * rules for the listener */ - public addListenerRule(props: AddRuleProps): void { } + readonly rules?: RuleProp[] | undefined; +} ``` - ### TargetGroup Creates a cloudformation `AWS::VpcLattice::TargetGroup` From 2a3db6563cc63cded49672bffd11015565f40df2 Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Mon, 24 Jul 2023 23:22:26 +0000 Subject: [PATCH 23/31] fixed outstanding linting issues in markup, removed public construct from AssociateVPC --- text/0502-vpclattice.md | 305 ++++++++++++++++++++-------------------- 1 file changed, 150 insertions(+), 155 deletions(-) diff --git a/text/0502-vpclattice.md b/text/0502-vpclattice.md index 4e6805a75..230965c41 100644 --- a/text/0502-vpclattice.md +++ b/text/0502-vpclattice.md @@ -6,49 +6,55 @@ - [FAQ](#faq) - [Acceptance](#acceptance) +--- ---- ## Project Information -**Status** (DRAFT) +### Status + +(DRAFT) + +### Original Author(s) -**Original Author(s):** @mrpackethead, , @taylaand, @nbaillie +@mrpackethead, , @taylaand, @nbaillie -**Tracking Issue:** #502 +### Tracking Issue -**API Bar Raiser:** @TheRealAmazonKendra +502 -**Public Issues ( aws-cdk)** -* (vpclattice): L2 for Amazon VPC Lattice #25452 +### API Bar Raiser +@TheRealAmazonKendra -**Prototype Code** -- https://github.com/raindancers/aws-cdk/tree/mrpackethead/aws-vpclattice-alpha/packages/%40aws-cdk/aws-vpclattice-alpha -- https://github.com/raindancers/vpclattice-prealpha-demo +## Public Issues -** Constructs.dev ** -- https://constructs.dev/packages/aws-vpclattice-prealpha +( aws-cdk)(vpclattice): L2 for Amazon VPC Lattice #25452 +### Prototype Code -**VpcLattice** +- +- +- + +--- + +## VpcLattice Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. -The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. - +The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. + --- ## Example Implementation -- A Service is created +- A Service is created - A Listener is added to the serviceand associated with a ServiceNetwork - A Rule is assocated with the listener which uses a Lambda function as a target - A Service Network is created -- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. -A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. -Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests.. Lambda1 will be in VPC1, and Lambda2 in VPC2 - - +- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. +- A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. +- Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests. Lambda1 will be in VPC1, and Lambda2 in VPC2 ```typescript import * as core from 'aws-cdk-lib'; @@ -78,10 +84,18 @@ export class LatticeTestStack extends core.Stack { // Create a Lattice Service // this will default to using IAM Authentication const myLatticeService = new Service(this, 'myLatticeService', {}); - + // add a listener to the service, using the defaults + // - HTTPS + // - Port 443 + // - default action of providing 404 NOT Found, + // - cloudformation name + const myListener = new vpclattice.Listener(this, 'Listener', { + service: myLatticeService, + }) + // add a listenerRule that will use the helloworld lambda as a Target - const helloworld: RuleProp = { + mylistener.addListenerRule({ name: 'helloworld', priority: 10, action: [ @@ -98,11 +112,12 @@ export class LatticeTestStack extends core.Stack { httpMatch: { pathMatches: { path: '/hello' }, }, + // we will only allow access to this service from the ec2 instance accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED - }; + }); //add a listenerRule that will use the goodbyeworld lambda as a Target - const goodbye: RuleProp = { + mylistener.addListenerRule({ name: 'goodbyeworld', priority: 20, action: [ @@ -122,20 +137,10 @@ export class LatticeTestStack extends core.Stack { // we will only allow access to this service from the ec2 instance allowedPrincipals: [support.ec2instance.role], accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, - }; + }); - // add a listener to the service, using the defaults - // - HTTPS - // - Port 443 - // - default action of providing 404 NOT Found, - // - cloudformation name - const myListener = new vpclattice.Listener(this, 'Listener', { - service: myLatticeService, - rules: [ - helloworld, - goodbyeworld, - ] - }) + + myLatticeService.applyAuthPolicy(); /** * Create a ServiceNetwork. @@ -150,89 +155,50 @@ export class LatticeTestStack extends core.Stack { support.vpc1, ], }); + + serviceNetwork.applyAuthPolicyToServiceNetwork(); } } ``` ---- -## Vpc Lattice Networking. - -When a vpc is associated with a vpclattice servicenetwork, the following occurs; - -- A service interface is placed in the vpc. Lattice uses link-local (169.254.x.x) address's for this. -- It associates a aws service domain (*.on.aws) with the vpc, which is how resources in the vpc are able to resolve the service interface. Generally you would then put a CNAME record at it. -- Optionally an array of securitygroups can be provided, which are applied on to the interface to filter what can connect - -https://d1.awsstatic.com/events/Summits/reinvent2022/NET215_NEW-LAUNCH!-Introducing-Amazon-VPC-Lattice-Simplifying-application-networking.pdf --- -## Proposed API Design for vpclattice: -[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) +## Proposed API Design for vpclattice +[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) ### Constructs -- ✓ [AssociateVpc](#associatevpc) - ✓ [ServiceNetwork](#servicenetwork) - ✓ [ServiceNetworkAssociation] (#servicenetworkassociation) -- ✓ [Service](#serviceService) +- ✓ [Service](service) - ✓ [ServiceAssociation] - ✓ [Listener](#listener) - ✓ [TargetGroup](#targetgroup) ### Classes - - [HealthCheck] - - [LoggingDestination] - - [Target] + +- [HealthCheck] +- [LoggingDestination] +- [Target] ### Enums - - [AuthType] - - [FixedResponse] - - [HTTPMethods] - - [IpAddressType] - - [MatchOperator] - - [PathMatchType] - - [Protocol] - - [ProtocolVersion] - - [RuleAccessMode] - - [ServiceNetworkAccessMode] - - [TargetType] +- [AuthType] +- [FixedResponse] +- [HTTPMethods] +- [IpAddressType] +- [MatchOperator] +- [PathMatchType] +- [Protocol] +- [ProtocolVersion] +- [RuleAccessMode] +- [ServiceNetworkAccessMode] +- [TargetType] --- -## Constructs - -### AssociateVpc - -Creates a CloudFormation `AWS::VpcLattice::ServiceNetworkVpcAssociation` - -This construct associates a VPC, with a service network. It creates an endpoint interface in a VPC to enable the resources in the vpc -to be clients of the service network. - -The construct extends core.Resource, and will consume AssociateVpcProps. - -```typescript -/** - * Props to Associate a VPC with a Service Network - */ -export interface AssociateVpcProps { - /** - * security groups for the lattice endpoint - * @default a security group that will permit inbound 443 - */ - readonly securityGroups?: ec2.ISecurityGroup[]; - /** - * The VPC to associate with - */ - readonly vpc: ec2.IVpc; - /** - * Service Network Identifier - */ - readonly serviceNetworkId: string; -} -``` - +## Constructs Details ### ServiceNetwork @@ -242,7 +208,6 @@ A service network is a logical boundary for a collection of services. Services a ![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) - The construct will extend ServiceNetworkBase and implement IServiceNetwork. ```typescript @@ -277,7 +242,6 @@ export interface IServiceNetwork extends core.IResource { The Construct will consume ServiceNetworkProps. - ```typescript export interface ServiceNetworkProps { @@ -288,7 +252,8 @@ export interface ServiceNetworkProps { readonly name?: string; /** - * The type of authentication to use with the Service Network + * The type of authentication to use with the Service Network. The only method avaialble is + * AWS_IAM, however in anticipation, it is expected that other types will be added. * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; @@ -311,16 +276,14 @@ export interface ServiceNetworkProps { */ readonly vpcs?: ec2.IVpc[] | undefined; /** - * Allow external principals - * @default false + * An access mode provides 'pre-canned' conditions for the policy + * @default no conditions */ readonly accessmode?: ServiceNetworkAccessMode | undefined; - /** - * Additional Optional Auth statements: - */ - readonly authStatements?: iam.PolicyStatement[] | undefined; } + ``` + `ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. ```typescript @@ -333,8 +296,18 @@ public static fromName(scope: constructs.Construct, id: string, serviceNetworkNa } ``` -`ServiceNetwork` will implement public methods for a variety of tasks; +`ServiceNetwork` will implement methods for a variety of tasks; + +```typescript + +// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application +addStatementToAuthPolicy(statement: iam.PolicyStatement) +``` +```typescript +// applies the AuthPolicy that has been created, to the serviceNetwork. +applyAuthPolicyToServiceNetwork() +``` ```typescript // creates and associates a logging subscription to provide visisiblity for the lattice service @@ -353,8 +326,8 @@ Associates a service with a service network. `ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps Consider using `.associateWithServiceNetwork` method on `Service` in preference. - ```typescript + export interface ServiceNetworkAssociationProps { /** * lattice Service @@ -373,11 +346,9 @@ Creates a cloudformation `AWS::VpcLattice::Service` A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. - ![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) - -`Service` extends `core.Resource` and implments `IService` +`Service` extends `core.Resource` and implments `IService` ```typescript export interface IService extends core.IResource { @@ -400,7 +371,7 @@ export interface IService extends core.IResource { /** * The authType of the service. */ - authType: string | undefined; + authType: AuthType | undefined; /** * A certificate that may be used by the service */ @@ -409,6 +380,10 @@ export interface IService extends core.IResource { * A custom Domain used by the service */ customDomain: string | undefined; + /** + * A DNS Entry for the service + */ + dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** * A name for the service */ @@ -422,15 +397,12 @@ export interface IService extends core.IResource { * associate the service with a servicenetwork. */ associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; - /** - * apply an authpolicy to the servicenetwork - */ - applyAuthPolicy(): iam.PolicyDocument; } ``` `Service` will take `ServiceProps` as props + ```typescript /** * Properties for a Lattice Service @@ -472,7 +444,7 @@ export interface ServiceProps { * A custom hosname * @default no hostname is used */ - readonly hostedZone?: r53.IHostedZone | undefined; + readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** * Share Service @@ -488,17 +460,19 @@ export interface ServiceProps { ``` `Service` will implement a static for importing the service. + ```typescript public static fromId(scope: constructs.Construct, id: string, serviceId: string): IService { return new ImportedService(scope, id, serviceId); } -``` -Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. - +``` +Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. `Service` will implement methods for the following + ```typescript + /** * .grantAccess on a lattice service, will permit the principals to * access all resoruces of the service. Consider using finer permissions @@ -509,6 +483,20 @@ Note: unlike ServiceNetwork there are minimal reason to implmenet a import by na public grantAccess(principals: iam.IPrincipal[]) { } ``` +```typescript + /** + * apply an authpolicy to the service + */ + public applyAuthPolicy(): iam.PolicyDocument { } +``` + +```typescript + /** + * Add a PolicyStatement to the auth policy + */ + public addPolicyStatement(statement: iam.PolicyStatement): void { } +``` + ```typescript /** * Share the service to other accounts via RAM @@ -523,12 +511,11 @@ public grantAccess(principals: iam.IPrincipal[]) { } public associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void { } ``` - ### ServiceAssociation Associates a ServiceNetwork to a Service -`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. ```typescript /** @@ -546,12 +533,6 @@ export interface ServiceNetworkAssociationProps { } ``` - - - - - - ### Listener Creates a cloudformation `AWS::VpcLattice::Listener` @@ -560,9 +541,7 @@ A listener is a process that checks for connection requests, using the protocol It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used on a service - -`Listener` extends `core.resource` implements `IListener` - +`Listener` extends `core.resource` implements `IListener` ``` typescript /** @@ -587,7 +566,7 @@ export interface IListener extends core.IResource { } ``` -`Listener` will consume `ListenerProps` +`Listener` will consome `ListenerProps` ```typescript /** @@ -598,7 +577,7 @@ export interface ListenerProps { * * A default action that will be taken if no rules match. * @default 404 NOT Found */ - readonly defaultAction?: DefaultListenerAction | undefined; + readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; /** * protocol that the listener will listen on * @default HTTPS @@ -607,9 +586,8 @@ export interface ListenerProps { /** * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol * @default 80 or 443 depending on the Protocol - */ - readonly port?: number | undefined; + readonly port?: number | undefined /** * The Name of the service. * @default CloudFormation provided name. @@ -619,13 +597,18 @@ export interface ListenerProps { * The Id of the service that this listener is associated with. */ readonly service: IService; - /** - * rules for the listener - */ - readonly rules?: RuleProp[] | undefined; } ``` +`Listener` will implement methods + +```typescript + /** + * add a rule to the listener, which will implement AWS::VpcLattice::Rule + * @param props AddRuleProps + */ + public addListenerRule(props: AddRuleProps): void { } +``` ### TargetGroup @@ -635,7 +618,6 @@ A VPC Lattice target group is a collection of targets, or compute resources, tha `TargetGroup` extends core.Resource and implements ITargetGroup - ```typescript /** Create a vpc lattice TargetGroup. @@ -672,9 +654,8 @@ export interface TargetGroupProps { ``` --- -## Classes - +## Classes Detail ### Target @@ -748,7 +729,7 @@ export abstract class LoggingDestination { ### HeatlhCheck -HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. +HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. ```typescript /** @@ -924,48 +905,59 @@ export abstract class HealthCheck { }; ``` + --- -## Enums -The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. + +## Enums Detail + +The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. ### AuthType -Lattice Services can use IAM for Authentication or NONE. + +Lattice Services can use IAM for Authentication or NONE. ### FixedResponse + Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need expanding ### HTTPMethods + Valid HTTP Methods, these are used for constructing Rules. ### IpAddressType + IPv4 and IPv6, used for creating rules ### MatchOperators + Contains, Exact and Prefix used for creating rules ### PathMatchType + Exact Prefix, used for creating path matches in rules. ### Protocol -HTTP or HTTPS - used for creating rules. -### PRotocolVersion -HTTP1, HTTP2 or GRPC - used for creating rules. +HTTP or HTTPS - used for creating rules. + +### ProtocolVersion + +HTTP1, HTTP2 or GRPC - used for creating rules. ### RuleAccessMode + Used for creating Authenticaiton Policy Access Modes. ### ServiceNetworkAccessMode + Used for creating Authenticaiton Policy Access Modes. (Note a different set of options from RuleAccessMode) ### TargetTypes -LAMBDA, IP, INSTANCE, ALB. Used for creating targets. +LAMBDA, IP, INSTANCE, ALB. Used for creating targets. --- - - ## FAQ **What are we launching today?** @@ -987,19 +979,22 @@ You can check common Amazon VPC Lattice Reference Architectures to understand th - Provides separation of concerns with a common interface for user personas **Why are we doing this?** + - To provide a CDK native interface for AWS VPC Lattice - Provide a way to deploy AWS VPC Lattice deterministically **Is this a breaking change** No. -**What are the drawbacks of this solution** +What are the drawbacks of this solution? + - It is an opinionated pattern, however there are escapes to help customisation where needed. - It is a new AWS Service and its common usecases and features may change and evolve --- + ### Acceptance -Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): `[ ] Signed-off by API Bar Raiser @TheRealAmazonKendra` From 75bff86bb498c902951cb917b81951b1b8df5c85 Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Tue, 25 Jul 2023 23:43:54 +0000 Subject: [PATCH 24/31] updated 0502_aws-vpclattice.md --- text/0502_aws-vpclattice.md | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index bb81853ca..230965c41 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -169,7 +169,6 @@ export class LatticeTestStack extends core.Stack { ### Constructs -- ✓ [AssociateVpc](#associatevpc) - ✓ [ServiceNetwork](#servicenetwork) - ✓ [ServiceNetworkAssociation] (#servicenetworkassociation) - ✓ [Service](service) @@ -201,36 +200,6 @@ export class LatticeTestStack extends core.Stack { ## Constructs Details -### AssociateVpc - -Creates a CloudFormation `AWS::VpcLattice::ServiceNetworkVpcAssociation` - -This construct associates a VPC, with a service network. It creates an endpoint interface in a VPC to enable the resources in the vpc -to be clients of the service network. - -The construct extends core.Resource, and will consume AssociateVpcProps. - -```typescript -/** - * Props to Associate a VPC with a Service Network - */ -export interface AssociateVpcProps { - /** - * security groups for the lattice endpoint - * @default a security group that will permit inbound 443 - */ - readonly securityGroups?: ec2.ISecurityGroup[]; - /** - * The VPC to associate with - */ - readonly vpc: ec2.IVpc; - /** - * Service Network Identifier - */ - readonly serviceNetworkId: string; -} -``` - ### ServiceNetwork Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` From 21645f59d4792fad7367db4186d858e8ac224271 Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Mon, 31 Jul 2023 21:19:14 +0000 Subject: [PATCH 25/31] deplicated file --- text/0502_aws-vpclattice.md | 1000 ----------------------------------- 1 file changed, 1000 deletions(-) delete mode 100644 text/0502_aws-vpclattice.md diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md deleted file mode 100644 index 230965c41..000000000 --- a/text/0502_aws-vpclattice.md +++ /dev/null @@ -1,1000 +0,0 @@ -# vpcLattice L2 Construct - -- [Project Information](#project-information) -- [Example Impleentation](#example-implementation) -- [API Design](#proposed-api-design-for-vpclattice) -- [FAQ](#faq) -- [Acceptance](#acceptance) - ---- - -## Project Information - -### Status - -(DRAFT) - -### Original Author(s) - -@mrpackethead, , @taylaand, @nbaillie - -### Tracking Issue - -502 - -### API Bar Raiser - -@TheRealAmazonKendra - -## Public Issues - -( aws-cdk)(vpclattice): L2 for Amazon VPC Lattice #25452 - -### Prototype Code - -- -- -- - ---- - -## VpcLattice - -Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. - -The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. - ---- - -## Example Implementation - -- A Service is created -- A Listener is added to the serviceand associated with a ServiceNetwork -- A Rule is assocated with the listener which uses a Lambda function as a target -- A Service Network is created -- The Service is associated with the ServiceNetwork, and two vpcs are attached to it. -- A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. -- Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests. Lambda1 will be in VPC1, and Lambda2 in VPC2 - -```typescript -import * as core from 'aws-cdk-lib'; - -import { - aws_iam as iam, -} - from 'aws-cdk-lib'; -import { Construct } from 'constructs'; - -import { SupportResources } from './support'; -import { - ServiceNetwork, - Service, - TargetGroup, - Target, -} - from '../../lib/index'; - -export class LatticeTestStack extends core.Stack { - - constructor(scope: Construct, id: string, props?: core.StackProps) { - super(scope, id, props); - - const support = new SupportResources(this, 'supportresources'); - - // Create a Lattice Service - // this will default to using IAM Authentication - const myLatticeService = new Service(this, 'myLatticeService', {}); - // add a listener to the service, using the defaults - // - HTTPS - // - Port 443 - // - default action of providing 404 NOT Found, - // - cloudformation name - const myListener = new vpclattice.Listener(this, 'Listener', { - service: myLatticeService, - }) - - - // add a listenerRule that will use the helloworld lambda as a Target - mylistener.addListenerRule({ - name: 'helloworld', - priority: 10, - action: [ - { - targetGroup: new vpclattice.TargetGroup(this, 'hellolambdatargets', { - name: 'hellowworld', - target: vpclattice.Target.lambda([ - support.helloWorld, - ]), - }), - }, - ], - - httpMatch: { - pathMatches: { path: '/hello' }, - }, - // we will only allow access to this service from the ec2 instance - accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED - }); - - //add a listenerRule that will use the goodbyeworld lambda as a Target - mylistener.addListenerRule({ - name: 'goodbyeworld', - priority: 20, - action: [ - { - targetGroup: new vpclattice.TargetGroup(this, 'goodbyelambdatargets', { - name: 'goodbyeworld', - target: vpclattice.Target.lambda([ - support.goodbyeWorld, - ]), - }), - }, - ], - - httpMatch: { - pathMatches: { path: '/goodbye' }, - }, - // we will only allow access to this service from the ec2 instance - allowedPrincipals: [support.ec2instance.role], - accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, - }); - - - myLatticeService.applyAuthPolicy(); - - /** - * Create a ServiceNetwork. - * OPINIONATED DEFAULT: The default behavior is to create a - * service network that requries an IAM policy, and authenticated access - * ( requestors must send signed requests ) - */ - - const serviceNetwork = new ServiceNetwork(this, 'LatticeServiceNetwork', { - services: [myLatticeService], - vpcs: [ - support.vpc1, - ], - }); - - serviceNetwork.applyAuthPolicyToServiceNetwork(); - } -} -``` - ---- - -## Proposed API Design for vpclattice - -[(The Api is additionally documented on Constructs.dev here)](https://constructs.dev/packages/aws-vpclattice-prealpha/v/0.4.11/api/AuthType?lang=typescript) - -### Constructs - -- ✓ [ServiceNetwork](#servicenetwork) -- ✓ [ServiceNetworkAssociation] (#servicenetworkassociation) -- ✓ [Service](service) -- ✓ [ServiceAssociation] -- ✓ [Listener](#listener) -- ✓ [TargetGroup](#targetgroup) - -### Classes - -- [HealthCheck] -- [LoggingDestination] -- [Target] - -### Enums - -- [AuthType] -- [FixedResponse] -- [HTTPMethods] -- [IpAddressType] -- [MatchOperator] -- [PathMatchType] -- [Protocol] -- [ProtocolVersion] -- [RuleAccessMode] -- [ServiceNetworkAccessMode] -- [TargetType] - ---- - -## Constructs Details - -### ServiceNetwork - -Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` - -A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. - -![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) - -The construct will extend ServiceNetworkBase and implement IServiceNetwork. - -```typescript -/** - * Create a vpc lattice service network. - * Implemented by `ServiceNetwork`. - */ -export interface IServiceNetwork extends core.IResource { - - /** - * The Amazon Resource Name (ARN) of the service network. - */ - readonly serviceNetworkArn: string; - /** - * The Id of the Service Network - */ - readonly serviceNetworkId: string; - /** - * Is this an imported serviceNetwork - */ - readonly imported: boolean; - /** - * Add Lattice Service - */ - addService(props: AddServiceProps): void; - /** - * Associate a VPC with the Service Network - */ - associateVPC(props: AssociateVPCProps): void; -} -``` - -The Construct will consume ServiceNetworkProps. - -```typescript -export interface ServiceNetworkProps { - - /** The name of the Service Network. If not provided Cloudformation will provide - * a name - * @default cloudformation generated name - */ - readonly name?: string; - - /** - * The type of authentication to use with the Service Network. The only method avaialble is - * AWS_IAM, however in anticipation, it is expected that other types will be added. - * @default 'AWS_IAM' - */ - readonly authType?: AuthType | undefined; - - /** - * Logging destinations - * @default: no logging - */ - readonly loggingDestinations?: LoggingDestination[]; - - /** - * Lattice Services that are assocaited with this Service Network - * @default no services are associated with the service network - */ - readonly services?: IService[] | undefined; - - /** - * Vpcs that are associated with this Service Network - * @default no vpcs are associated - */ - readonly vpcs?: ec2.IVpc[] | undefined; - /** - * An access mode provides 'pre-canned' conditions for the policy - * @default no conditions - */ - readonly accessmode?: ServiceNetworkAccessMode | undefined; -} - -``` - -`ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. - -```typescript -public static fromId(scope: constructs.Construct, id: string, props: ImportedServiceNetworkProps ): IServiceNetwork { - return new ImportedServiceNetwork(scope, id, props); -} - -public static fromName(scope: constructs.Construct, id: string, serviceNetworkName: string ): IServiceNetwork { - return new ImportedServiceNetwork(scope, id, { serviceNetworkName: serviceNetworkName }); - } -``` - -`ServiceNetwork` will implement methods for a variety of tasks; - -```typescript - -// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application -addStatementToAuthPolicy(statement: iam.PolicyStatement) -``` - -```typescript -// applies the AuthPolicy that has been created, to the serviceNetwork. -applyAuthPolicyToServiceNetwork() -``` - -```typescript -// creates and associates a logging subscription to provide visisiblity for the lattice service -addloggingDestination(props: AddloggingDestinationProps) -``` - -```typescript -// share the service network using RAM - public share(props: ShareServiceNetworkProps) -``` - -### ServiceNetworkAssociation - -Creates a Cloudformation `AWS::VpcLattice::ServiceNetworkServiceAssociation` -Associates a service with a service network. -`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps -Consider using `.associateWithServiceNetwork` method on `Service` in preference. - -```typescript - -export interface ServiceNetworkAssociationProps { - /** - * lattice Service - */ - readonly serviceNetwork: IServiceNetwork; - /** - * Lattice ServiceId - */ - readonly serviceId: string; -} -``` - -### Service - -Creates a cloudformation `AWS::VpcLattice::Service` - -A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. - -![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) - -`Service` extends `core.Resource` and implments `IService` - -```typescript -export interface IService extends core.IResource { - /** - * The Id of the Service - */ - readonly serviceId: string; - /** - * The Arn of the Service - */ - readonly serviceArn: string; - /** - * the discovered OrgId - */ - readonly orgId: string | undefined; - /** - * Imported - */ - readonly imported: boolean; - /** - * The authType of the service. - */ - authType: AuthType | undefined; - /** - * A certificate that may be used by the service - */ - certificate: certificatemanager.Certificate | undefined; - /** - * A custom Domain used by the service - */ - customDomain: string | undefined; - /** - * A DNS Entry for the service - */ - dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; - /** - * A name for the service - */ - name: string | undefined; - /** - * The auth Policy for the service. - */ - authPolicy: iam.PolicyDocument; - - /** - * associate the service with a servicenetwork. - */ - associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; -} - -``` - -`Service` will take `ServiceProps` as props - -```typescript -/** - * Properties for a Lattice Service - */ -/** - * Properties for a Lattice Service - */ -export interface ServiceProps { - - /** - * Name for the service - * @default cloudformation will provide a name - */ - readonly name?: string | undefined; - - /** - * The authType of the Service - * @default 'AWS_IAM' - */ - readonly authType?: string | undefined; - - /** - * Listeners that will be attached to the service - * @default no listeners - */ - readonly listeners?: IListener[] | undefined; - - /** - * A certificate that may be used by the service - * @default no custom certificate is used - */ - readonly certificate?: certificatemanager.Certificate | undefined; - /** - * A customDomain used by the service - * @default no customdomain is used - */ - readonly customDomain?: string | undefined; - /** - * A custom hosname - * @default no hostname is used - */ - readonly dnsEntry?: aws_vpclattice.CfnService.DnsEntryProperty | undefined; - - /** - * Share Service - *@default no sharing of the service - */ - readonly shares?: ShareServiceProps[] | undefined; - /** - * ServiceNetwork to associate with. - * @default will not assocaite with any serviceNetwork. - */ - readonly serviceNetwork?: IServiceNetwork | undefined; -} -``` - -`Service` will implement a static for importing the service. - -```typescript -public static fromId(scope: constructs.Construct, id: string, serviceId: string): IService { - return new ImportedService(scope, id, serviceId); - } -``` - -Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. - -`Service` will implement methods for the following - -```typescript - -/** - * .grantAccess on a lattice service, will permit the principals to - * access all resoruces of the service. Consider using finer permissions - * at the rule level. - * - * @param principals - */ -public grantAccess(principals: iam.IPrincipal[]) { } -``` - -```typescript - /** - * apply an authpolicy to the service - */ - public applyAuthPolicy(): iam.PolicyDocument { } -``` - -```typescript - /** - * Add a PolicyStatement to the auth policy - */ - public addPolicyStatement(statement: iam.PolicyStatement): void { } -``` - -```typescript - /** - * Share the service to other accounts via RAM - */ - public shareToAccounts(props: ShareServiceProps): void { } -``` - -```typescript -/** - * Associate with a Service Network - */ - public associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void { } -``` - -### ServiceAssociation - -Associates a ServiceNetwork to a Service - -`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. - -```typescript -/** - * Props for Service Assocaition - */ -export interface ServiceNetworkAssociationProps { - /** - * lattice Service - */ - readonly serviceNetwork: IServiceNetwork; - /** - * Lattice ServiceId - */ - readonly serviceId: string; -} -``` - -### Listener - -Creates a cloudformation `AWS::VpcLattice::Listener` - -A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the service routes requests to its registered targets. - -It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used on a service - -`Listener` extends `core.resource` implements `IListener` - -``` typescript -/** - * Create a vpcLattice Listener. - * Implemented by `Listener`. - */ -export interface IListener extends core.IResource { - /** - * The Amazon Resource Name (ARN) of the service. - */ - readonly listenerArn: string; - /** - * The Id of the Service Network - */ - readonly listenerId: string; - - /** - * Add A Listener Rule to the Listener - */ - addListenerRule(props: AddRuleProps): void; - -} -``` - -`Listener` will consome `ListenerProps` - -```typescript -/** - * Propertys to Create a Lattice Listener - */ -export interface ListenerProps { - /** - * * A default action that will be taken if no rules match. - * @default 404 NOT Found - */ - readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; - /** - * protocol that the listener will listen on - * @default HTTPS - */ - readonly protocol?: Protocol | undefined; - /** - * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol - * @default 80 or 443 depending on the Protocol - */ - readonly port?: number | undefined - /** - * The Name of the service. - * @default CloudFormation provided name. - */ - readonly name?: string; - /** - * The Id of the service that this listener is associated with. - */ - readonly service: IService; -} -``` - -`Listener` will implement methods - -```typescript - /** - * add a rule to the listener, which will implement AWS::VpcLattice::Rule - * @param props AddRuleProps - */ - public addListenerRule(props: AddRuleProps): void { } -``` - -### TargetGroup - -Creates a cloudformation `AWS::VpcLattice::TargetGroup` - -A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers - -`TargetGroup` extends core.Resource and implements ITargetGroup - -```typescript - - /** Create a vpc lattice TargetGroup. - * Implemented by `TargetGroup`. - */ -export interface ITargetGroup extends core.IResource { - /** - * The id of the target group - */ - readonly targetGroupId: string - /** - * The Arn of the target group - */ - readonly targetGroupArn: string; -} -``` - -`TargetGroup` will take `TargetGroupProps` - -```typescript -/** - * Properties for a Target Group, Only supply one of instancetargets, lambdaTargets, albTargets, ipTargets - */ -export interface TargetGroupProps { - /** - * The name of the target group - */ - readonly name: string, - /** - * Targets - */ - readonly target: Target, -} -``` - ---- - -## Classes Detail - -### Target - -`Target` is an abstract class with static function to return propertys for use in a `TargetGroup` -Targets can be lambda, ipAddress, ec2instances, or applicaiton loadbalancers. - -```typescript -/** - * Targets for target Groups - */ -export abstract class Target { - - /** - * Lambda Target - * @param lambda - */ - public static lambda(lambda: aws_lambda.Function[]): Target { }; - - /** - * IpAddress as Targets - * @param ipAddress - * @param config - */ - public static ipAddress(ipAddress: string[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty ): Target { }; - - /** - * EC2 Instances as Targets - * @param ec2instance - * @param config - */ - public static ec2instance(ec2instance: ec2.Instance[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { }; - - /** - * Application Load Balancer as Targets - * @param alb - * @param config - */ - public static applicationLoadBalancer(alb: elbv2.ApplicationListener[], config: aws_vpclattice.CfnTargetGroup.TargetGroupConfigProperty): Target { } - -``` - -### LoggingDestination - -LoggingDestination is a abstract class to return properties for a LoggingSubscription - -```typescript -/** - * Logging options - */ -export abstract class LoggingDestination { - - /** - * Construct a logging destination for a S3 Bucket - * @param bucket an s3 bucket - */ - public static s3(bucket: s3.IBucket): LoggingDestination { } - /** - * Send to CLoudwatch - * @param logGroup - */ - public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination { } - - /** - * Stream to Kinesis - * @param stream - */ - public static kinesis(stream: kinesis.IStream): LoggingDestination { } - -} -``` - -### HeatlhCheck - -HealthChecks is an abstract class that is used to build a Health Check which can be optionally used as part of a listener rule. - -```typescript -/** - * A Configuration of the TargetGroup Health Check. - */ -export interface TargetGroupHealthCheckProps { - /** - * Enable this Health Check - * @default true - */ - readonly enabled?: boolean | undefined; - /** - * Health Check Interval - * @default 30 seconds - */ - readonly healthCheckInterval?: core.Duration | undefined; - /** - * TimeOut Period - * @default 5 seconds - */ - readonly healthCheckTimeout?: core.Duration | undefined; - /** - * Number of Healthy Responses before Target is considered healthy - * @default 2 - */ - readonly healthyThresholdCount?: number | undefined; - /** - * Check based on Response from target - * @default 200 OK - */ - readonly matcher?: FixedResponse | undefined; - /** - * Path to use for Health Check - * @default '/' - */ - readonly path?: string | undefined; - /** - * Port to use for Health Check - * @default 443 - */ - readonly port?: number | undefined; - /** - * Protocol to use for Health Check - * @default HTTPS - */ - readonly protocol?: Protocol | undefined; - /** - * Protocol to use for Health Check - * @default HTTP2 - */ - readonly protocolVersion?: ProtocolVersion | undefined; - /** - * Number of unhealty events before Target is considered unhealthy - * @default 1 - */ - readonly unhealthyThresholdCount?: number | undefined; -} - -/** - * Create a Health Check for a target - */ -export abstract class HealthCheck { - - /** - * A Health Check configuration object for a target - * @param props - * @returns HealthCheck - */ - public static check(props: TargetGroupHealthCheckProps): HealthCheck { - - // validate the ranges for the health check - if (props.healthCheckInterval) { - if (props.healthCheckInterval.toSeconds() < 5 || props.healthCheckInterval.toSeconds() > 300) { - throw new Error('HealthCheckInterval must be between 5 and 300 seconds'); - } - }; - - if (props.healthCheckTimeout) { - if (props.healthCheckTimeout.toSeconds() < 1 || props.healthCheckTimeout.toSeconds() > 120) { - throw new Error('HealthCheckTimeout must be between 1 and 120seconds'); - } - }; - - if (props.healthyThresholdCount) { - if (props.healthyThresholdCount < 1 || props.healthyThresholdCount > 10) { - throw new Error('HealthyThresholdCount must be between 1 and 10'); - } - }; - - if (props.protocolVersion) { - if (props.protocolVersion === ProtocolVersion.GRPC) { - throw new Error('GRPC is not supported'); - } - }; - - if (props.unhealthyThresholdCount) { - if (props.unhealthyThresholdCount < 2 || props.unhealthyThresholdCount > 10) { - throw new Error('UnhealthyThresholdCount must be between 2 and 10'); - } - } - - var port: number; - if (props.port) { - port = props.port; - } else if ( props.protocol === Protocol.HTTP ) { - port = 80; - } else { - port = 443; - }; - - let matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined = undefined; - if (props.matcher) { - const codeAsString = props.matcher.toString(); - matcher = { httpCode: codeAsString }; - }; - - return { - enabled: props.enabled ?? true, - healthCheckInterval: props.healthCheckInterval ?? core.Duration.seconds(30), - healthCheckTimeout: props.healthCheckTimeout ?? core.Duration.seconds(5), - path: props.path ?? '/', - protocol: props.protocol ?? 'HTTPS', - port: port, - protocolVersion: props.protocolVersion ?? 'HTTP1', - unhealthyThresholdCount: props.unhealthyThresholdCount ?? 2, - healthyThresholdCount: props.healthyThresholdCount ?? 5, - matcher: matcher, - }; - }; - - /** - * health check is enabled. - */ - public abstract readonly enabled: boolean; - /** - * healthCheck Interval - */ - public abstract readonly healthCheckInterval: core.Duration; - /** - * HealthCheck Timeout - */ - public abstract readonly healthCheckTimeout: core.Duration; - /** - * Target Match reponse - */ - public abstract readonly matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined; - /** - * Path to check - */ - public abstract readonly path: string; - /** - * Port to check - */ - public abstract readonly port: number; - /** Protocol - * - */ - public abstract readonly protocol: string; - /** - * HTTP Protocol Version - */ - public abstract readonly protocolVersion: string; - /** - * Unhealthy Threshold Count - */ - public abstract readonly unhealthyThresholdCount: number; - /** - * Healthy Threshold Count - */ - public abstract readonly healthyThresholdCount: number; - - protected constructor() {}; - -}; -``` - ---- - -## Enums Detail - -The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. - -### AuthType - -Lattice Services can use IAM for Authentication or NONE. - -### FixedResponse - -Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need expanding - -### HTTPMethods - -Valid HTTP Methods, these are used for constructing Rules. - -### IpAddressType - -IPv4 and IPv6, used for creating rules - -### MatchOperators - -Contains, Exact and Prefix used for creating rules - -### PathMatchType - -Exact Prefix, used for creating path matches in rules. - -### Protocol - -HTTP or HTTPS - used for creating rules. - -### ProtocolVersion - -HTTP1, HTTP2 or GRPC - used for creating rules. - -### RuleAccessMode - -Used for creating Authenticaiton Policy Access Modes. - -### ServiceNetworkAccessMode - -Used for creating Authenticaiton Policy Access Modes. (Note a different set of options from RuleAccessMode) - -### TargetTypes - -LAMBDA, IP, INSTANCE, ALB. Used for creating targets. - ---- - -## FAQ - -**What are we launching today?** -Amazon VPC Lattice AWS CDK L2 Construct - -**Why should I use this construct?** -This CDK L2 Construct can be used to deploy resources from Amazon VPC Lattice. VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). - -This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). You have the freedom to create the combination of resources you need, so in multi-AWS Account environments you can make use of the module as many times as needed (different providers) to create your application network architecture. - -You can check common Amazon VPC Lattice Reference Architectures to understand the different use cases you can build with the AWS service. - -- It simplifies the deployment of common patterns for AWS VPC Lattice -- It has been tested and implemented as part of a number of wider architectures -- It is extensible to support other patterns as they emerge -- It simplifies AWS VPC Lattice adoption and administration -- Allows you to integrate infrastructure deployment with your application code -- Reduces time to deploy and test AWS VPC Lattice -- Provides separation of concerns with a common interface for user personas - -**Why are we doing this?** - -- To provide a CDK native interface for AWS VPC Lattice -- Provide a way to deploy AWS VPC Lattice deterministically - -**Is this a breaking change** -No. - -What are the drawbacks of this solution? - -- It is an opinionated pattern, however there are escapes to help customisation where needed. -- It is a new AWS Service and its common usecases and features may change and evolve - ---- - -### Acceptance - -Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): - -`[ ] Signed-off by API Bar Raiser @TheRealAmazonKendra` From 1c1a4ed1384b745db757d7c36d4ceaabdc6b0e01 Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Mon, 31 Jul 2023 21:21:35 +0000 Subject: [PATCH 26/31] restored 0502_aws-vpclattice.md --- text/{0502-vpclattice.md => 0502_aws-vpclattice.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename text/{0502-vpclattice.md => 0502_aws-vpclattice.md} (100%) diff --git a/text/0502-vpclattice.md b/text/0502_aws-vpclattice.md similarity index 100% rename from text/0502-vpclattice.md rename to text/0502_aws-vpclattice.md From 64b889428a24ea53532dbbaaf806f21edaa47792 Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Mon, 7 Aug 2023 02:55:17 +0000 Subject: [PATCH 27/31] fix: formatting of markup document to remove MD013 and MD009 errors --- .gitignore | 1 + .markdownlint.json | 4 + text/0502_aws-vpclattice.md | 254 +++++++++++++++++++----------------- 3 files changed, 138 insertions(+), 121 deletions(-) create mode 100644 .markdownlint.json diff --git a/.gitignore b/.gitignore index 520aade24..1505510f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # VSCode Local history extension .history/ *.swp +.markdownlint.json diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 000000000..ab00c44e0 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,4 @@ +{ + "MD013": { "line_length": 150}, + "MD009": { "strict": false} +} \ No newline at end of file diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 230965c41..3585c88f9 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -16,7 +16,7 @@ ### Original Author(s) -@mrpackethead, , @taylaand, @nbaillie +@mrpackethead, , @taylaand, @nbaillie ### Tracking Issue @@ -40,9 +40,13 @@ ## VpcLattice -Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, and serverless applications. +Amazon VPC Lattice is an application networking service that consistently connects, monitors, and secures communications between your services, +helping to improve productivity so that your developers can focus on building features that matter to your business. You can define policies for +network traffic management, access, and monitoring to connect compute services in a simplified and consistent way across instances, containers, +and serverless applications. -The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in creating the underlying auth policy and listener rules together, as their is significant intersection in the properties require for both. +The L2 Construct seeks to assist the consumer to create a lattice service easily by abstracting some of the detail. The major part of this is in +creating the underlying auth policy and listener rules together, as their is significant intersection in the properties required for both. --- @@ -54,28 +58,18 @@ The L2 Construct seeks to assist the consumer to create a lattice service easily - A Service Network is created - The Service is associated with the ServiceNetwork, and two vpcs are attached to it. - A Lattice Network is created, and associated with two different VPC's, VPC1 and VPC2. -- Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests. Lambda1 will be in VPC1, and Lambda2 in VPC2 +- Two lambdas are created, lambda1 is providing a interface to an api, lambda2 is making requests. Lambda1 will be in VPC1, and Lambda2 in VPC2 ```typescript import * as core from 'aws-cdk-lib'; -import { - aws_iam as iam, -} - from 'aws-cdk-lib'; +import { aws_iam as iam } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { SupportResources } from './support'; -import { - ServiceNetwork, - Service, - TargetGroup, - Target, -} - from '../../lib/index'; +import { ServiceNetwork, Service, TargetGroup, Target } from '../../lib/index'; export class LatticeTestStack extends core.Stack { - constructor(scope: Construct, id: string, props?: core.StackProps) { super(scope, id, props); @@ -91,9 +85,8 @@ export class LatticeTestStack extends core.Stack { // - cloudformation name const myListener = new vpclattice.Listener(this, 'Listener', { service: myLatticeService, - }) + }); - // add a listenerRule that will use the helloworld lambda as a Target mylistener.addListenerRule({ name: 'helloworld', @@ -102,9 +95,7 @@ export class LatticeTestStack extends core.Stack { { targetGroup: new vpclattice.TargetGroup(this, 'hellolambdatargets', { name: 'hellowworld', - target: vpclattice.Target.lambda([ - support.helloWorld, - ]), + target: vpclattice.Target.lambda([support.helloWorld]), }), }, ], @@ -113,7 +104,7 @@ export class LatticeTestStack extends core.Stack { pathMatches: { path: '/hello' }, }, // we will only allow access to this service from the ec2 instance - accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED + accessMode: vpclattice.RuleAccessMode.UNAUTHENTICATED, }); //add a listenerRule that will use the goodbyeworld lambda as a Target @@ -122,15 +113,17 @@ export class LatticeTestStack extends core.Stack { priority: 20, action: [ { - targetGroup: new vpclattice.TargetGroup(this, 'goodbyelambdatargets', { - name: 'goodbyeworld', - target: vpclattice.Target.lambda([ - support.goodbyeWorld, - ]), - }), + targetGroup: new vpclattice.TargetGroup( + this, + 'goodbyelambdatargets', + { + name: 'goodbyeworld', + target: vpclattice.Target.lambda([support.goodbyeWorld]), + }, + ), }, ], - + httpMatch: { pathMatches: { path: '/goodbye' }, }, @@ -139,7 +132,6 @@ export class LatticeTestStack extends core.Stack { accessMode: vpclattice.RuleAccessMode.AUTHENTICATED_ONLY, }); - myLatticeService.applyAuthPolicy(); /** @@ -151,9 +143,7 @@ export class LatticeTestStack extends core.Stack { const serviceNetwork = new ServiceNetwork(this, 'LatticeServiceNetwork', { services: [myLatticeService], - vpcs: [ - support.vpc1, - ], + vpcs: [support.vpc1], }); serviceNetwork.applyAuthPolicyToServiceNetwork(); @@ -202,9 +192,11 @@ export class LatticeTestStack extends core.Stack { ### ServiceNetwork -Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` +Creates a cloudformation `AWS::VpcLattice::ServiceNetwork` -A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is associated with the service network. +A service network is a logical boundary for a collection of services. Services associated with the network can be authorized for discovery, +connectivity, accessibility, and observability. To make requests to services in the network, your service or client must be in a VPC that is +associated with the service network. ![Service Network](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service-network.png) @@ -216,10 +208,9 @@ The construct will extend ServiceNetworkBase and implement IServiceNetwork. * Implemented by `ServiceNetwork`. */ export interface IServiceNetwork extends core.IResource { - /** - * The Amazon Resource Name (ARN) of the service network. - */ + * The Amazon Resource Name (ARN) of the service network. + */ readonly serviceNetworkArn: string; /** * The Id of the Service Network @@ -244,7 +235,6 @@ The Construct will consume ServiceNetworkProps. ```typescript export interface ServiceNetworkProps { - /** The name of the Service Network. If not provided Cloudformation will provide * a name * @default cloudformation generated name @@ -253,7 +243,7 @@ export interface ServiceNetworkProps { /** * The type of authentication to use with the Service Network. The only method avaialble is - * AWS_IAM, however in anticipation, it is expected that other types will be added. + * AWS_IAM, however in anticipation, it is expected that other types will be added. * @default 'AWS_IAM' */ readonly authType?: AuthType | undefined; @@ -281,10 +271,11 @@ export interface ServiceNetworkProps { */ readonly accessmode?: ServiceNetworkAccessMode | undefined; } - ``` -`ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks ( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete value between cross account stacks. +`ServiceNetwork` will implement statics in addition to those in IServiceNetwork, to allow the import of the servicenetwork in other stacks +( potentially cross account ). `fromName` provides a lookup to obtain the Id, using a custom resource. This provides a way to pass a concrete +value between cross account stacks. ```typescript public static fromId(scope: constructs.Construct, id: string, props: ImportedServiceNetworkProps ): IServiceNetwork { @@ -300,13 +291,13 @@ public static fromName(scope: constructs.Construct, id: string, serviceNetworkNa ```typescript -// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application +// adds an iam statement to the the authpolicy. Use this to create policy that is bespoke to this application addStatementToAuthPolicy(statement: iam.PolicyStatement) ``` ```typescript -// applies the AuthPolicy that has been created, to the serviceNetwork. -applyAuthPolicyToServiceNetwork() +// applies the AuthPolicy that has been created, to the serviceNetwork. +applyAuthPolicyToServiceNetwork(); ``` ```typescript @@ -321,13 +312,11 @@ addloggingDestination(props: AddloggingDestinationProps) ### ServiceNetworkAssociation -Creates a Cloudformation `AWS::VpcLattice::ServiceNetworkServiceAssociation` -Associates a service with a service network. -`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps -Consider using `.associateWithServiceNetwork` method on `Service` in preference. +Creates a Cloudformation `AWS::VpcLattice::ServiceNetworkServiceAssociation` Associates a service with a service network. +`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssociationProps Consider using `.associateWithServiceNetwork` method on +`Service` in preference. ```typescript - export interface ServiceNetworkAssociationProps { /** * lattice Service @@ -344,7 +333,9 @@ export interface ServiceNetworkAssociationProps { Creates a cloudformation `AWS::VpcLattice::Service` -A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. +A service within VPC Lattice is an independently deployable unit of software that delivers a specific task or function. A service has listeners that +use rules, that you configure to route traffic to your targets. Targets can be EC2 instances, IP addresses, serverless Lambda functions, +Application Load Balancers, or Kubernetes Pods. The following diagram shows the key components of a typical service within VPC Lattice. ![service](https://docs.aws.amazon.com/images/vpc-lattice/latest/ug/images/service.png) @@ -385,8 +376,8 @@ export interface IService extends core.IResource { */ dnsEntry: aws_vpclattice.CfnService.DnsEntryProperty | undefined; /** - * A name for the service - */ + * A name for the service + */ name: string | undefined; /** * The auth Policy for the service. @@ -394,11 +385,10 @@ export interface IService extends core.IResource { authPolicy: iam.PolicyDocument; /** - * associate the service with a servicenetwork. - */ + * associate the service with a servicenetwork. + */ associateWithServiceNetwork(serviceNetwork: IServiceNetwork): void; } - ``` `Service` will take `ServiceProps` as props @@ -411,7 +401,6 @@ export interface IService extends core.IResource { * Properties for a Lattice Service */ export interface ServiceProps { - /** * Name for the service * @default cloudformation will provide a name @@ -427,7 +416,7 @@ export interface ServiceProps { /** * Listeners that will be attached to the service * @default no listeners - */ + */ readonly listeners?: IListener[] | undefined; /** @@ -459,7 +448,7 @@ export interface ServiceProps { } ``` -`Service` will implement a static for importing the service. +`Service` will implement a static for importing the service. ```typescript public static fromId(scope: constructs.Construct, id: string, serviceId: string): IService { @@ -467,7 +456,10 @@ public static fromId(scope: constructs.Construct, id: string, serviceId: string) } ``` -Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. +Note: unlike ServiceNetwork there are minimal reason to implmenet a import by name, (so a concrete reference can be used cross accounts), as a +services 'boundarys' are within a single account. THe fromId allows an import of the service from within an account, if required to implement multiple +stacks.. (this however is probably an edge case as well). The use case here is dependant on the security stance of how lattice will be configured and +who has control of the service/servicenetworks. Its unclear if a crossAccount method should be implemeneted. `Service` will implement methods for the following @@ -492,7 +484,7 @@ public grantAccess(principals: iam.IPrincipal[]) { } ```typescript /** - * Add a PolicyStatement to the auth policy + * Add a PolicyStatement to the auth policy */ public addPolicyStatement(statement: iam.PolicyStatement): void { } ``` @@ -515,7 +507,8 @@ public grantAccess(principals: iam.IPrincipal[]) { } Associates a ServiceNetwork to a Service -`ServiceNetworkAssociation` extends core.Resource and consumes ServiceNetworkAssocationProps. +`ServiceNetworkAssociation` extends core.Resource and consumes +ServiceNetworkAssocationProps. ```typescript /** @@ -537,32 +530,32 @@ export interface ServiceNetworkAssociationProps { Creates a cloudformation `AWS::VpcLattice::Listener` -A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the service routes requests to its registered targets. +A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener +determine how the service routes requests to its registered targets. It is not expected that a direct call to Listener will be made, instead the `.addListener()` should be used on a service `Listener` extends `core.resource` implements `IListener` -``` typescript +```typescript /** * Create a vpcLattice Listener. * Implemented by `Listener`. */ export interface IListener extends core.IResource { /** - * The Amazon Resource Name (ARN) of the service. - */ + * The Amazon Resource Name (ARN) of the service. + */ readonly listenerArn: string; /** - * The Id of the Service Network - */ + * The Id of the Service Network + */ readonly listenerId: string; /** * Add A Listener Rule to the Listener */ addListenerRule(props: AddRuleProps): void; - } ``` @@ -576,22 +569,24 @@ export interface ListenerProps { /** * * A default action that will be taken if no rules match. * @default 404 NOT Found - */ - readonly defaultAction?: aws_vpclattice.CfnListener.DefaultActionProperty | undefined; + */ + readonly defaultAction?: + | aws_vpclattice.CfnListener.DefaultActionProperty + | undefined; /** - * protocol that the listener will listen on - * @default HTTPS - */ + * protocol that the listener will listen on + * @default HTTPS + */ readonly protocol?: Protocol | undefined; /** - * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol - * @default 80 or 443 depending on the Protocol - */ - readonly port?: number | undefined + * Optional port number for the listener. If not supplied, will default to 80 or 443, depending on the Protocol + * @default 80 or 443 depending on the Protocol + */ + readonly port?: number | undefined; /** - * The Name of the service. - * @default CloudFormation provided name. - */ + * The Name of the service. + * @default CloudFormation provided name. + */ readonly name?: string; /** * The Id of the service that this listener is associated with. @@ -614,20 +609,20 @@ export interface ListenerProps { Creates a cloudformation `AWS::VpcLattice::TargetGroup` -A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP addresses, Lambda functions, Application Load Balancers +A VPC Lattice target group is a collection of targets, or compute resources, that run your application or service. Targets can be EC2 instances, IP +addresses, Lambda functions, Application Load Balancers `TargetGroup` extends core.Resource and implements ITargetGroup ```typescript - - /** Create a vpc lattice TargetGroup. +/** Create a vpc lattice TargetGroup. * Implemented by `TargetGroup`. */ export interface ITargetGroup extends core.IResource { /** * The id of the target group */ - readonly targetGroupId: string + readonly targetGroupId: string; /** * The Arn of the target group */ @@ -645,11 +640,11 @@ export interface TargetGroupProps { /** * The name of the target group */ - readonly name: string, + readonly name: string; /** * Targets */ - readonly target: Target, + readonly target: Target; } ``` @@ -659,8 +654,8 @@ export interface TargetGroupProps { ### Target -`Target` is an abstract class with static function to return propertys for use in a `TargetGroup` -Targets can be lambda, ipAddress, ec2instances, or applicaiton loadbalancers. +`Target` is an abstract class with static function to return propertys for use in a `TargetGroup` Targets can be lambda, ipAddress, ec2instances, or +applicaiton loadbalancers. ```typescript /** @@ -699,31 +694,30 @@ export abstract class Target { ### LoggingDestination -LoggingDestination is a abstract class to return properties for a LoggingSubscription +LoggingDestination is a abstract class to return properties for a +LoggingSubscription ```typescript /** * Logging options */ export abstract class LoggingDestination { - /** * Construct a logging destination for a S3 Bucket * @param bucket an s3 bucket */ - public static s3(bucket: s3.IBucket): LoggingDestination { } + public static s3(bucket: s3.IBucket): LoggingDestination {} /** * Send to CLoudwatch * @param logGroup */ - public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination { } + public static cloudwatch(logGroup: logs.ILogGroup): LoggingDestination {} /** * Stream to Kinesis * @param stream */ - public static kinesis(stream: kinesis.IStream): LoggingDestination { } - + public static kinesis(stream: kinesis.IStream): LoggingDestination {} } ``` @@ -792,41 +786,50 @@ export interface TargetGroupHealthCheckProps { * Create a Health Check for a target */ export abstract class HealthCheck { - /** * A Health Check configuration object for a target * @param props * @returns HealthCheck */ public static check(props: TargetGroupHealthCheckProps): HealthCheck { - // validate the ranges for the health check if (props.healthCheckInterval) { - if (props.healthCheckInterval.toSeconds() < 5 || props.healthCheckInterval.toSeconds() > 300) { - throw new Error('HealthCheckInterval must be between 5 and 300 seconds'); + if ( + props.healthCheckInterval.toSeconds() < 5 || + props.healthCheckInterval.toSeconds() > 300 + ) { + throw new Error( + 'HealthCheckInterval must be between 5 and 300 seconds', + ); } - }; + } if (props.healthCheckTimeout) { - if (props.healthCheckTimeout.toSeconds() < 1 || props.healthCheckTimeout.toSeconds() > 120) { + if ( + props.healthCheckTimeout.toSeconds() < 1 || + props.healthCheckTimeout.toSeconds() > 120 + ) { throw new Error('HealthCheckTimeout must be between 1 and 120seconds'); } - }; + } if (props.healthyThresholdCount) { if (props.healthyThresholdCount < 1 || props.healthyThresholdCount > 10) { throw new Error('HealthyThresholdCount must be between 1 and 10'); } - }; + } if (props.protocolVersion) { if (props.protocolVersion === ProtocolVersion.GRPC) { throw new Error('GRPC is not supported'); } - }; + } if (props.unhealthyThresholdCount) { - if (props.unhealthyThresholdCount < 2 || props.unhealthyThresholdCount > 10) { + if ( + props.unhealthyThresholdCount < 2 || + props.unhealthyThresholdCount > 10 + ) { throw new Error('UnhealthyThresholdCount must be between 2 and 10'); } } @@ -834,21 +837,23 @@ export abstract class HealthCheck { var port: number; if (props.port) { port = props.port; - } else if ( props.protocol === Protocol.HTTP ) { + } else if (props.protocol === Protocol.HTTP) { port = 80; } else { port = 443; - }; + } - let matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined = undefined; + let matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined = + undefined; if (props.matcher) { const codeAsString = props.matcher.toString(); matcher = { httpCode: codeAsString }; - }; + } return { enabled: props.enabled ?? true, - healthCheckInterval: props.healthCheckInterval ?? core.Duration.seconds(30), + healthCheckInterval: + props.healthCheckInterval ?? core.Duration.seconds(30), healthCheckTimeout: props.healthCheckTimeout ?? core.Duration.seconds(5), path: props.path ?? '/', protocol: props.protocol ?? 'HTTPS', @@ -858,7 +863,7 @@ export abstract class HealthCheck { healthyThresholdCount: props.healthyThresholdCount ?? 5, matcher: matcher, }; - }; + } /** * health check is enabled. @@ -875,7 +880,9 @@ export abstract class HealthCheck { /** * Target Match reponse */ - public abstract readonly matcher: aws_vpclattice.CfnTargetGroup.MatcherProperty | undefined; + public abstract readonly matcher: + | aws_vpclattice.CfnTargetGroup.MatcherProperty + | undefined; /** * Path to check */ @@ -901,16 +908,16 @@ export abstract class HealthCheck { */ public abstract readonly healthyThresholdCount: number; - protected constructor() {}; - -}; + protected constructor() {} +} ``` --- ## Enums Detail -The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. +The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however +there are only certain valid options. ### AuthType @@ -918,7 +925,8 @@ Lattice Services can use IAM for Authentication or NONE. ### FixedResponse -Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need expanding +Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need +expanding ### HTTPMethods @@ -964,9 +972,12 @@ LAMBDA, IP, INSTANCE, ALB. Used for creating targets. Amazon VPC Lattice AWS CDK L2 Construct **Why should I use this construct?** -This CDK L2 Construct can be used to deploy resources from Amazon VPC Lattice. VPC Lattice is a fully managed application networking service that you use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). +This CDK L2 Construct can be used to deploy resources from Amazon VPC Lattice. VPC Lattice is a fully managed application networking service that you +use to connect, secure, and monitor all your services across multiple accounts and virtual private clouds (VPCs). -This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups (and targets), and Associations (Service or VPC). You have the freedom to create the combination of resources you need, so in multi-AWS Account environments you can make use of the module as many times as needed (different providers) to create your application network architecture. +This construct handles all the different resources you can use with VPC Lattice: Service Network, Service, Listeners, Listener Rules, Target Groups +(and targets), and Associations (Service or VPC). You have the freedom to create the combination of resources you need, so in multi-AWS Account +environments you can make use of the module as many times as needed (different providers) to create your application network architecture. You can check common Amazon VPC Lattice Reference Architectures to understand the different use cases you can build with the AWS service. @@ -978,7 +989,7 @@ You can check common Amazon VPC Lattice Reference Architectures to understand th - Reduces time to deploy and test AWS VPC Lattice - Provides separation of concerns with a common interface for user personas -**Why are we doing this?** +**Why are we doing this?** - To provide a CDK native interface for AWS VPC Lattice - Provide a way to deploy AWS VPC Lattice deterministically @@ -995,6 +1006,7 @@ What are the drawbacks of this solution? ### Acceptance -Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the RFC pull request): +Ticking the box below indicates that the public API of this RFC has been signed-off by the API bar raiser (the api-approved label was applied to the +RFC pull request): `[ ] Signed-off by API Bar Raiser @TheRealAmazonKendra` From 1871cb879c0911e6a3fdd5c057bf2d8105c6e50d Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Wed, 9 Aug 2023 23:00:10 +0000 Subject: [PATCH 28/31] replace AuthType enum with enum like class 'Authorizer' for potential future auth models --- text/0502_aws-vpclattice.md | 70 +++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/text/0502_aws-vpclattice.md b/text/0502_aws-vpclattice.md index 3585c88f9..ced85cabc 100644 --- a/text/0502_aws-vpclattice.md +++ b/text/0502_aws-vpclattice.md @@ -246,7 +246,7 @@ export interface ServiceNetworkProps { * AWS_IAM, however in anticipation, it is expected that other types will be added. * @default 'AWS_IAM' */ - readonly authType?: AuthType | undefined; + readonly authorizer?: Authorizer | undefined; /** * Logging destinations @@ -411,7 +411,7 @@ export interface ServiceProps { * The authType of the Service * @default 'AWS_IAM' */ - readonly authType?: string | undefined; + readonly authorizer: IAuthorizer; /** * Listeners that will be attached to the service @@ -652,6 +652,68 @@ export interface TargetGroupProps { ## Classes Detail +### Authorizer + +`Authorizer` is an enum like class with static functions to return propertys for an Authorizer Type. At present the only type of +Authorizers are `NONE` or `AWS_IAM`. In order to provide non breaking upgrades for the possiblity of other authorizers in the future +this class is used rather than an enum. + +```typescript +/** + * Authorization Types for VPC Lattice. The class type Enum is used to allow + * for the creation of other authentication methods easily in the future. + */ +export enum AuthorizerMode { + /** + * No Authorization is used for Lattice Requests + */ + NONE = 'NONE', + /** + * IAM Policys are used for Lattice Requests. + */ + AWS_IAM = 'AWS_IAM' +} + +/** + * Authorizer Interface. +*/ +export interface IAuthorizer { + /** + * Authorizer Mode + */ + readonly type: AuthorizerMode; +} + +/** + * Authorization Type for Lattice. + */ +export abstract class Authorizer implements IAuthorizer { + + /** + * Use IAM Policy for Authorization + */ + public static iam(): IAuthorizer { + return { + type: AuthorizerMode.AWS_IAM, + }; + } + /** + * Use no Authorization for Lattice Requests + */ + public static none(): IAuthorizer { + return { + type: AuthorizerMode.NONE, + }; + } + /** + * THe AuthMode TYpe + */ + public abstract readonly type: AuthorizerMode; + + protected constructor() {}; +} +``` + ### Target `Target` is an abstract class with static function to return propertys for use in a `TargetGroup` Targets can be lambda, ipAddress, ec2instances, or @@ -919,10 +981,6 @@ export abstract class HealthCheck { The enums in this construct are intended to provide a way to reduce deployment time errors. Many of the L1 constructs will accept `string` however there are only certain valid options. -### AuthType - -Lattice Services can use IAM for Authentication or NONE. - ### FixedResponse Provides valid HTTP Responses such as NOT_FOUND and OK. This is intended for using primarly with configuring default rules. This list may well need From 6b34f2b5a07ba7e0e18c0736cb9b12cf7a4a92cb Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Tue, 15 Aug 2023 05:45:01 +0000 Subject: [PATCH 29/31] fix: removed markdownlint.json --- .markdownlint.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .markdownlint.json diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index ab00c44e0..000000000 --- a/.markdownlint.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "MD013": { "line_length": 150}, - "MD009": { "strict": false} -} \ No newline at end of file From 1e378c86ff999c0056347ede3f1cddbb72e3b801 Mon Sep 17 00:00:00 2001 From: Andrew Frazer Date: Tue, 15 Aug 2023 21:08:11 +0000 Subject: [PATCH 30/31] fix: removed line 4 of .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1505510f1..0d9399db1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ # VSCode Local history extension .history/ -*.swp -.markdownlint.json +*.swp \ No newline at end of file From bcbff0812cb9fcf2c09752f54495983b9cf9dadb Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 27 Oct 2023 17:18:50 +0900 Subject: [PATCH 31/31] fix: readme was altered fix readme --- README.md | 207 +++++++++--------------------------------------------- 1 file changed, 33 insertions(+), 174 deletions(-) diff --git a/README.md b/README.md index 9f10676b7..d387c516c 100644 --- a/README.md +++ b/README.md @@ -8,178 +8,27 @@ future state of the libraries and to discover projects for contribution. [jsii]: https://github.com/aws/jsii **Jump to**: [What is an RFC?](#what-is-an-rfc) | -[When to submit?](#when-to-submit-an-rfc) | [RFC Process](#rfc-process) | -[RFC Life Cycle](#the-rfc-life-cycle) +[RFC State Diagram](#the-rfc-life-cycle) + +## Current RFCs + +**Jump to**: +[Full list](./FULL_INDEX.md) | +[Accepted](./ACCEPTED.md) | +[Proposed](./PROPOSED.md) | +[Closed](./CLOSED.md) \#|Title|Owner|Status ---|-----|-----|------ -[52](https://github.com/aws/aws-cdk-rfcs/issues/52)|[Support resource import](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0052-resource-importing-support.md)||👷 implementing -[77](https://github.com/aws/aws-cdk-rfcs/issues/77)|[CloudFormation Registry Support](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0077-import-external-resources.md)||👷 implementing -[340](https://github.com/aws/aws-cdk-rfcs/issues/340)|[Kinesis Data Firehose Delivery Stream L2](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0340-firehose-l2.md)|[@BenChaimberg](https://github.com/BenChaimberg)|👷 implementing -[431](https://github.com/aws/aws-cdk-rfcs/issues/431)|[SageMaker Model Hosting L2 Constructs](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0431-sagemaker-l2-endpoint.md)||👷 implementing -[456](https://github.com/aws/aws-cdk-rfcs/issues/456)|[L2 ElastiCache support](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0456-elasticache-l2.md)||👷 implementing -[460](https://github.com/aws/aws-cdk-rfcs/issues/460)|[Reduce aws-cdk-lib package size](https://github.com/aws/aws-cdk-rfcs/issues/460)||👷 implementing -[474](https://github.com/aws/aws-cdk-rfcs/issues/474)|[EventBridge Scheduler L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)||👷 implementing -[457](https://github.com/aws/aws-cdk-rfcs/issues/457)|[Create fluent-assertions library to improve consumer test readability](https://github.com/aws/aws-cdk-rfcs/issues/457)||📆 planning -[502](https://https://github.com/aws/aws-cdk-rfcs/issues/502) | [L2 Constructs for VPCLattice](https://github.com/aws/aws-cdk-rfcs/issues/502) | [@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra) | ✍️ review -[507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved -[510](https://github.com/aws/aws-cdk-rfcs/issues/510)|[DyanmoDB Global Table L2 Construct](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0510-dynamodb-global-table.md)|[@vinayak-kukreja](https://github.com/vinayak-kukreja)|👍 approved -[8](https://github.com/aws/aws-cdk-rfcs/issues/8)|[Project Structure Guidelines](https://github.com/aws/aws-cdk-rfcs/issues/8)|[@rix0rrr](https://github.com/rix0rrr)|✍️ review -[175](https://github.com/aws/aws-cdk-rfcs/issues/175)|[AppSync Mapping Template Object Model](https://github.com/aws/aws-cdk-rfcs/pull/177)|[@MrArnoldPalmer](https://github.com/MrArnoldPalmer)|✍️ review -[317](https://github.com/aws/aws-cdk-rfcs/issues/317)|[CDK third-party dependencies management](https://github.com/aws/aws-cdk-rfcs/issues/317)||✍️ review +[456](https://github.com/aws/aws-cdk-rfcs/issues/456)|[L2 ElastiCache support](https://github.com/aws/aws-cdk-rfcs/blob/main/text/0456-elasticache-l2.md)||👷 implementing +[473](https://github.com/aws/aws-cdk-rfcs/issues/473)|[EventBridge Pipes L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/473)|[@mrgrain](https://github.com/mrgrain)|👷 implementing +[162](https://github.com/aws/aws-cdk-rfcs/issues/162)|[CDK Refactoring Tools](https://github.com/aws/aws-cdk-rfcs/issues/162)||📆 planning +[507](https://github.com/aws/aws-cdk-rfcs/issues/507)|[Full control over VPC and subnet configuration](https://github.com/aws/aws-cdk-rfcs/blob/main/text/0507-subnets)|[@otaviomacedo](https://github.com/otaviomacedo)|👍 approved +[502](https://github.com/aws/aws-cdk-rfcs/issues/502)|[Amazon VPC Lattice L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/502)||⏰ final comments [362](https://github.com/aws/aws-cdk-rfcs/issues/362)|[Construct Library for Contributor Insights Rules](https://github.com/aws/aws-cdk-rfcs/issues/362)||✍️ review [419](https://github.com/aws/aws-cdk-rfcs/issues/419)|[CDK environment setup for platform/system administrators](https://github.com/aws/aws-cdk-rfcs/issues/419)||✍️ review -[2](https://github.com/aws/aws-cdk-rfcs/issues/2)|[Support for CloudFormation Resource Imports](https://github.com/aws/aws-cdk-rfcs/issues/2)||💡 proposed -[4](https://github.com/aws/aws-cdk-rfcs/issues/4)|[CDK Testing Toolkit](https://github.com/aws/aws-cdk-rfcs/issues/4)|[@nija-at](https://github.com/nija-at)|💡 proposed -[5](https://github.com/aws/aws-cdk-rfcs/issues/5)|[Security-restricted environments](https://github.com/aws/aws-cdk-rfcs/issues/5)||💡 proposed -[9](https://github.com/aws/aws-cdk-rfcs/issues/9)|[Master developer guide sources in main repo](https://github.com/aws/aws-cdk-rfcs/issues/9)||💡 proposed -[10](https://github.com/aws/aws-cdk-rfcs/issues/10)|[New workshop modules](https://github.com/aws/aws-cdk-rfcs/issues/10)||💡 proposed -[13](https://github.com/aws/aws-cdk-rfcs/issues/13)|[Improvements to Reference docs](https://github.com/aws/aws-cdk-rfcs/issues/13)||💡 proposed -[14](https://github.com/aws/aws-cdk-rfcs/issues/14)|[Toolchain 2.0](https://github.com/aws/aws-cdk-rfcs/issues/14)||💡 proposed -[15](https://github.com/aws/aws-cdk-rfcs/issues/15)|[Scaffolding](https://github.com/aws/aws-cdk-rfcs/issues/15)||💡 proposed -[17](https://github.com/aws/aws-cdk-rfcs/issues/17)|[CLI support for multiple-environments](https://github.com/aws/aws-cdk-rfcs/issues/17)||💡 proposed -[18](https://github.com/aws/aws-cdk-rfcs/issues/18)|[Open Context Providers](https://github.com/aws/aws-cdk-rfcs/pull/167)|[@ddneilson](https://github.com/ddneilson)|💡 proposed -[19](https://github.com/aws/aws-cdk-rfcs/issues/19)|[Introspection API](https://github.com/aws/aws-cdk-rfcs/issues/19)||💡 proposed -[20](https://github.com/aws/aws-cdk-rfcs/issues/20)|[Security posture summary](https://github.com/aws/aws-cdk-rfcs/issues/20)||💡 proposed -[21](https://github.com/aws/aws-cdk-rfcs/issues/21)|[CDK Explorer Roadmap](https://github.com/aws/aws-cdk-rfcs/issues/21)||💡 proposed -[22](https://github.com/aws/aws-cdk-rfcs/issues/22)|[Cost calculator](https://github.com/aws/aws-cdk-rfcs/issues/22)||💡 proposed -[23](https://github.com/aws/aws-cdk-rfcs/issues/23)|[Stateful resource support](https://github.com/aws/aws-cdk-rfcs/issues/23)||💡 proposed -[24](https://github.com/aws/aws-cdk-rfcs/issues/24)|[Resource imports](https://github.com/aws/aws-cdk-rfcs/issues/24)||💡 proposed -[25](https://github.com/aws/aws-cdk-rfcs/issues/25)|[Defaults & configuration policy](https://github.com/aws/aws-cdk-rfcs/issues/25)||💡 proposed -[26](https://github.com/aws/aws-cdk-rfcs/issues/26)|[Monitoring packs](https://github.com/aws/aws-cdk-rfcs/issues/26)||💡 proposed -[27](https://github.com/aws/aws-cdk-rfcs/issues/27)|[200 resource limit tools & guidance](https://github.com/aws/aws-cdk-rfcs/issues/27)||💡 proposed -[30](https://github.com/aws/aws-cdk-rfcs/issues/30)|[Improve synthesized template output](https://github.com/aws/aws-cdk-rfcs/issues/30)||💡 proposed -[31](https://github.com/aws/aws-cdk-rfcs/issues/31)|[Integration tests](https://github.com/aws/aws-cdk-rfcs/issues/31)||💡 proposed -[32](https://github.com/aws/aws-cdk-rfcs/issues/32)|[App-centric operational experience](https://github.com/aws/aws-cdk-rfcs/issues/32)||💡 proposed -[39](https://github.com/aws/aws-cdk-rfcs/issues/39)|[Release public artifacts (lambda layers for custom resources, docker images)](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0039-reduce-module-size.md)||💡 proposed -[40](https://github.com/aws/aws-cdk-rfcs/issues/40)|[Stack traces across language boundaries](https://github.com/aws/aws-cdk-rfcs/issues/40)||💡 proposed -[48](https://github.com/aws/aws-cdk-rfcs/issues/48)|[Faster builds](https://github.com/aws/aws-cdk-rfcs/issues/48)||💡 proposed -[51](https://github.com/aws/aws-cdk-rfcs/issues/51)|[Standardize security groups](https://github.com/aws/aws-cdk-rfcs/issues/51)||💡 proposed -[58](https://github.com/aws/aws-cdk-rfcs/issues/58)|[Improved ergonomics for stack default environment](https://github.com/aws/aws-cdk-rfcs/issues/58)||💡 proposed -[63](https://github.com/aws/aws-cdk-rfcs/issues/63)|[CDK in Secure Environments](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0063-precreated-roles.md)||💡 proposed -[64](https://github.com/aws/aws-cdk-rfcs/issues/64)|[Garbage Collection for Assets](https://github.com/aws/aws-cdk-rfcs/issues/64)|[@kaizencc](https://github.com/kaizencc)|💡 proposed -[65](https://github.com/aws/aws-cdk-rfcs/issues/65)|[CDK Code Generation from AWS Console](https://github.com/aws/aws-cdk-rfcs/issues/65)||💡 proposed -[66](https://github.com/aws/aws-cdk-rfcs/issues/66)|[StackSets Support](https://github.com/aws/aws-cdk-rfcs/issues/66)||💡 proposed -[67](https://github.com/aws/aws-cdk-rfcs/issues/67)|[Monitoring Packs](https://github.com/aws/aws-cdk-rfcs/issues/67)||💡 proposed -[69](https://github.com/aws/aws-cdk-rfcs/issues/69)|[One-off "job" Stacks ("auto destruct")](https://github.com/aws/aws-cdk-rfcs/issues/69)||💡 proposed -[70](https://github.com/aws/aws-cdk-rfcs/issues/70)|[Cost Estimation Tools](https://github.com/aws/aws-cdk-rfcs/issues/70)||💡 proposed -[72](https://github.com/aws/aws-cdk-rfcs/issues/72)|[Stack Policy](https://github.com/aws/aws-cdk-rfcs/issues/72)||💡 proposed -[73](https://github.com/aws/aws-cdk-rfcs/issues/73)|[AWS Resource Model](https://github.com/aws/aws-cdk-rfcs/issues/73)||💡 proposed -[74](https://github.com/aws/aws-cdk-rfcs/issues/74)|[Common API for Resources with Web Addresses](https://github.com/aws/aws-cdk-rfcs/issues/74)||💡 proposed -[78](https://github.com/aws/aws-cdk-rfcs/issues/78)|[Feature proposal: Workspaces](https://github.com/aws/aws-cdk-rfcs/issues/78)||💡 proposed -[81](https://github.com/aws/aws-cdk-rfcs/issues/81)|[AWS Landing Zone CDK pattern request](https://github.com/aws/aws-cdk-rfcs/issues/81)||💡 proposed -[82](https://github.com/aws/aws-cdk-rfcs/issues/82)|[Weak references](https://github.com/aws/aws-cdk-rfcs/issues/82)||💡 proposed -[83](https://github.com/aws/aws-cdk-rfcs/issues/83)|[Global Name Prefix](https://github.com/aws/aws-cdk-rfcs/issues/83)||💡 proposed -[86](https://github.com/aws/aws-cdk-rfcs/issues/86)|[AWS Account Alias Resource](https://github.com/aws/aws-cdk-rfcs/issues/86)||💡 proposed -[127](https://github.com/aws/aws-cdk-rfcs/issues/127)|[CDK to directly reference/import/update an existing stack](https://github.com/aws/aws-cdk-rfcs/issues/127)||💡 proposed -[139](https://github.com/aws/aws-cdk-rfcs/issues/139)|["fromLookup" for additional resources](https://github.com/aws/aws-cdk-rfcs/issues/139)||💡 proposed -[158](https://github.com/aws/aws-cdk-rfcs/issues/158)|[Implement Custom Resources in the AWS Construct Library as CFN Registry Resource Types](https://github.com/aws/aws-cdk-rfcs/pull/170)||💡 proposed -[159](https://github.com/aws/aws-cdk-rfcs/issues/159)|[Cross-App Resource Sharing](https://github.com/aws/aws-cdk-rfcs/issues/159)||💡 proposed -[161](https://github.com/aws/aws-cdk-rfcs/issues/161)|[Cross-Region/Account References](https://github.com/aws/aws-cdk-rfcs/issues/161)||💡 proposed -[162](https://github.com/aws/aws-cdk-rfcs/issues/162)|[CDK Refactoring Tools](https://github.com/aws/aws-cdk-rfcs/issues/162)||💡 proposed -[180](https://github.com/aws/aws-cdk-rfcs/issues/180)|[CustomResources: Allow usage across accounts](https://github.com/aws/aws-cdk-rfcs/issues/180)||💡 proposed -[193](https://github.com/aws/aws-cdk-rfcs/issues/193)|[Fixing of type unions](https://github.com/aws/aws-cdk-rfcs/pull/194)|[@RomainMuller](https://github.com/RomainMuller)|💡 proposed -[201](https://github.com/aws/aws-cdk-rfcs/issues/201)|[Construct scope relocation](https://github.com/aws/aws-cdk-rfcs/issues/201)||💡 proposed -[217](https://github.com/aws/aws-cdk-rfcs/issues/217)|[Alternative Infrastructure Providers](https://github.com/aws/aws-cdk-rfcs/issues/217)|[@ccfife](https://github.com/ccfife)|💡 proposed -[219](https://github.com/aws/aws-cdk-rfcs/issues/219)|[ECS Patterns Service Builder](https://github.com/aws/aws-cdk-rfcs/issues/219)||💡 proposed -[223](https://github.com/aws/aws-cdk-rfcs/issues/223)|[Improvements to Lambda Development Experience](https://github.com/aws/aws-cdk-rfcs/issues/223)||💡 proposed -[228](https://github.com/aws/aws-cdk-rfcs/issues/228)|[CDK CLI Triggers](https://github.com/aws/aws-cdk-rfcs/issues/228)||💡 proposed -[229](https://github.com/aws/aws-cdk-rfcs/issues/229)|[Construct library pattern for metrics](https://github.com/aws/aws-cdk-rfcs/issues/229)||💡 proposed -[230](https://github.com/aws/aws-cdk-rfcs/issues/230)|[Construct library pattern for grants](https://github.com/aws/aws-cdk-rfcs/issues/230)||💡 proposed -[231](https://github.com/aws/aws-cdk-rfcs/issues/231)|[Construct library pattern for resources that use a VPC](https://github.com/aws/aws-cdk-rfcs/issues/231)||💡 proposed -[232](https://github.com/aws/aws-cdk-rfcs/issues/232)|[Construct library pattern for resources that need IAM roles](https://github.com/aws/aws-cdk-rfcs/issues/232)||💡 proposed -[242](https://github.com/aws/aws-cdk-rfcs/issues/242)|[Bootstrap stacks as CDK apps](https://github.com/aws/aws-cdk-rfcs/issues/242)||💡 proposed -[244](https://github.com/aws/aws-cdk-rfcs/issues/244)|[Migration path for EKS Developer Preview](https://github.com/aws/aws-cdk-rfcs/pull/245)||💡 proposed -[247](https://github.com/aws/aws-cdk-rfcs/issues/247)|[CDK Common Stored Data Type Model](https://github.com/aws/aws-cdk-rfcs/issues/247)||💡 proposed -[248](https://github.com/aws/aws-cdk-rfcs/issues/248)|[Standardized context key for "cheap mode"](https://github.com/aws/aws-cdk-rfcs/issues/248)||💡 proposed -[256](https://github.com/aws/aws-cdk-rfcs/issues/256)|[ReactCDK: Add JSX/TSX Support](https://github.com/aws/aws-cdk-rfcs/pull/258)||💡 proposed -[275](https://github.com/aws/aws-cdk-rfcs/issues/275)|[route53-patterns for cross account DNS delegation](https://github.com/aws/aws-cdk-rfcs/issues/275)||💡 proposed -[277](https://github.com/aws/aws-cdk-rfcs/issues/277)|[cdk logs](https://github.com/aws/aws-cdk-rfcs/issues/277)||💡 proposed -[294](https://github.com/aws/aws-cdk-rfcs/issues/294)|[Policy Definition and Enforcement](https://github.com/aws/aws-cdk-rfcs/issues/294)||💡 proposed -[300](https://github.com/aws/aws-cdk-rfcs/issues/300)|[Programmatic access of AWS CDK CLI](https://github.com/aws/aws-cdk-rfcs/issues/300)||💡 proposed -[305](https://github.com/aws/aws-cdk-rfcs/issues/305)|[support code signing of assets](https://github.com/aws/aws-cdk-rfcs/issues/305)||💡 proposed -[309](https://github.com/aws/aws-cdk-rfcs/issues/309)|[Parameter Store for cross stack references](https://github.com/aws/aws-cdk-rfcs/issues/309)||💡 proposed -[313](https://github.com/aws/aws-cdk-rfcs/issues/313)|[Questions on the Go Bindings RFC](https://github.com/aws/aws-cdk-rfcs/issues/313)||💡 proposed -[348](https://github.com/aws/aws-cdk-rfcs/issues/348)|[CloudFormationController - refactor CloudFormation stacks](https://github.com/aws/aws-cdk-rfcs/issues/348)||💡 proposed -[370](https://github.com/aws/aws-cdk-rfcs/issues/370)|[CLI deploy with change set review confirmation](https://github.com/aws/aws-cdk-rfcs/issues/370)||💡 proposed -[375](https://github.com/aws/aws-cdk-rfcs/issues/375)|[Support Encode Properties for CloudFormation CustomResource](https://github.com/aws/aws-cdk-rfcs/issues/375)||💡 proposed -[380](https://github.com/aws/aws-cdk-rfcs/issues/380)|[Remove Node.js as an installed pre-requisite for the jsii runtime](https://github.com/aws/aws-cdk-rfcs/issues/380)||💡 proposed -[394](https://github.com/aws/aws-cdk-rfcs/issues/394)|[WAF v2 L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/394)||💡 proposed -[399](https://github.com/aws/aws-cdk-rfcs/issues/399)|[SSM Document as Objects](https://github.com/aws/aws-cdk-rfcs/issues/399)||💡 proposed -[400](https://github.com/aws/aws-cdk-rfcs/issues/400)|[RUM AppMonitor L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/400)||💡 proposed -[402](https://github.com/aws/aws-cdk-rfcs/issues/402)|[Glue DataBrew L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/402)||💡 proposed -[418](https://github.com/aws/aws-cdk-rfcs/issues/418)|[CDK Operator CLI](https://github.com/aws/aws-cdk-rfcs/issues/418)||💡 proposed -[423](https://github.com/aws/aws-cdk-rfcs/issues/423)|[IoT Sitewise L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/423)||💡 proposed -[426](https://github.com/aws/aws-cdk-rfcs/issues/426)|[AppConfig L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/426)||💡 proposed -[428](https://github.com/aws/aws-cdk-rfcs/issues/428)|[Amazon CloudWatch Evidently L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/428)||💡 proposed -[434](https://github.com/aws/aws-cdk-rfcs/issues/434)|[AWS Ground Station L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/434)||💡 proposed -[437](https://github.com/aws/aws-cdk-rfcs/issues/437)|[CDK post-deployment experience](https://github.com/aws/aws-cdk-rfcs/issues/437)||💡 proposed -[441](https://github.com/aws/aws-cdk-rfcs/issues/441)|[Add Sagemaker endpoint L2 construct](https://github.com/aws/aws-cdk-rfcs/issues/441)||💡 proposed -[446](https://github.com/aws/aws-cdk-rfcs/issues/446)|[Network Firewall L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/446)||💡 proposed -[448](https://github.com/aws/aws-cdk-rfcs/issues/448)|[AWS Compute Optimizer Constructs](https://github.com/aws/aws-cdk-rfcs/issues/448)||💡 proposed -[450](https://github.com/aws/aws-cdk-rfcs/issues/450)|[AWS CDK public roadmap](https://github.com/aws/aws-cdk-rfcs/issues/450)||💡 proposed -[458](https://github.com/aws/aws-cdk-rfcs/issues/458)|[Service Catalog ProductStack Asset Support](https://github.com/aws/aws-cdk-rfcs/issues/458)||💡 proposed -[463](https://github.com/aws/aws-cdk-rfcs/issues/463)|[Glue View L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/463)||💡 proposed -[465](https://github.com/aws/aws-cdk-rfcs/issues/465)|[AWS Organizations L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/465)|[@Naumel](https://github.com/Naumel)|💡 proposed -[467](https://github.com/aws/aws-cdk-rfcs/issues/467)|[Add L2 constructs for Amaxon FSx Windows](https://github.com/aws/aws-cdk-rfcs/issues/467)||💡 proposed -[469](https://github.com/aws/aws-cdk-rfcs/issues/469)|[AWS Lambda for .NET Support](https://github.com/aws/aws-cdk-rfcs/issues/469)||💡 proposed -[470](https://github.com/aws/aws-cdk-rfcs/issues/470)|[Amazon Aurora Serverless v2 support](https://github.com/aws/aws-cdk-rfcs/issues/470)||💡 proposed -[471](https://github.com/aws/aws-cdk-rfcs/issues/471)|[Amazon Managed Grafana L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/471)||💡 proposed -[473](https://github.com/aws/aws-cdk-rfcs/issues/473)|[EventBridge Pipes L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/473)|[@mrgrain](https://github.com/mrgrain)|💡 proposed -[481](https://github.com/aws/aws-cdk-rfcs/issues/481)|[Add L2 constructs for Amazon Redshift Serverless](https://github.com/aws/aws-cdk-rfcs/issues/481)||💡 proposed -[483](https://github.com/aws/aws-cdk-rfcs/issues/483)|[AppFlow L2 Constructs](https://github.com/aws/aws-cdk-rfcs/issues/483)|[@iliapolo](https://github.com/iliapolo)|💡 proposed -[487](https://github.com/aws/aws-cdk-rfcs/issues/487)|[New L2 Construct for Step Functions Map State in Distributed Mode](https://github.com/aws/aws-cdk-rfcs/issues/487)||💡 proposed -[489](https://github.com/aws/aws-cdk-rfcs/issues/489)|[Add API to register and execute code before or after CDK App lifecycle events](https://github.com/aws/aws-cdk-rfcs/issues/489)||💡 proposed -[491](https://github.com/aws/aws-cdk-rfcs/issues/491)|[CloudFront Origin Access Control L2](https://github.com/aws/aws-cdk-rfcs/issues/491)||💡 proposed -[492](https://github.com/aws/aws-cdk-rfcs/issues/492)|[Amazon OpenSearch Serverless L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/492)||💡 proposed -[495](https://github.com/aws/aws-cdk-rfcs/issues/495)|[AWS IAM Identity Store L2 construct](https://github.com/aws/aws-cdk-rfcs/issues/495)||💡 proposed -[497](https://github.com/aws/aws-cdk-rfcs/issues/497)|[AWS Glue L2 CDK Construct](https://github.com/aws/aws-cdk-rfcs/issues/497)|[@TheRealAmazonKendra](https://github.com/TheRealAmazonKendra)|💡 proposed -[499](https://github.com/aws/aws-cdk-rfcs/issues/499)|[AppConfig L2 Constructs](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0499-appconfig-constructs.md)||💡 proposed -[501](https://github.com/aws/aws-cdk-rfcs/issues/501)|[L2 Constructs for Lattice Service](https://github.com/aws/aws-cdk-rfcs/issues/501)||💡 proposed -[502](https://github.com/aws/aws-cdk-rfcs/issues/502)|[Amazon VPC Lattice L2 Construct](https://github.com/aws/aws-cdk-rfcs/issues/502)||💡 proposed -[509](https://github.com/aws/aws-cdk-rfcs/issues/509)|[Add Step Functions SageMaker CreateProcessingJob task construct](https://github.com/aws/aws-cdk-rfcs/issues/509)||💡 proposed -[512](https://github.com/aws/aws-cdk-rfcs/issues/512)|[Thumbprint L2 Construct for use with IAM OIDC Provider](https://github.com/aws/aws-cdk-rfcs/issues/512)||💡 proposed -[513](https://github.com/aws/aws-cdk-rfcs/issues/513)|[Application Specific Staging Resources](https://github.com/aws/aws-cdk-rfcs/issues/513)||💡 proposed -[1](https://github.com/aws/aws-cdk-rfcs/issues/1)|[CDK Watch](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0001-cdk-update.md)||✅ done -[6](https://github.com/aws/aws-cdk-rfcs/issues/6)|[Monolithic Packaging](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0006-monolothic-packaging.md)||✅ done -[7](https://github.com/aws/aws-cdk-rfcs/issues/7)|[Lambda Bundles](https://github.com/aws/aws-cdk-rfcs/issues/7)||✅ done -[16](https://github.com/aws/aws-cdk-rfcs/issues/16)|[RFC Process](https://github.com/aws/aws-cdk-rfcs/pull/53)|[@MrArnoldPalmer](https://github.com/MrArnoldPalmer)|✅ done -[34](https://github.com/aws/aws-cdk-rfcs/issues/34)|[Third-party construct ecosystem](https://github.com/aws/aws-cdk-rfcs/issues/34)||✅ done -[35](https://github.com/aws/aws-cdk-rfcs/issues/35)|[Publish construct library guidelines](https://github.com/aws/aws-cdk-rfcs/issues/35)||✅ done -[36](https://github.com/aws/aws-cdk-rfcs/issues/36)|[Constructs Programming Model](https://github.com/aws/aws-cdk-rfcs/issues/36)||✅ done -[37](https://github.com/aws/aws-cdk-rfcs/issues/37)|[Release from a "release" branch](https://github.com/aws/aws-cdk-rfcs/issues/37)|[@MrArnoldPalmer](https://github.com/MrArnoldPalmer)|✅ done -[49](https://github.com/aws/aws-cdk-rfcs/issues/49)|[CI/CD for CDK apps](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0049-continuous-delivery.md)|[@rix0rrr](https://github.com/rix0rrr)|✅ done -[55](https://github.com/aws/aws-cdk-rfcs/issues/55)|[Feature Flags](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0055-feature-flags.md)||✅ done -[71](https://github.com/aws/aws-cdk-rfcs/issues/71)|[Deployment Triggers](https://github.com/aws/aws-cdk-rfcs/issues/71)||✅ done -[79](https://github.com/aws/aws-cdk-rfcs/issues/79)|[CDK v2.0](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0079-cdk-2.0.md)||✅ done -[92](https://github.com/aws/aws-cdk-rfcs/issues/92)|[CI/CD Asset Publishing](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0092-asset-publishing.md)|[@rix0rrr](https://github.com/rix0rrr)|✅ done -[95](https://github.com/aws/aws-cdk-rfcs/issues/95)|[Cognito Construct Library](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0095-cognito-construct-library)|[@nija-at](https://github.com/nija-at)|✅ done -[107](https://github.com/aws/aws-cdk-rfcs/issues/107)|[Publish a Construct Library Module Lifecycle document](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0107-construct-library-module-lifecycle.md)|[@ccfife](https://github.com/ccfife)|✅ done -[110](https://github.com/aws/aws-cdk-rfcs/issues/110)|[CLI Compatibility Strategy](https://github.com/aws/aws-cdk-rfcs/blob/master/text/00110-cli-framework-compatibility-strategy.md)|[@iliapolo](https://github.com/iliapolo)|✅ done -[116](https://github.com/aws/aws-cdk-rfcs/issues/116)|[Easier identification of experimental modules](https://github.com/aws/aws-cdk-rfcs/issues/116)||✅ done -[171](https://github.com/aws/aws-cdk-rfcs/issues/171)|[CloudFront Module Redesign](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0171-cloudfront-redesign.md)||✅ done -[192](https://github.com/aws/aws-cdk-rfcs/issues/192)|[Removal of the "constructs" compatibility layer (v2.0)](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0192-remove-constructs-compat.md)|[@eladb](https://github.com/eladb)|✅ done -[204](https://github.com/aws/aws-cdk-rfcs/issues/204)|[JSII Go Support](https://github.com/aws/aws-cdk-rfcs/blob/master/text/204-golang-bindings.md)|[@MrArnoldPalmer](https://github.com/MrArnoldPalmer)|✅ done -[249](https://github.com/aws/aws-cdk-rfcs/issues/249)|[Experimental Code in CDK v2](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0249-v2-experiments.expired.md)|[@ericzbeard](https://github.com/ericzbeard)|✅ done -[253](https://github.com/aws/aws-cdk-rfcs/issues/253)|[CDK Metadata v2](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0253-cdk-metadata-v2.md)||✅ done -[282](https://github.com/aws/aws-cdk-rfcs/issues/282)|[CDK Pipelines security posture change approvals](https://github.com/aws/aws-cdk-rfcs/issues/282)||✅ done -[287](https://github.com/aws/aws-cdk-rfcs/issues/287)|[Deprecated API Warnings](https://github.com/aws/aws-cdk-rfcs/blob/master/text/287-cli-deprecation-warnings.md)||✅ done -[308](https://github.com/aws/aws-cdk-rfcs/issues/308)|[CLI notices](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0308-cli-advisories.md)||✅ done -[322](https://github.com/aws/aws-cdk-rfcs/issues/322)|[CDK Pipelines Updated API](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0322-cdk-pipelines-updated-api.md)||✅ done -[324](https://github.com/aws/aws-cdk-rfcs/issues/324)|[Construct Hub](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0324-cdk-construct-hub.md)|[@RomainMuller](https://github.com/RomainMuller)|✅ done -[328](https://github.com/aws/aws-cdk-rfcs/issues/328)|[polyglot assert library](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0328-polyglot-assert.md)|[@nija-at](https://github.com/nija-at)|✅ done -[353](https://github.com/aws/aws-cdk-rfcs/issues/353)|[Constructs for all public CloudFormation resources and modules](https://github.com/aws/aws-cdk-rfcs/blob/master/text/353-cfn-registry-constructs.md)||✅ done -[359](https://github.com/aws/aws-cdk-rfcs/issues/359)|[Construct Hub Deny List](https://github.com/aws/aws-cdk-rfcs/blob/master/text/359-construct-hub-deny-list.md)||✅ done -[374](https://github.com/aws/aws-cdk-rfcs/issues/374)|[The jsii compiler to follow TypeScript versioning](https://github.com/aws/aws-cdk-rfcs/issues/374)||✅ done -[388](https://github.com/aws/aws-cdk-rfcs/issues/388)|[CLI Banners](https://github.com/aws/aws-cdk-rfcs/issues/388)||✅ done -[477](https://github.com/aws/aws-cdk-rfcs/issues/477)|[Add policy validation to CDK](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0477-policy-validation.md)|[@otaviomacedo](https://github.com/otaviomacedo)|✅ done -[60](https://github.com/aws/aws-cdk-rfcs/issues/60)|[Bazel Build System](https://github.com/aws/aws-cdk-rfcs/pull/61)||👎 rejected -[164](https://github.com/aws/aws-cdk-rfcs/issues/164)|[Construct Library Segments](https://github.com/aws/aws-cdk-rfcs/pull/169)|[@nija-at](https://github.com/nija-at)|👎 rejected -[272](https://github.com/aws/aws-cdk-rfcs/issues/272)|[CI/CD to Cloudfront Deploy](https://github.com/aws/aws-cdk-rfcs/issues/272)||👎 rejected -[436](https://github.com/aws/aws-cdk-rfcs/issues/436)|[Amazon GameLift L2 Constructs](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0436-gamelift-l2.md)||❓unknown -[485](https://github.com/aws/aws-cdk-rfcs/issues/485)|[AWS Batch L2](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0485-aws-batch.md)||❓unknown ## What is an RFC? @@ -310,6 +159,14 @@ that you may need to throw your code away or refactor it substantially, but our experience shows that good RFCs are the ones who dive into the details. A prototype is great way to make sure your design "holds water". +> [!NOTE] +> To ensure consistency, the Markdown you write will be checked for common > +mistakes using a linter. To get early feedback while you are writing, use the +[VSCode > markdownlint +extensions](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint), +> or run the `./lint.sh` script in the root of the repository. +> Run `./lint.sh --fix` auto fix all fixable violations. + ### 5. Feedback Once you have an initial version of your RFC document (it is completely fine to @@ -348,7 +205,7 @@ Before you can merge your RFC, you will need the API Bar Raiser to sign-off on the public API of your feature. This is will normally be described under the **Working Backwards** section of your RFC. -To sign-off, the API bar raiser will add the **api-approved** label to the RFC +To sign-off, the API bar raiser will add the **status/api-approved** label to the RFC pull request. Once the API was signed-off, update your RFC document and add a `[x]` the @@ -391,7 +248,7 @@ Throughout this process, update the tracking issue: - Plan approved and merged (label: `status/implementing`) - Implementation complete (label: `status/done`) -## State Diagram +## The RFC Life Cycle The following state diagram describes the RFC process: @@ -401,17 +258,17 @@ The following state diagram describes the RFC process: digraph states { node [shape=ellipse]; edge [color=gray, fontsize=12] - + idea [label = "Idea", shape = plaintext] proposed [label = "Proposed"]; review [label = "In Review"]; fcp [label = "Final Comment Period"]; approved [label = "Approved"]; - plannning [label = "Planning"]; + planning [label = "Planning"]; implementing [label = "Implementing"]; done [label = "Done"]; rejected [label = "Rejected"]; - + idea -> proposed [label = "github issue created"] proposed -> review [label = "pull request with rfc doc created"]; review -> review [label = "doc revisions"]; @@ -420,10 +277,10 @@ digraph states { fcp -> review [label = "revision requested"]; fcp -> approved [label = "pull request approved and merged"]; fcp -> rejected [label = "rfc rejected"]; - approved -> plannning [label = "pull request with implementation plan created"]; - plannning -> implementing [label = "rfc with implementation plan approved and merged"]; + approved -> planning [label = "pull request with implementation plan created"]; + planning -> implementing [label = "rfc with implementation plan approved and merged"]; implementing -> done [label = "implementation completed"]; -} +} --> 1. **Proposed** - A tracking issue has been created with a basic outline of the @@ -437,12 +294,14 @@ digraph states { 4. **Approved** - The RFC PR is approved and merged to `master`, and the RFC is now ready to be implemented. 5. **Planning** - A PR is created with the **Implementation Plan** section of the RFC. -6. **Implementing** - Implemetation plan is approved and merged and the RFC is actively +6. **Implementing** - Implementation plan is approved and merged and the RFC is actively being implemented. 7. **Done** - Implementation is complete and merged across appropriate repositories. 8. **Rejected** - During the review period, the RFC may be rejected and then it will be marked as such. +9. **Stale** - The RFC did not get any significant enough progress or tracking and has become stale. + We welcome a re-submission with substantial enough changes to overcome the original issues. ---