-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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(global-accelerator): referencing Global Accelerator security group #9358
Merged
mergify
merged 10 commits into
aws:master
from
flemjame-at-amazon:global-accelerator-sg
Aug 11, 2020
Merged
Changes from 7 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
22e8500
Initial commit
flemjame-at-amazon f5a55cb
Successful build
flemjame-at-amazon b58d582
Add unit tests
flemjame-at-amazon 8f2c13c
Add readme
flemjame-at-amazon d1512c6
Add dependency to guarantee order
flemjame-at-amazon 8128219
Needed to use ResourcePart.CompleteDefinition to compare the DependsO…
flemjame-at-amazon 636c31e
Merge branch 'master' into global-accelerator-sg
flemjame-at-amazon 3cc2846
Review feedback
flemjame-at-amazon 5e1176c
Merge branch 'master' into global-accelerator-sg
flemjame-at-amazon d40fff4
Merge branch 'master' into global-accelerator-sg
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
packages/@aws-cdk/aws-globalaccelerator/lib/accelerator-security-group.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { ISecurityGroup, SecurityGroup, IVpc } from '@aws-cdk/aws-ec2'; | ||
import { Construct } from '@aws-cdk/core'; | ||
import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId} from '@aws-cdk/custom-resources'; | ||
import { EndpointGroup } from '../lib'; | ||
|
||
/** | ||
* The security group used by a Global Accelerator to send traffic to resources in a VPC. | ||
*/ | ||
export class AcceleratorSecurityGroup { | ||
/** | ||
* Lookup the Global Accelerator security group at CloudFormation deployment time. | ||
* | ||
* As of this writing, Global Accelerators (AGA) create a single security group per VPC. AGA security groups are shared | ||
* by all AGAs in an account. Additionally, there is no CloudFormation mechanism to reference the AGA security groups. | ||
* | ||
* This makes creating security group rules which allow traffic from an AGA complicated in CDK. This lookup will identify | ||
* the AGA security group for a given VPC at CloudFormation deployment time, and lets you create rules for traffic from AGA | ||
* to other resources created by CDK. | ||
*/ | ||
public static fromVpc(scope: Construct, id: string, vpc: IVpc, endpointGroup: EndpointGroup): ISecurityGroup { | ||
|
||
// The security group name is always 'GlobalAccelerator' | ||
const globalAcceleratorSGName = 'GlobalAccelerator'; | ||
|
||
// How to reference the security group name in the response from EC2 | ||
const ec2ResponseSGIdField = 'SecurityGroups.0.GroupId'; | ||
|
||
// The AWS Custom Resource that make a call to EC2 to get the security group ID, for the given VPC | ||
const lookupAcceleratorSGCustomResource = new AwsCustomResource(scope, id + 'CustomResource', { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is clever! |
||
onCreate: { | ||
service: 'EC2', | ||
action: 'describeSecurityGroups', | ||
parameters: { | ||
Filters: [ | ||
{ | ||
Name: 'group-name', | ||
Values: [ | ||
globalAcceleratorSGName, | ||
], | ||
}, | ||
{ | ||
Name: 'vpc-id', | ||
Values: [ | ||
vpc.vpcId, | ||
], | ||
}, | ||
], | ||
}, | ||
// We get back a list of responses, but the list should be of length 0 or 1 | ||
// Getting no response means no resources have been linked to the AGA | ||
physicalResourceId: PhysicalResourceId.fromResponse(ec2ResponseSGIdField), | ||
}, | ||
policy: AwsCustomResourcePolicy.fromSdkCalls({ | ||
resources: AwsCustomResourcePolicy.ANY_RESOURCE, | ||
}), | ||
}); | ||
|
||
// Look up the security group ID | ||
const sg = SecurityGroup.fromSecurityGroupId(scope, | ||
id, | ||
lookupAcceleratorSGCustomResource.getResponseField(ec2ResponseSGIdField)); | ||
// We add a dependency on the endpoint group, guaranteeing that CloudFormation won't | ||
// try and look up the SG before AGA creates it. The SG is created when a VPC resource | ||
// is associated with an AGA | ||
lookupAcceleratorSGCustomResource.node.addDependency(endpointGroup); | ||
return sg; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
// AWS::GlobalAccelerator CloudFormation Resources: | ||
export * from './globalaccelerator.generated'; | ||
export * from './accelerator'; | ||
export * from './accelerator-security-group'; | ||
export * from './listener'; | ||
export * from './endpoint-group'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
packages/@aws-cdk/aws-globalaccelerator/test/globalaccelerator-security-group.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { expect, haveResource, ResourcePart } from '@aws-cdk/assert'; | ||
import { Port } from '@aws-cdk/aws-ec2'; | ||
import * as ga from '../lib'; | ||
import { testFixture, testFixtureAlb } from './util'; | ||
|
||
test('custom resource exists', () => { | ||
// GIVEN | ||
const { stack, vpc } = testFixture(); | ||
const accelerator = new ga.Accelerator(stack, 'Accelerator'); | ||
const listener = new ga.Listener(stack, 'Listener', { | ||
accelerator, | ||
portRanges: [ | ||
{ | ||
fromPort: 443, | ||
toPort: 443, | ||
}, | ||
], | ||
}); | ||
const endpointGroup = new ga.EndpointGroup(stack, 'Group', { listener }); | ||
|
||
// WHEN | ||
ga.AcceleratorSecurityGroup.fromVpc(stack, 'GlobalAcceleratorSG', vpc, endpointGroup); | ||
|
||
// THEN | ||
expect(stack).to(haveResource('Custom::AWS', { | ||
Properties: { | ||
ServiceToken: { | ||
'Fn::GetAtt': [ | ||
'AWS679f53fac002430cb0da5b7982bd22872D164C4C', | ||
'Arn', | ||
], | ||
}, | ||
Create: { | ||
action: 'describeSecurityGroups', | ||
service: 'EC2', | ||
parameters: { | ||
Filters: [ | ||
{ | ||
Name: 'group-name', | ||
Values: [ | ||
'GlobalAccelerator', | ||
], | ||
}, | ||
{ | ||
Name: 'vpc-id', | ||
Values: [ | ||
{ | ||
Ref: 'VPCB9E5F0B4', | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
physicalResourceId: { | ||
responsePath: 'SecurityGroups.0.GroupId', | ||
}, | ||
}, | ||
}, | ||
DependsOn: [ | ||
'GroupC77FDACD', | ||
], | ||
}, ResourcePart.CompleteDefinition)); | ||
}); | ||
|
||
test('can create security group rule', () => { | ||
// GIVEN | ||
const { stack, alb, vpc } = testFixtureAlb(); | ||
const accelerator = new ga.Accelerator(stack, 'Accelerator'); | ||
const listener = new ga.Listener(stack, 'Listener', { | ||
accelerator, | ||
portRanges: [ | ||
{ | ||
fromPort: 443, | ||
toPort: 443, | ||
}, | ||
], | ||
}); | ||
const endpointGroup = new ga.EndpointGroup(stack, 'Group', { listener }); | ||
endpointGroup.addLoadBalancer('endpoint', alb); | ||
|
||
// WHEN | ||
const sg = ga.AcceleratorSecurityGroup.fromVpc(stack, 'GlobalAcceleratorSG', vpc, endpointGroup); | ||
alb.connections.allowFrom(sg, Port.tcp(443)); | ||
|
||
// THEN | ||
expect(stack).to(haveResource('AWS::EC2::SecurityGroupIngress', { | ||
IpProtocol: 'tcp', | ||
FromPort: 443, | ||
GroupId: { | ||
'Fn::GetAtt': [ | ||
'ALBSecurityGroup8B8624F8', | ||
'GroupId', | ||
], | ||
}, | ||
SourceSecurityGroupId: { | ||
'Fn::GetAtt': [ | ||
'GlobalAcceleratorSGCustomResourceC1DB5287', | ||
'SecurityGroups.0.GroupId', | ||
], | ||
}, | ||
ToPort: 443, | ||
})); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For safety's sake, can you give this class a
private constructor() { }
?To make sure it's only used statically, gives us the opportunity to add a constructor later on should we ever need to (otherwise we can't ever make this class a construct anymore without breaking backwards compat).