Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(ecs): vpc link for api gatway and load balanced services #1541

Merged
merged 3 commits into from
Jan 16, 2019

Conversation

dotxlem
Copy link
Contributor

@dotxlem dotxlem commented Jan 14, 2019

Overview

The primary purpose of this work is to fill in the gaps in
implementation for deploying a VPC link between API Gateway, and an
ECS service. My goal was to allow setting up a {proxy+} API which would
forward to a Fargate service in a private VPC.

This has been tagged as 'ecs', but also involves changes to api gateway.

Since VPC links require an NLB, the LoadBalanced{Fargate|Ecs}Service classes
have been modified to support selecting either an ALB or an NLB.

Closes #1500.

Changes

On the APIGW side, IntegrationOptions now accepts an optional connetion
type enum, as well as a VpcLink. VpcLink itself is a new construct
which accepts an array of Network Load Balancers. I also added the missing
requestParameters prop for Method, to allow properly setting up a proxy
path variable.

For ECS, in my use case I wanted to use the LoadBalanced*Service constructs, however
they only supported ALB. I have pulled all of the ELBv2 related setup
into the new LoadBalancedService base class, and also created a base
props interface LoadBalancedServiceProps. This deals with the common setup
between the Fargate and ECS services, and allows the selection of ALB or NLB.
As a side-effect of this refactoring, you can also now pass a Certificate to
LoadBalancedEcsService.

There is a new Method test for the VPC link props, as well as new tests
for both VpcLink and LoadBalancedFargateService.


Pull Request Checklist

  • Testing
    • Unit test added
    • CLI change?: manually run integration tests and paste output as a PR comment
    • cdk-init template change?: coordinated update of integration tests with team
  • Docs
    • jsdocs: All public APIs documented
    • README: README and/or documentation topic updated
  • Title and Description
    • Change type: title prefixed with fix, feat will appear in changelog
    • Title: use lower-case and doesn't end with a period
    • Breaking?: last paragraph: "BREAKING CHANGE: <describe what changed + link for details>"
    • Issues: Indicate issues fixed via: "Fixes #xxx" or "Closes #xxx"
  • [n/a] Sensitive Modules (requires 2 PR approvers)
    • IAM Policy Document (in @aws-cdk/aws-iam)
    • EC2 Security Groups and ACLs (in @aws-cdk/aws-ec2)
    • Grant APIs (only if not based on official documentation with a reference)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license.

Overview
========
The primary purpose of this work is to fill in the gaps in
implementation for deploying a VPC link between API Gateway, and an
ECS service. My goal was to allow setting up a {proxy+} API which would
forward to a Fargate service in a private VPC.

This has been tagged as 'ecs', but also involves changes to api gateway.

Since VPC links require an NLB, the LoadBalanced{Fargate|Ecs}Service classes
have been modified to support selecting either an ALB or an NLB.

Changes
=======
On the APIGW side, `IntegrationOptions` now accepts an optional connetion
type enum, as well as a VpcLink. `VpcLink` itself is a new construct
which accepts an array of Network Load Balancers. I also added the missing
`requestParameters` prop for `Method`, to allow properly setting up a proxy
path variable.

For ECS, in my use case I wanted to use the LoadBalanced*Service constructs, however
they only supported ALB. I have pulled all of the ELBv2 related setup
into the new `LoadBalancedService` base class, and also created a base
props interface `LoadBalancedServiceProps`. This deals with the common setup
between the Fargate and ECS services, and allows the selection of ALB or NLB.
As a side-effect of this refactoring, you can also now pass a Certificate to
`LoadBalancedEcsService`.

There is a new `Method` test for the VPC link props, as well as new tests
for both `VpcLink` and `LoadBalancedFargateService`.
@dotxlem dotxlem requested review from SoManyHs and a team as code owners January 14, 2019 13:35
Copy link
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love what you've done with the refactor!

I have some small style comments, but approved modulo those!

@@ -173,6 +179,8 @@ export class Method extends cdk.Construct {
requestTemplates: options.requestTemplates,
passthroughBehavior: options.passthroughBehavior,
integrationResponses: options.integrationResponses,
connectionType: options.connectionType,
connectionId: options.vpcLink ? options.vpcLink.vpcLinkId : undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if connectiontype === internet and a vpcLink is supplied. Is that ok?

Copy link
Contributor Author

@dotxlem dotxlem Jan 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for ConnectionId state:

The ID of the VpcLink used for the integration when connectionType=VPC_LINK and undefined, otherwise.

I took that to mean that it would just be ignored. Probably best to throw an error though to alert the user, since that's probably not what they wanted to happen.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I was getting at. Thanks.

/**
* The name used to label and identify the VPC link.
*/
name: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make this optional.

If CloudFormation doesn't allow an optional name, you can always default inside the construct to this.uniqueId.

* The network load balancers of the VPC targeted by the VPC link.
* The network load balancers must be owned by the same AWS account of the API owner.
*/
targets: elbv2.NetworkLoadBalancer[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should take elbv2.INetworkLoadBalancer[].

*/
export interface VpcLinkProps {
/**
* The name used to label and identify the VPC link.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@default automatically generated name

name: string;

/**
* The description of the VPC link.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@default no description

});
}

public get vpcLinkId() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works, but we generally just declare a string property on the construct and assign it in the constructor.

@@ -132,6 +90,7 @@ export class LoadBalancedFargateService extends cdk.Construct {

const container = taskDefinition.addContainer('web', {
image: props.image,
environment: props.containerEnvironment,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was recently also added on master, so you need to merge from master and this change is no longer necessary.

/**
* Base class for load-balanced Fargate and ECS service
*/
export abstract class LoadBalancedService extends cdk.Construct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename to LoadBalancedServiceBase to make it clear from the name that it's not meant to be instantiated. I know, it's abstract already, but more clarity never hurts.

}

const targetProps = {
port: 80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this use containerPort?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought so too, but apparently when used with ECS the port number for the target group is ignored.

I can confirm that it works fine as-is, I use 8000 for my container port.

@dotxlem
Copy link
Contributor Author

dotxlem commented Jan 16, 2019

Love what you've done with the refactor!

I have some small style comments, but approved modulo those!

Thanks @rix0rrr! I've committed the requested changes, save for setting the LB target port to the container port. That was hard-coded to 80 prior to my changes, and as I said, I don't think it's actually used in conjunction with ECS anyway.

@rix0rrr
Copy link
Contributor

rix0rrr commented Jan 16, 2019

That was hard-coded to 80 prior to my changes, and as I said, I don't think it's actually used in conjunction with ECS anyway.

Interesting. Well okay, if it works then it works :).

@rix0rrr rix0rrr merged commit 6642ca2 into aws:master Jan 16, 2019
@SpainTrain SpainTrain mentioned this pull request Feb 9, 2019
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for VPC link between APIGW and Fargate Service
2 participants